Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.24;
Скачать: CL | DM;

Вниз

Узнать активный элемент окна, имея хендл окна   Найти похожие ветки 

 
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 вся ветка

Текущий архив: 2006.12.24;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.059 c
2-1165313272
daser
2006-12-05 13:07
2006.12.24
Как перевести символ в шестнадцатиричную строку и обратно?


15-1165218074
Kolan
2006-12-04 10:41
2006.12.24
Два вопроса по BDS2006


15-1164755613
Real
2006-11-29 02:13
2006.12.24
Ссылка на папку вида - file://10.0.0.200/folder


15-1165178576
Real
2006-12-03 23:42
2006.12.24
Тюнеры от AverMedia - управление громкостью


2-1164802899
Alex870
2006-11-29 15:21
2006.12.24
Какой файл играет WMPlayer