Конференция "WinAPI" » Обработка WM_CHAR в WH_GETMESSAGE [D6, WinXP]
 
  • anwe (01.07.08 08:38) [0]
    Отлавливаю сообщения WM_CHAR в активном окне. Как поймал нужный символ изменяю его код на код другой буквы, не английской, но вывести ее не удается. Как изменить параметры WM_CHAR, чтобы отправить окну код буквы в Unicode?
    Через отладчик заметил, что если, допустим, я меняю код символа на 123, то до окна доходит лишь байт, то есть 23.
  • clickmaker © (01.07.08 10:05) [1]
    WM_UNICHAR ?
  • Leonid Troyanovsky © (01.07.08 11:07) [2]

    > anwe   (01.07.08 08:38)  

    > Отлавливаю сообщения WM_CHAR в активном окне. Как поймал
    > нужный символ изменяю его код на код другой буквы, не английской,
    >  но вывести ее не удается.

    Ошибка в 17 строке.

    > Как изменить параметры WM_CHAR, чтобы отправить окну код
    > буквы в Unicode?

    Он и так в UTF-16, если словлен WM_CHAR.

    > меняю код символа на 123, то до окна доходит лишь байт,
    > то есть 23

    123 - это тоже байт.

    --
    Regards, LVT.
  • anwe (01.07.08 20:50) [3]
    > WM_UNICHAR ?

    А почему та справка, что прилагается к пакету Deplhi (6), это сообщение не знает? Подсказали, что его номер = $109, но Олли такое сообщение не отлавливает, да и моя ловушка тоже.
    Что касается

    > Ошибка в 17 строке.

    так это не верно. Нет, я знаю, что означает такой ответ, но в коде все верно, ведь с английскими буквами работает. А 123 я имел ввиду $123. Думал это понятно, но признаю - это моя ошибка и имею ли я ввиду десятичную или шестнадцатиричную систему никому не известно.
    Но по сути. Если изменить:
    Msg(Pointer(lParam)^).wParam: = $123 //код символа $123


    то до приложения доходит $23.
    Как сделать чтобы приложение получило код символа размером в слово???
  • Leonid Troyanovsky © (01.07.08 23:06) [4]

    > anwe   (01.07.08 20:50) [3]

    >  но в коде все верно, ведь с английскими буквами работает.

    Да-да, "но вывести ее не удается".

    > Msg(Pointer(lParam)^).wParam: = $123 //код символа $123

    В чем сакральный оного символа?

    Если окно не юникодное, то из четырех байт wParam будет использован
    только один - ASCII character codes.

    > Как сделать чтобы приложение получило код символа размером
    > в слово???

    Неверная постановка. См. выше.

    --
    Regards, LVT,
  • Сергей М. © (01.07.08 23:07) [5]

    > Как сделать чтобы приложение получило код символа размером
    > в слово?


    Цитата из станд.справки:

    If applications process virtual-key messages for some other purpose, they should not call TranslateMessage
  • Leonid Troyanovsky © (01.07.08 23:27) [6]

    > Сергей М. ©   (01.07.08 23:07) [5]

    > If applications process virtual-key messages for some other
    > purpose, they should not call TranslateMessage

    Приложение-то чужое, и оно его вызывает.
    (Откуда б взялось тогда WM_CHAR)

    Автору же надо сосредоточиться на постановке задачи,
    а не на поиске источников своих заблуждений.

    --
    Regards, LVT.
  • Сергей М. © (01.07.08 23:33) [7]

    > Приложение-то чужое


    Почем мне знать, чужое оно или свое ?

    Автор об этом сказать не соизволил)
  • Leonid Troyanovsky © (01.07.08 23:35) [8]

    > Leonid Troyanovsky ©   (01.07.08 23:06) [4]

    > В чем сакральный оного символа?

    Выпал смысл, sorry.

    --
    Regards, LVT.
  • Leonid Troyanovsky © (01.07.08 23:37) [9]

    > Сергей М. ©   (01.07.08 23:33) [7]

    > Автор об этом сказать не соизволил)

    WH_GETMESSAGE .. в активном окне.

    --
    Regards, LVT.
  • Сергей М. © (01.07.08 23:42) [10]

    > Автору же надо сосредоточиться на постановке задачи


    Эт точно)

    А то на сей момент задача выглядит более чем странно: перехват посылки с фасованой репой и подмена содержимого на заморский прямо с грядки корнеплод, в надежде что адресат схавает его вместе с ботвой и не подавится)
  • Сергей М. © (01.07.08 23:44) [11]

    > WH_GETMESSAGE .. в активном окне


    Почему бы не существовать и не быть активным окну своего приложения ?

    На аргумент не тянет)

    Впрочем, не суть уже как важно.
  • anwe (02.07.08 09:04) [12]
    Да, верно подмечено, что WH_GETMESSAGE .. в активном окне, это и значит, что через хук ловлю сообщения в чужом окне.

    > Почему бы не существовать и не быть активным окну своего
    > приложения ?

    Так задача такая: если пользователь в любом окне нажал Z - то вставить А с ударением.
  • anwe (02.07.08 09:06) [13]

    > нажал Z - то вставить А с ударением

    Это для примера, а суть теперь думаю понятна.
  • Сергей М. © (02.07.08 09:21) [14]

    > в активном окне, это и значит, что через хук ловлю сообщения
    > в чужом окне


    Вовсе не значит.
    Активным вполне может быть и окно, созданное твоим приложением.


    > если пользователь в любом окне нажал Z - то вставить А с
    > ударением


    Куда "вставить"-то ?
  • anwe (02.07.08 12:08) [15]

    > Куда "вставить"-то ?

    В чужое приложение.

    Еще раз с примером: запускаю программу, которую я делаю. Она устанавливает ловушку на WM_CHAR. Открываю, допустим, блокном. Набираю текст латинскими буквами. Как нажал Z вставляется вместо нее А с ударением.
    А с ударение имеет код $123. Так вот, изменив в wParam структуры MSG код на $123, вижу через отладчик, что до блокнота "доходит" лишь $23, и вставляется символ, соответствующий $23.
    Теперь, думаю, понятно?
    Что и как надо сделать, что в данной конкретной ситуации надо сделать, что поменять код символа на $123?
  • Сергей М. © (02.07.08 13:01) [16]

    > Что и как надо сделать, что в данной конкретной ситуации
    > надо сделать, что поменять код символа на $123?


    В данной конкретной ситуации ничто и никак сделать нельзя, об этом тебе сказано еще в [4] - кодировка в ASCII ограничена одним байтом, а окно блокнота как раз не юникодовое.
  • anwe (02.07.08 13:29) [17]
    Может и не юникодовое, но ситуацию я описал выше и больше байта не проходит.
  • Сергей М. © (02.07.08 13:37) [18]

    > Может и не юникодовое


    Ну а раз не-юникодовое, то что же ты тогда хочешь ?
    Не-юникодовое окно работает только с одним младшим байтом wParam.
    Выше штанов тут не прыгнешь)
  • anwe (02.07.08 13:40) [19]
    А почему когда печатаешь в нем (блокноте) русскими буквами, то посылаются значения от $410 до $44F. Значит штаны шире, чем предполагается?
  • anwe (02.07.08 13:53) [20]
    О, пришел хороший аналогичный вопрос: как же тогда работает транслит в режиме трансляции латинских букв в русские!? Русские же, как я написал выше, имеют кодировку от $410 до $44F!!
  • Сергей М. © (02.07.08 14:45) [21]

    > посылаются значения от $410 до $44F


    Не надо трындеть.

    Вот протокол перехвата сообщений WM_CHAR методом установки глобального хука, записанный одной из известных и надежных утилит SPY++ (идет в составе MS Visual Studio) для как раз твоего случая (в окно редактирования Блокнота посылаются сообщения, соответствующие последовательному нажатию клавиш абвгдАБВГДэюяЭЮЯabcABCxyzXYZ):

    001D06E6 P WM_CHAR chCharCode:'а' (224) cRepeat:1 ScanCode:21 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'б' (225) cRepeat:1 ScanCode:33 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'в' (226) cRepeat:1 ScanCode:20 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'г' (227) cRepeat:1 ScanCode:16 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'д' (228) cRepeat:1 ScanCode:26 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'А' (192) cRepeat:1 ScanCode:21 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'Б' (193) cRepeat:1 ScanCode:33 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'В' (194) cRepeat:1 ScanCode:20 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'Г' (195) cRepeat:1 ScanCode:16 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'Д' (196) cRepeat:1 ScanCode:26 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'э' (253) cRepeat:1 ScanCode:28 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'ю' (254) cRepeat:1 ScanCode:34 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'я' (255) cRepeat:1 ScanCode:2C fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'Э' (221) cRepeat:1 ScanCode:28 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'Ю' (222) cRepeat:1 ScanCode:34 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'Я' (223) cRepeat:1 ScanCode:2C fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'a' (97) cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'b' (98) cRepeat:1 ScanCode:30 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'c' (99) cRepeat:1 ScanCode:2E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'A' (65) cRepeat:1 ScanCode:1E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'B' (66) cRepeat:1 ScanCode:30 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'C' (67) cRepeat:1 ScanCode:2E fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'x' (120) cRepeat:1 ScanCode:2D fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'y' (121) cRepeat:1 ScanCode:15 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'z' (122) cRepeat:1 ScanCode:2C fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'X' (88) cRepeat:1 ScanCode:2D fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'Y' (89) cRepeat:1 ScanCode:15 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    001D06E6 P WM_CHAR chCharCode:'Z' (90) cRepeat:1 ScanCode:2C fExtended:0 fAltDown:0 fRepeat:0 fUp:0

    Как видишь, нет ни одного значения больше 255
  • Leonid Troyanovsky © (02.07.08 15:21) [22]

    > anwe   (02.07.08 13:40) [19]

    > А почему когда печатаешь в нем (блокноте) русскими буквами,
    >  то посылаются значения от $410 до $44F

    Кем посылаются? Чем меряем?
    Код где?

    В блокноте не разу не видел русских букв более $FF.

    --
    Regards, LVT.
  • Leonid Troyanovsky © (02.07.08 15:27) [23]

    > anwe   (02.07.08 13:53) [20]

    > как же тогда работает транслит в режиме трансляции латинских
    > букв в русские!?

    Переведи.

    --
    Regards, LVT.
  • Anatoly Podgoretsky © (02.07.08 16:53) [24]
    > Leonid Troyanovsky  (02.07.2008 15:21:22)  [22]

    Я тоже, даже и меньше $FF, а вот в файле подобные коды наблюдал. От $401 и выше, только для русских букв.
    А почему? А потому что Юникод!
  • Anatoly Podgoretsky © (02.07.08 16:53) [25]
    > Leonid Troyanovsky  (02.07.2008 15:27:23)  [23]

    Зачем?

    транслит в режиме трансляции латинских букв в русские!?

    не работает.
  • anwe (02.07.08 19:25) [26]
    Сергей М. ©   (02.07.08 14:45) [21]

    > Не надо трындеть.


    Leonid Troyanovsky ©   (02.07.08 15:21) [22]

    > Код где?


    Я что, придумал что ли?
    Вот что показывает Олли в стеке блокнота при остановке на TranslateMessage по нажатию на русскую А:

    0006FEEC   0006FEFC //адрес MSG
    0006FEF0   00000000
    0006FEF4   7C80B6A1
    0006FEF8   00091EF8
    0006FEFC   000303BC
    0006FF00   00000102
    0006FF04   00000410
    0006FF08   00210001
    Leonid Troyanovsky ©   (02.07.08 15:27) [23]

    > > как же тогда работает транслит в режиме трансляции латинских
    >
    > > букв в русские!?
    >
    > Переведи.

    Ну что не понятного? Как работает транслит, когда переводит латинские буквы в кириллицу?
  • Сергей М. © (02.07.08 19:56) [27]

    > Вот что показывает Олли в стеке блокнота при остановке на
    > TranslateMessage по нажатию


    А причем здесь WM_CHAR ?

    "по нажатию" - это WM_KEYDOWN, а не WM_CHAR)

    Ты бы хоть справку удосужился почитать, прежде чем почемукать и делать умозрительные выводы !

    Там ведь черным по белому написано:

    The TranslateMessage function translates virtual-key messages into character messages. The character messages are posted to the calling thread's message queue, to be read the next time the thread calls the GetMessage or PeekMessage function.
    ..
    The WM_CHAR message is posted to the window with the keyboard focus when a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR contains the character code of the key that was pressed.
  • Сергей М. © (02.07.08 19:57) [28]
    Так что со штанами все в порядке)
  • Сергей М. © (02.07.08 20:01) [29]
    Трансляция и транслит(ерация), мягко говоря, из разных опер, хотя  оба термина и объединяет один и тот же корень)
  • Leonid Troyanovsky © (02.07.08 20:24) [30]

    > anwe   (02.07.08 19:25) [26]

    > Вот что показывает Олли в стеке блокнота при остановке на
    > TranslateMessage

    Я не знаю, кто такой олли, и что он показывает при остановке.

    Но, from msdn:
    The wParam parameter of all character messages contains the character code of the character key that was pressed. The value of the character code depends on the window class of the window receiving the message. If the Unicode version of the RegisterClass function was used to register the window class, the system provides Unicode characters to all windows of that class. Otherwise, the system provides ASCII character codes.

    Речь об окне, значит, видимо, уже было DispatchMessages, но,
    легко убедиться, что для собсн. приложения, что еще до DM,
    русские буквы в WM_CHAR представляются одним байтом.

    --
    Regards, LVT.
  • anwe (02.07.08 22:30) [31]

    > Сергей М. ©   (02.07.08 19:56) [27]
    >
    > А причем здесь WM_CHAR ?
    >
    > "по нажатию" - это WM_KEYDOWN, а не WM_CHAR)
    >
    > Ты бы хоть справку удосужился почитать, прежде чем почемукать
    > и делать умозрительные выводы !

    Во-первых, TranslateMessage, если по-русски, преобразует аппаратные сообщения клавиатуры в символьные сообщения. Если этим сообщением является WM_KEYDOWN тогда TranslateMessage помещает символьное сообщение в очередь сообщений. То есть WM_CHAR будет следующим, после WM_KEYDOWN, которое функция GetMessage извлечет из очереди сообщений. Так что по нажатию (как ты это акцентируешь) после WM_KEYDOWN придет WM_CHAR.

    Во-вторых, я остановливаю отладчик именно на WM_CHAR

    И в-третьих, по поводу высказывания
    > прежде чем почемукать и делать умозрительные выводы

    могу и в той адрес сделать выпад: если бы ты разбирался в этом, то увидел бы, что в приведенном мною куске кода из стека значится цифирь 102: 0006FF00   00000102. А это не что иное, как номер сообщения, что мы в просторечии именуем WM_CHAR!
  • Сергей М. © (03.07.08 09:11) [32]

    > куске кода из стека значится цифирь 102


    На цифирь сразу не обратил внимания.
    Приношу извинения.
  • Сергей М. © (03.07.08 10:04) [33]
    Проверяй - жми Button1 и следом 'А' в кир.раскладке

    procedure TForm1.Button1Click(Sender: TObject);
    type
     PWMChar = ^TWMChar;
    var
     msg: TMsg;
    begin
     while GetMessage(msg, 0, 0, 0) do begin
       if msg.message = WM_CHAR then
         ShowMessage(IntToHex(PWMChar(@msg.Message).CharCode, 4));
       TranslateMessage(msg);
       DispatchMessage(msg);
     end;
    end;



    Видишь 00C0 ?
    Видишь)
    Где уж ты там при таких же условиях увидел $410 - ума не приложу)
  • Leonid Troyanovsky © (03.07.08 13:31) [34]

    > Leonid Troyanovsky ©   (02.07.08 20:24) [30]

    > Речь об окне, значит, видимо, уже было DispatchMessages,

    Все же, видимо, Dispatch еще не было.
    TranslateMessage при обработке сообщения ориентируется на окно.
    Т.е., если окно не юникодное, то ждать там UTF-16 - бессмысленно.

    --
    Regards, LVT.
  • Renegat (03.07.08 14:12) [35]
    > [26] anwe   (02.07.08 19:25)
    > [33] Сергей М. ©   (03.07.08 10:04)

    OllyDBG совершенно прав. Ибо

    The TranslateMessage function translates virtual-key messages into character messages.
    © Справка

    410h - это всего лишь некий виртуальный код клавиши А. В результате выполнения TranslateMessage он будет преобразован в символьный код, который и правда не может быть больше 0FFh.
  • Renegat (03.07.08 14:17) [36]
    Хм... Отдизасмил нотепад... получил вот это:

    0063FDBC:   00000F9C <---- hWnd, начало _MSG
    0063FDC0:   00000102
    0063FDC4:   00000041

    410h там при нажатии А и правда быть не может!
  • Сергей М. © (03.07.08 16:17) [37]

    > 410h там при нажатии А и правда быть не может


    Конечтно не может)

    см. [21]
  • Anatoly Podgoretsky © (03.07.08 16:38) [38]
    > Сергей М.  (03.07.2008 16:17:37)  [37]

    Код буквы А (русская, заглавная) = $0410
  • anwe (04.07.08 20:24) [39]

    >
    > Код буквы А (русская, заглавная) = $0410

    Вот и еще один чел подтвердил, что А=$410

    > Сергей М. ©   (03.07.08 10:04) [33]
    > Проверяй - жми Button1 и следом 'А' в кир.раскладке

    Мне не нужна кир. раскладка. Посмотри вопрос в [15].
 
Конференция "WinAPI" » Обработка WM_CHAR в WH_GETMESSAGE [D6, WinXP]
Есть новые Нет новых   [134434   +27][b:0][p:0.002]