Форум: "WinAPI";
Текущий архив: 2006.12.24;
Скачать: [xml.tar.bz2];
ВнизУзнать активный элемент окна, имея хендл окна Найти похожие ветки
← →
Lezha (2006-08-16 17:42) [0]Здравствуйте, написал хук, который перехватывает нажатие стрл+ээ и должен заменять его апостроф. Проблема в том, что я не могу узнать дескриптор елемента ввода, который имеет фокус.
SendMessage(GetFocus, WM_CHAR, Ord(""""),1); -- не работает.
При передаче Application.MainForm.ActiveMDIChild.ActiveControl.Handle апостроф отсылается не туда, если текст вводится в модальном диалоговом окне.
← →
Lezha (2006-08-16 17:55) [1]Хм, может проблема вообще в другом? Не работает:
SendMessage(memo.Handle, WM_KEYUP, Ord(""""),1);
← →
Ketmar © (2006-08-16 21:54) [2]а с какого испугу WM_KEYUP должно так работать? так VK_xxx посылать надо, а не код символа.
← →
begin...end © (2006-08-17 11:00) [3]И если уж посылать WM_KEYUP, то асинхронно.
← →
Lezha (2006-08-17 11:46) [4]WM_KEYUP -- это для примера. Я пробовал в трех вариантах: WM_KEYUPб WM_KEYDOWN и WM_CHAR, пробовал и код символа, и вирт. код (VK_TAB, VK_SPACE) -- ничего не работает.
Кстати, мемо -- объект класса TDBMemo.
А что значит посылать асинхронно? Асинхронно чему? Извините, если вопрос глупый... :)
← →
begin...end © (2006-08-17 11:53) [5]> Lezha (17.08.06 11:46) [4]
> А что значит посылать асинхронно?
Через PostMessage, например. Но моё замечание относилось только к посылке WM_KEYDOWN/WM_KEYUP, а не WM_CHAR.
А хук только в пределах потока Вашего приложения устанавливается? И какой?
← →
Ketmar © (2006-08-17 11:57) [6]> [4] Lezha (17.08.06 11:46)
PostMessage(). потому что так правильно. %-)
← →
Lezha (2006-08-17 11:59) [7]Да, хук локальный, но с хуком все ок -- он работает правильно. Изначально я хотел в хуке поджменить коды клавиш, но ничего не получилось. Хук на сообщение WH_KEYBOARD.
function KeyBoardHook(code: integer; wParam: word; lParam: longword): longword; stdcall;
var Input: TInput;
begin
if code<0 then begin //if code is <0 your keyboard hook should always run CallNextHookEx instantly and
KeyBoardHook:=CallNextHookEx(CurrentHook,code,wParam,lparam); //then return the value from it.
Exit;
end;
// if (lParam and KF_UP)=0 then sysutils.beep; //if the key is being pressed, not releases, BEEP!
if (wParam = 222)and(HiWord(GetAsyncKeyState(VK_CONTROL))<>0) then
begin
Inc(Status);
if Status=4 then
begin
beep;
Status := 0;
with PKbDllHookStruct(lParam)^ do
begin
FillChar(Input,SizeOf(Input),0);
Input.Itype:=INPUT_KEYBOARD;
Input.ki.wVk:=Key_Apostrophe;
Input.ki.dwFlags:=0;
// SendInput(1,Input,SizeOf(Input));
SendMessage(Application.MainForm.ActiveMDIChild.ActiveControl.Handle, WM_CHAR, Ord(""""),1);
end;
Result := 1;
Exit;
end;
end else Status := 0;
CallNextHookEx(CurrentHook,code,wParam,lparam); //call the next hook proc if there is one
KeyBoardHook:=0;
end;
← →
Lezha (2006-08-17 12:05) [8]PostMessage тоже не работает (пробовал WM_CHAR, WM_KEYDOWN, отсылал как Ord(""""), так и VK_TAB).
← →
Ketmar © (2006-08-17 12:06) [9]в хуке коды не подменяются. для этого ставь хук на GetMessage() и меняй параметры сообщения.
← →
begin...end © (2006-08-17 12:07) [10]> Lezha (17.08.06 11:59) [7]
> Изначально я хотел в хуке поджменить коды клавиш, но ничего
> не получилось.
И не получится. А вот если поставить хук WH_GETMESSAGE, то параметры сообщений (в том числе, и WM_KEYDOWN/WN_KEYUP/WM_CHAR) изменять будет можно. Может быть, так и поступить?
← →
Lezha (2006-08-17 12:56) [11]Спасибо, пробую, только вот не могу найти, как мне определить коды при нажатии стрл+ээ. Дебаггом не получается -- даже активизировать окно не могу, брейкпоинт прерывает выполнение.
← →
Ketmar © (2006-08-17 13:05) [12]> [11] Lezha (17.08.06 12:56)
выводи полученое в memo, например. посмотри, что выведется после соответствующих нажатий. %-)
← →
Lezha (2006-08-17 13:47) [13]:)) Блин, точно, стормозил.
Сейчас-то оно работает, но с раскладкой проблемма. То есть на стрл+ээ оно отсылает символ "э". Ведь оно ловит сканкоды клавиш, которые от раскладки на зависят, то есть я вроде не могу отослать апостроф без сендМесиджа? :(
function KeyBoardHook(code: integer; wParam: word; lParam: longword): longword; stdcall;
var KeyState : TKeyboardState;
begin
if code<0 then begin
KeyBoardHook:=CallNextHookEx(CurrentHook,code,wParam,lparam);
Exit;
end;
if (PEventMsg(lParam)^.paramH=222)and(GetAsyncKeyState(VK_CONTROL)<>0)then
begin
Inc(Status);
if Status=2 then
begin
GetKeyboardState(KeyState);
KeyState[VK_CONTROL] := not KeyState[VK_CONTROL];
SetKeyboardState(KeyState);
Status := 0;
end;
end;// else Status := 0;
CallNextHookEx(CurrentHook,code,wParam,lparam);
KeyBoardHook:=0;
end;
← →
Ketmar © (2006-08-17 13:52) [14]> [13] Lezha (17.08.06 13:47)
странная логика -- перемешивать GetAsyncKeyState() и GetKeyboardState()... они могут и отличаться, между прочим. %-)
← →
Ketmar © (2006-08-17 13:52) [15]в смысле -- рузкльтаты могут отличаться.
← →
Lezha (2006-08-17 13:55) [16]Просто я не нашел SetAsyncKeyState() :)
По теме: переключал раскладку: LoadKeyboardLayout(StrCopy(Layout,"00000409"),KLF_ACTIVATE);
Но назад-то ее нельзя вернуть. Может есть еще решения?
← →
Ketmar © (2006-08-17 13:58) [17]> [16] Lezha (17.08.06 13:55)
почему нельзя? кто запрещает старую запомнить?
← →
Lezha (2006-08-17 14:07) [18]CallNextHookEx(CurrentHook,code,wParam,lparam); //call the next hook proc if there is one
KeyBoardHook:=0; //if KeyBoardHook returns a non-zero value, the window that should get
//the keyboard message doesnt get it.
if Status=2 then
begin
LoadKeyboardLayout( StrCopy(Layout,"00000419"),KLF_ACTIVATE);
Status := 0;
end;
Это я ставил в конце хука. Раскладка сначала возвращается, а потом уже сообщение передается.
← →
GrayFace © (2006-08-17 19:53) [19]А зачем тут менять раскладку?
Еще можно использовать keybd_message. И можно без хука.
Lezha (17.08.06 11:59) [7]
Да, хук локальный, но с хуком все ок -- он работает правильно.
А вот и нет.
Lezha (17.08.06 11:59) [7]
function KeyBoardHook(code: integer; wParam: word; lParam: longword): longword; stdcall;
Надо function KeyBoardHook(code: integer; wParam, lParam: longint): longint; stdcall;
Lezha (17.08.06 13:55) [16]
Просто я не нашел SetAsyncKeyState() :)
Есть еще GetKeyState.
← →
Lezha (2006-08-18 14:24) [20]GrayFace, все-таки, на вижу смысла менять хук, если он правильно вызывается и работает в таком виде :)
К сожалению, функции keybd_message нигде не нашел, нашел только keybd_event, но она также передает "э" вместо апострофа:
keybd_event(Key_Apostrophe, 222, 0, 0); или
keybd_event(Key_Apostrophe, 39, 0, 0);
SendMessage(PEventMsg(lParam)^.hwnd, WM_CHAR, 222, 1); или
SendMessage(PEventMsg(lParam)^.hwnd, WM_CHAR, 39, 1);
также отсылают "э".
К сожалению, решение проблемы вижу только в переключении раскладки, но вот как вернуть ее назад... :(
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2006.12.24;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.046 c