-
Отлавливаю сообщения WM_CHAR в активном окне. Как поймал нужный символ изменяю его код на код другой буквы, не английской, но вывести ее не удается. Как изменить параметры WM_CHAR, чтобы отправить окну код буквы в Unicode? Через отладчик заметил, что если, допустим, я меняю код символа на 123, то до окна доходит лишь байт, то есть 23.
-
WM_UNICHAR ?
-
> anwe (01.07.08 08:38)
> Отлавливаю сообщения WM_CHAR в активном окне. Как поймал > нужный символ изменяю его код на код другой буквы, не английской, > но вывести ее не удается.
Ошибка в 17 строке.
> Как изменить параметры WM_CHAR, чтобы отправить окну код > буквы в Unicode?
Он и так в UTF-16, если словлен WM_CHAR.
> меняю код символа на 123, то до окна доходит лишь байт, > то есть 23
123 - это тоже байт.
-- Regards, LVT.
-
> WM_UNICHAR ?А почему та справка, что прилагается к пакету Deplhi (6), это сообщение не знает? Подсказали, что его номер = $109, но Олли такое сообщение не отлавливает, да и моя ловушка тоже. Что касается > Ошибка в 17 строке.так это не верно. Нет, я знаю, что означает такой ответ, но в коде все верно, ведь с английскими буквами работает. А 123 я имел ввиду $123. Думал это понятно, но признаю - это моя ошибка и имею ли я ввиду десятичную или шестнадцатиричную систему никому не известно. Но по сути. Если изменить: Msg(Pointer(lParam)^).wParam: = $123 то до приложения доходит $23. Как сделать чтобы приложение получило код символа размером в слово???
-
> anwe (01.07.08 20:50) [3]
> но в коде все верно, ведь с английскими буквами работает.
Да-да, "но вывести ее не удается".
> Msg(Pointer(lParam)^).wParam: = $123 //код символа $123
В чем сакральный оного символа?
Если окно не юникодное, то из четырех байт wParam будет использован только один - ASCII character codes.
> Как сделать чтобы приложение получило код символа размером > в слово???
Неверная постановка. См. выше.
-- Regards, LVT,
-
> Как сделать чтобы приложение получило код символа размером > в слово?
Цитата из станд.справки:
If applications process virtual-key messages for some other purpose, they should not call TranslateMessage
-
> Сергей М. © (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.
-
> Приложение-то чужое
Почем мне знать, чужое оно или свое ?
Автор об этом сказать не соизволил)
-
> Leonid Troyanovsky © (01.07.08 23:06) [4]
> В чем сакральный оного символа?
Выпал смысл, sorry.
-- Regards, LVT.
-
> Сергей М. © (01.07.08 23:33) [7]
> Автор об этом сказать не соизволил)
WH_GETMESSAGE .. в активном окне.
-- Regards, LVT.
-
> Автору же надо сосредоточиться на постановке задачи
Эт точно)
А то на сей момент задача выглядит более чем странно: перехват посылки с фасованой репой и подмена содержимого на заморский прямо с грядки корнеплод, в надежде что адресат схавает его вместе с ботвой и не подавится)
-
> WH_GETMESSAGE .. в активном окне
Почему бы не существовать и не быть активным окну своего приложения ?
На аргумент не тянет)
Впрочем, не суть уже как важно.
-
Да, верно подмечено, что WH_GETMESSAGE .. в активном окне, это и значит, что через хук ловлю сообщения в чужом окне.
> Почему бы не существовать и не быть активным окну своего > приложения ?
Так задача такая: если пользователь в любом окне нажал Z - то вставить А с ударением.
-
> нажал Z - то вставить А с ударением
Это для примера, а суть теперь думаю понятна.
-
> в активном окне, это и значит, что через хук ловлю сообщения > в чужом окне
Вовсе не значит. Активным вполне может быть и окно, созданное твоим приложением.
> если пользователь в любом окне нажал Z - то вставить А с > ударением
Куда "вставить"-то ?
-
> Куда "вставить"-то ?
В чужое приложение.
Еще раз с примером: запускаю программу, которую я делаю. Она устанавливает ловушку на WM_CHAR. Открываю, допустим, блокном. Набираю текст латинскими буквами. Как нажал Z вставляется вместо нее А с ударением. А с ударение имеет код $123. Так вот, изменив в wParam структуры MSG код на $123, вижу через отладчик, что до блокнота "доходит" лишь $23, и вставляется символ, соответствующий $23. Теперь, думаю, понятно? Что и как надо сделать, что в данной конкретной ситуации надо сделать, что поменять код символа на $123?
-
> Что и как надо сделать, что в данной конкретной ситуации > надо сделать, что поменять код символа на $123?
В данной конкретной ситуации ничто и никак сделать нельзя, об этом тебе сказано еще в [4] - кодировка в ASCII ограничена одним байтом, а окно блокнота как раз не юникодовое.
-
Может и не юникодовое, но ситуацию я описал выше и больше байта не проходит.
-
> Может и не юникодовое
Ну а раз не-юникодовое, то что же ты тогда хочешь ? Не-юникодовое окно работает только с одним младшим байтом wParam. Выше штанов тут не прыгнешь)
-
А почему когда печатаешь в нем (блокноте) русскими буквами, то посылаются значения от $410 до $44F. Значит штаны шире, чем предполагается?
-
О, пришел хороший аналогичный вопрос: как же тогда работает транслит в режиме трансляции латинских букв в русские!? Русские же, как я написал выше, имеют кодировку от $410 до $44F!!
-
> посылаются значения от $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
-
> anwe (02.07.08 13:40) [19]
> А почему когда печатаешь в нем (блокноте) русскими буквами, > то посылаются значения от $410 до $44F
Кем посылаются? Чем меряем? Код где?
В блокноте не разу не видел русских букв более $FF.
-- Regards, LVT.
-
> anwe (02.07.08 13:53) [20]
> как же тогда работает транслит в режиме трансляции латинских > букв в русские!?
Переведи.
-- Regards, LVT.
-
> Leonid Troyanovsky (02.07.2008 15:21:22) [22]
Я тоже, даже и меньше $FF, а вот в файле подобные коды наблюдал. От $401 и выше, только для русских букв. А почему? А потому что Юникод!
-
> Leonid Troyanovsky (02.07.2008 15:27:23) [23]
Зачем?
транслит в режиме трансляции латинских букв в русские!?
не работает.
-
Сергей М. © (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]
> > как же тогда работает транслит в режиме трансляции латинских > > > букв в русские!? > > Переведи.
Ну что не понятного? Как работает транслит, когда переводит латинские буквы в кириллицу?
-
> Вот что показывает Олли в стеке блокнота при остановке на > 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.
-
Так что со штанами все в порядке)
-
Трансляция и транслит(ерация), мягко говоря, из разных опер, хотя оба термина и объединяет один и тот же корень)
-
> 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.
-
> Сергей М. © (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!
-
> куске кода из стека значится цифирь 102
На цифирь сразу не обратил внимания. Приношу извинения.
-
Проверяй - жми 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 © (02.07.08 20:24) [30]
> Речь об окне, значит, видимо, уже было DispatchMessages,
Все же, видимо, Dispatch еще не было. TranslateMessage при обработке сообщения ориентируется на окно. Т.е., если окно не юникодное, то ждать там UTF-16 - бессмысленно.
-- Regards, LVT.
-
> [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.
-
Хм... Отдизасмил нотепад... получил вот это:
0063FDBC: 00000F9C <---- hWnd, начало _MSG 0063FDC0: 00000102 0063FDC4: 00000041
410h там при нажатии А и правда быть не может!
-
> 410h там при нажатии А и правда быть не может
Конечтно не может)
см. [21]
-
> Сергей М. (03.07.2008 16:17:37) [37]
Код буквы А (русская, заглавная) = $0410
-
> > Код буквы А (русская, заглавная) = $0410
Вот и еще один чел подтвердил, что А=$410
> Сергей М. © (03.07.08 10:04) [33] > Проверяй - жми Button1 и следом 'А' в кир.раскладке
Мне не нужна кир. раскладка. Посмотри вопрос в [15].
|