Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > OleContainer KeyBoard Hook


Автор: rith2 6.7.2009, 06:40
Привет.

В загруженном в OleContainer'е MS Word - сменить раскладку нажатием альт + шифт нельзя. Но работает Шифт + альт + альт. Сделал хук на клавиатуру - перехватывает Альт + Шифт и отправляет на ввод Шифт + Альт + Альт.

Проблема - С левым Альт+Шифт все работает отлично. Но при нажатии правого Альт + Шифт - OleContainer подвисает не надолго и теряет фокус, тоже самое если ЛевыйАльт (ЛевыйШифт) и ПравыйШифт (Правый Альт). 

После использования правых Альт либо Шифт - до этого нормально работающая комба ЛевыйАльт + ЛевыйШифт начинает дико тормозить

Не могу понять почему. Команды отправляю с помощью SendInput

Код

library hookDLL;

uses
 ....
const
  WM_KEYEVENT = WM_USER+1;

var
  HookHandle: HHOOK;
  KeybrdState:TKeyboardState;
  keycombo:boolean;

//Смена раскладки
procedure ChangeLayout();
var
  KeyInputs : Array of TInput;
  KeyInputCount : Integer;
    //Запись команд в массив для SendInput
    procedure KeyBdInput(VKey : Byte; Flags : DWord);
      begin {1}
        Inc(KeyInputCount);
        SetLength(KeyInputs, KeyInputCount);
        KeyInputs[KeyInputCount - 1].Itype := INPUT_KEYBOARD;
        with KeyInputs[KeyInputCount - 1].ki do
          begin {2}
            wVk := VKey;
            wScan := MapVirtualKey(wVk, 0);
            dwFlags := KEYEVENTF_EXTENDEDKEY;
            dwFlags := Flags or dwFlags;
            time := 0;
            dwExtraInfo := 0;
          end; {2}
      end;  {1}
begin
  KeyBdInput(VK_LSHIFT, 0);
  KeyBdInput(VK_LMENU, 0);
  KeyBdInput(VK_LMENU, KEYEVENTF_KEYUP);
  KeyBdInput(VK_LMENU, 0);
  KeyBdInput(VK_LMENU, KEYEVENTF_KEYUP);
  KeyBdInput(VK_LSHIFT, KEYEVENTF_KEYUP);
  SendInput(KeyInputCount, KeyInputs[0], SizeOf(KeyInputs[0]));
end;

function KeyHook(CODE, WParam, LParam: DWORD): DWORD; stdcall;
var
  ServerWnd: THandle;
  ScanCode:integer;
  winname:PChar;
  hkl_:HKL;
  LeftShift, LeftAlt, LeftButtons : boolean;
  RightShift, RightAlt, RightButtons : boolean;
begin
  LeftButtons := false;
  RightButtons := false;
  winname := 'Edit ActiveX Control -';
  if (CODE = HC_ACTION) and ((lparam and $80000000) <> $80000000) then
    begin
      LeftShift := GetAsyncKeyState(VK_LSHIFT) <> 0;
      LeftAlt := GetAsyncKeyState(VK_LMENU) <> 0;
      LeftButtons := LeftShift and LeftAlt;

      RightShift := GetAsyncKeyState(VK_RSHIFT) <> 0;
      RightAlt := GetAsyncKeyState(VK_RMENU) <> 0;
      RightButtons := RightShift and RightAlt;

      if (LeftButtons) or (RightButtons) or
                (LeftAlt and RightShift) or (RightAlt and LeftShift) then
        begin
          ChangeLayout();
        end;
end;
  Result:=CallNextHookEx(HookHandle, code, WParam, LParam);
end;

procedure SetKeyHook; stdcall; export;
begin
  if HookHandle=0 then
    begin
     keycombo:= false;
     HookHandle:=SetWindowsHookEx(WH_KEYBOARD, @KeyHook, hInstance, 0);
    end;
end;

procedure DelKeyHook; stdcall; export;
begin
  if HookHandle <> 0 then UnhookWindowsHookEx(HookHandle);
   HookHandle:=0;
end;

exports
  SetKeyHook, DelKeyHook;
begin
end.



Спасибо за любую помощь!

Автор: rith2 6.7.2009, 07:54
Немного переделал с 58 по 66 строки

Код

......
 LeftShift := GetAsyncKeyState(VK_SHIFT) <> 0;
      Alt := GetAsyncKeyState(VK_MENU) <> 0;
      Buttons := Shift and Alt;
      if Buttons then
          ChangeLayout();


ибо прочитал описание к GetAsyncKeyState и там написано, что  "Вы можете использовать константы кода виртуальной клавиши VK_SHIFT, VK_CONTROL и VK_MENU как значения для параметра vKey. Это дает состояние клавиш SHIFT, CTRL или ALT без различия между левой и правой сторонами."

Результат - ничего не изменилось

Автор: dumb 7.7.2009, 11:14
начнем с того, что смены раскладки не обязательно "жать" кнопки.
продолжим тем, что подвергнем сомнению твою предпосылку к написанию какого-то странного кода:
Цитата(rith2 @  6.7.2009,  07:40 Найти цитируемый пост)
В загруженном в OleContainer'е MS Word - сменить раскладку нажатием альт + шифт нельзя.

ну и закончим на мысли о возникающей в твоем коде рекурсии.

Автор: rith2 8.7.2009, 05:27
Цитата

ну и закончим на мысли о возникающей в твоем коде рекурсии. 


Эхх... присвойте мне статус быдлокодер  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)