Хуки... Может и можно. По идеи, сообщение о нажатии клавиши сначала проходит по всем хукам, а потом идет к программам. Так что по идеи можно своим хуком подменить сообщение о нажатии/отпускании на другую кнопку.
Не пробовал переназначить, но вот код хука, который я когда-то писал (блочит всякие кнопки):
Код:
library KeyBoardBlock;
uses Windows,messages;
type
KBDLLHOOKSTRUCT = record
vkCode: LongWord;
scanCode: LongWord;
flags: LongWord;
time: LongWord;
dwExtraInfo:Pointer;
end;
PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;
var
KeyHookHandle: hHook = 0;
RUN:boolean = false;
hMain: hWnd = 0;
const
LLKHF_ALTDOWN = KF_ALTDOWN shr 8;
function KeyboardProc(nCode: integer; wParam: longint; lParam: longint): integer; stdcall;
var
p: PKBDLLHOOKSTRUCT;
begin
if (nCode = HC_ACTION) then
begin
p := PKBDLLHOOKSTRUCT(lParam);
case wparam of
WM_KEYDOWN, WM_SYSKEYDOWN:
if not run then begin
RUN:=((p^.flags and LLKHF_ALTDOWN) <> 0)and // RUN-флаг запуска хука
((GetKeyState(VK_SHIFT)and $8000) <> 0)and // у меня активируется через
(p^.scanCode = 33); // Alt+Shift+F
end;
end;
if (run) then // Если запущено (нажали Alt+Shift+F)
begin
case wParam of
WM_KEYDOWN, WM_SYSKEYDOWN, // Нажата какая-то клавиша
WM_KEYUP, WM_SYSKEYUP:
begin
sendmessage(hmain,wparam,p^.vkCode,0); // перенаправляем в мое приложение
result := 1; // Если не 0 - то сообщение дальше не пойдет
end;
end;
end
else // Если НЕ запущен
result := CallNextHookEx(0, nCode, wParam, lParam); // Передаем следующему хуку
end;
end;
// установка, отключение ловушки
procedure RunStopHook(lRun:byte; HM:hWnd); export; stdcall;
begin
if lRun=0 then begin
KeyHookHandle:=SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardProc, HInstance, 0);
hMain:=HM;
end
else if lRun=2 then
begin
UnhookWindowsHookEx(KeyHookHandle);
KeyHookHandle:=0;
end;
end;
// Возврат. Если передали 0 - вырубаем (Run:=false), сбрасываем возможно "залипшие"
// кнопки ALT и SHIFT, 1 - проверка, включен ли хук, 2 - ручной запуск
function Return(State:byte):boolean; export; stdcall;
begin
if state=0 then begin
Run:=false;
keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
end
else if state=1 then result:=RUN
else run:=true;
end;
exports RunStopHook name 'RunStopHook';
exports Return name 'Return';
begin
end.
ставится мой хук вызовом RunStopHook(0,Form1.Handle), включается через Alt+Shift+F или вручную из программы.
Если включен - перенаправляет все нажатия кнопок на мою форму, остальные же кнопок не слышат (жаль, что ALT+CTRL+DEL не вырубается. Похоже, он стоит на первом хуке в системе, поэтому его вырубить так нереально).
В твоем случае наверно надо поставить при
Код:
result := CallNextHookEx(0, nCode, wParam, lParam); // Передаем следующему хуку
новую клавишу.
З.Ы. возможно че-то нужное убрал, но вроде нет. Там просто был еще хук на мышь, который к делу отношения не имеет.