Корректно копирование текста в буфер обмена при любой раскладке клавы

Тема в разделе "WASM.BEGINNERS", создана пользователем EvilsInterrupt, 14 ноя 2007.

  1. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Всем хай.

    Чето я голову сломал над этим сабжем ;)

    При использовании SetClipboardData(CF_TEXT, происходит следующее:
    1. Юзер переключается в русскую раскладку по Ctrl+Shift или Alt+Shift, заходит в моей проги в окно и там жмет правой кнопкой, где есть пункт смысл которого: Скопировать текст в буфер обмена. После этого он решает послать это своему другу по аське и вставляет в QIP окно спомощью Ctrl+V. Вуаля, русские буквы кажутся корректно и его друг Вася видит текст, все ок и все довольны!
    2. Все тоже самое но юзер переключился в английскую раскладку, но из буфера обмена в QIP окно скопировалось некорректно и заместо русских букв крякозябры (

    Вопрос:
    Как при любой активной раскладке клавиатуры, корректно копировать мульти-язык? Ведь может же быть не только русский, но и китайский?

    Нюансы:
    У юзера на ЭВМ может быть несколько раскладок: Татарская, Русская, Английская, но по дефолту как правило выбирают Английскую, но также бывают что выбирают и русскую, кто-то татарскую, Японцы наверно японскую выбирают в качестве дефолта.
     
  2. dermatolog

    dermatolog Member

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    406
    Адрес:
    Екатеринбург
    Гугль уже отменили? :))
    http://www.google.ru/search?q=CF_LOCALE
     
  3. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    dermatolog
    А ты попробуй ;) Если я указываю CF_LOCALE, то у меня в буфере вообще ничего нет, по крайней мере Ctrl+V ничего невставляет ;(
    Код (Text):
    1. SetClipboardData(CF_LOCALE, hData);
    Приходится CF_TEXT. Вот из статьи в нэте, и подобное в MSDN:
    Т.е. смысл использовать CF_LOCALE нет!

    Я попросил пинать по существу, а в гугл даже новичок умеет послать ;)
     
  4. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Используй CF_UNICODETEXT.
     
  5. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Стандартные компоненты Delphi используют тип string и в зависимости от одной директивы или настройки в проекте, этот тип принимает вид AnsiString или ShortString. Что в конечном итоге приводит к ANSI. Т.е. в буфер обмена я загоняю в ANSI

    ЗЫ:
    Скорее бы 2008,там обещали что string будут иметь тип WideString,т.е. в Delphi можно будет работать с UTF-16 ;)
     
  6. Atlantic

    Atlantic Member

    Публикаций:
    0
    Регистрация:
    22 июн 2005
    Сообщения:
    322
    Адрес:
    Швеция
    EvilsInterrupt
    Так ведь можно и самому сконвертить в нужный формат. MultiByteToWideChar сам все сделает.
     
  7. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Atlantic
    Мысль! ;) Спасибо ;)

    Мысль-то она мысль, но пробемы не решает ;(

    Насколько я понимаю, происходит следующее:
    1. Я ввожу в буфер CF_TEXT то, что есть а есть там русские буквы. Если я нахожусь на русской раскладке, то по закрытию буфера автоматически ставится CF_LOCALE, та которая сейчас, т.е русская. И та прога, что потом из буфера забирает может видит что это русская локаль и все хекс-коды, а среди них и русские буквы, распознаются нормально.
    2. Если же копирую в буфер с CF_TEXT и на английской раскладке, то по закрытию ставится флаг, что все хекс-коды ни что иное как символы английского алфавита. Прога что читает этот буфер видит эти хексы и вывод на аглийском языке.

    Т.е. там где у нас на русском хекс-код отображает русскую букву "А", то в английском не обязательно тот же вид!

    Вот в этом-то и проблема, получается что копируя текст в буфер надо четко быть уверенным какой язык текста и именно такой локалью буфер и пометить.
     
  8. Atlantic

    Atlantic Member

    Публикаций:
    0
    Регистрация:
    22 июн 2005
    Сообщения:
    322
    Адрес:
    Швеция
    EvilsInterrupt
    Тебе же сказали, сначала сконвертить в Юникод, а потом SetClipboardData(CF_UNICODETEXT, ...
     
  9. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    EvilsInterrupt
    У меня таки получилось. По крайней мере, нижепроцитированный кусок программы вполне работает.

    Код (Text):
    1. function SetClipbrdText(Text:PUA_BinaryBlock; Locale:Cardinal; UseLocale:Boolean):Boolean;
    2. var hTextMem,hLocaleMem,textlen:Cardinal;
    3.     pLocale:PCardinal;
    4.     pText:PChar;
    5. begin
    6.   Result:=False;
    7.     begin
    8.       if UseLocale then // Устанавливаем локаль для Clipboard
    9.       begin
    10.        if OpenClipboard(0) then
    11.         EmptyClipboard; // Удаляем из Clipboard старую информацию
    12.         hLocaleMem:=GlobalAlloc(GMEM_MOVEABLE+GMEM_ZEROINIT,SizeOf(Cardinal));
    13.         if hLocaleMem=0 then begin CloseClipboard; Exit; end
    14.           else
    15.            begin
    16.             pLocale:=GlobalLock(hLocaleMem);
    17.             if pLocale=nil
    18.              then begin CloseClipboard; Exit; end
    19.              else pLocale^:=Locale;
    20.             if SetClipboardData(CF_LOCALE,hLocaleMem)=0 then
    21.               begin
    22.                 CloseClipboard;
    23.                 LocalUnlock(hLocaleMem);
    24.                 GlobalFree(hLocaleMem);
    25.                 Exit;
    26.               end;
    27.            end;//else
    28.        end;//if OpenClipboard
    29.       end;//if UseLocale
    30.  
    31.      //Теперь пишем текст в Clipboard
    32.      if OpenClipboard(0) then
    33.       begin
    34.         if not UseLocale then EmptyClipboard; // Если локаль не используется - надо очистить Clipboard
    35.         textlen:=Text^.Header.ElemCount-1;
    36.         // Один 0 в конце двоичного блока оставляем, т.к. это ASCIIZ-строка
    37.         hTextMem:=GlobalAlloc(GMEM_MOVEABLE+GMEM_ZEROINIT,textlen);
    38.         if hTextMem<>0 then
    39.           begin
    40.             pText:=GlobalLock(hTextMem);
    41.             if pText=nil then
    42.               begin
    43.                 CloseClipboard;
    44.                 GlobalUnlock(hTextMem);
    45.               end //if pText=nil
    46.             else
    47.               begin
    48.                 Move(Text^.Arr[0],pText^,textlen);
    49.                 if SetClipboardData(CF_TEXT,hTextMem)=0 then
    50.                   begin
    51.                    CloseClipboard;
    52.                    GlobalUnlock(hTextMem);
    53.                    GlobalFree(hTextMem);
    54.                    Exit;
    55.                   end;
    56.                 CloseClipboard;
    57.                 GlobalUnlock(hTextMem);
    58.                 Result:=True;
    59.               end; //else
    60.           end
    61.         else CloseClipboard;
    62.       end;//if OpenClipboard(0)
    63. end;
     
  10. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    CyberManiac
    Да не, думаю идея с UTF-16 более здравая ! ;) Ведь по сути юникод- символ это уникальный код для любого символа ;) И никогда не будет что один и тот хекс-код в русском одно, а в англ. другое )
     
  11. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Проблема решена ;)
     
  12. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    EvilsInterrupt
    invoke MultiByteToWideChar, CP_ACP,... ?