Тотальная неудачница и убийца жёстких дисков.
#post-id: 2538-13-32

#original-date: 8.07.2007 Sun

#original-time: 1:32 PM

#original-day:  2538



Нашла источник всех бед. Помните глюк в XP, когда копируешь в буфер обмена русский текст, а вставляются крякозяблики? Второй админ заметил, что этого не происходит, если в программе, от куда копируется текст, переключиться на русский.



Я сейчас исправляю этот глюк в Megumi Converter (решила использовать текст в UNICODE, а сам VB в буфер обмена UNICODE не копирует) и решила посмотреть, что копируется в буфер обмена. Оказалось, что кроме UNICODE, ANSI и OEM копируется ещё и некая Locale. Это, как подсказывает интуиция, язык для ANSI части данных. Да-да, в буфере обмена на самом деле одновременно могут находиться несколько разных форматов, скажем, текст, HTML, RTF и картинка. Обычно это используется для разных представлений одного блока данных: данные в простом тексте, данные в HTML, данные на картинке.



Так что же в Locale? Вот что пишет MSDN:



CF_LOCALE



The data is a handle to the locale identifier associated with text in the clipboard. When you close the clipboard, if it contains CF_TEXT data but no CF_LOCALE data, the system automatically sets the CF_LOCALE format to the current input language. You can use the CF_LOCALE format to associate a different locale with the clipboard text.



An application that pastes text from the clipboard can retrieve this format to determine which character set was used to generate the text.




Тоесть если программа сама не ставит язык текста, Windows делает это сама. Учитывая что MSDN говорит что так происходит всега, но тот же VB не менялся со времён Windows 95, значит, скорее всего, предыдущие версии Windows просто ставили локаль по умолчанию...



Хммм... Или может просто дружно плевали на локаль. Так. Запуталась. Текст в буфер попадает уже повреждённым (это хорошо видно через просмотрщик буфера обмена), тоесть XP перед тем как вставить текст, конвертирует его с учётом языка ввода.



Вот. Я после этого не хочу перейти на Линукс. /* Обычно линуксоиды на каждый мелкий глюк начинают вой "Давно пора". */ Просто жалко.



Так. Как я это делаю:



Public Sub PasteToClipBoard(ByVal Text As BStr)

 Dim hInData As API_HANDLE
 Dim Buff() As Byte
 
 If OpenClipboard(0) = C_FALSE Then
   MsgBox "Ia oaaeinu ioe?uou aooa? iaiaia.", vbCritical
   Exit Sub
 End If
 
 EmptyClipboard
 
 If Text <> "" Then
   If asIsHostWinNT Then
     Buff = Text & NUL
     hInData = GlobalAlloc(GMEM_ZEROINIT Or GMEM_DDESHARE, _
                           UBound(Buff) - LBound(Buff) + 2)
     CopyMemory ByVal hInData, Buff(0), _
                UBound(Buff) - LBound(Buff) + 1
     SetClipboardData CF_UNICODETEXT, hInData
   End If
   
   Buff = StrConv(Text & NUL, vbFromUnicode)
   hInData = GlobalAlloc(GMEM_ZEROINIT Or GMEM_DDESHARE, _
                         UBound(Buff) - LBound(Buff) + 2)
   CopyMemory ByVal hInData, Buff(0), _
              UBound(Buff) - LBound(Buff) + 1
   SetClipboardData CF_TEXT, hInData
   
   Buff = StrConv(asAnsiToOem(Text) & NUL, vbFromUnicode)
   hInData = GlobalAlloc(GMEM_ZEROINIT Or GMEM_DDESHARE, _
                         UBound(Buff) - LBound(Buff) + 2)
   CopyMemory ByVal hInData, Buff(0), _
              UBound(Buff) - LBound(Buff) + 1
   SetClipboardData CF_OEMTEXT, hInData
 End If
 
 CloseClipboard
End Sub
Как видите, я ручками формирую три формата текста, а программы, как показывает практика, используют UNICODE составляющую. До вставки правильной локали я ещё не доросла ^^'



#music: Galla\Initial D\Kiseki no Hana

@темы: Программизм