2009. december 25., péntek

Minimize an application by pressing [ALT] [TAB]

Problem/Question/Abstract:

I would like to be able to minimize my application if the user presses [ALT] + [TAB]. Will I need to hook the keyboard for this? There is lot of code around to disable [ALT] [TAB] but nothing to detect it.

Answer:

This works on WinNT SP3+, Win2K and WinXP:

{ ... }
var
FHook: HHook = 0;

const
WH_KEYBOARD_LL = 13;
LLKHF_ALTDOWN = KF_ALTDOWN shr 8;

type
tagKBDLLHOOKSTRUCT = packed record
vkCode: DWord;
scanCode: DWord;
flags: DWord;
time: DWord;
dwExtraInfo: PDWord;
end;
TKBDLLHOOKSTRUCT = tagKBDLLHOOKSTRUCT;
PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;
{ ... }

function LowLevelKeyboardProc(HookCode: Longint; MessageParam: WParam;
StructParam: LParam): DWord; stdcall;
var
SwitchingTask: Boolean;
P: PKBDLLHOOKSTRUCT;
begin
SwitchingTask := False;
if (HookCode = HC_ACTION) then
case (MessageParam) of
WM_KEYDOWN, WM_SYSKEYDOWN, WM_KEYUP, WM_SYSKEYUP:
begin
P := PKBDLLHOOKSTRUCT(StructParam);
SwitchingTask := ((P.VKCode = VK_TAB) and (P.Flags and LLKHF_ALTDOWN <> 0))
or
((P.VKCode = VK_ESCAPE) and ((P.Flags and LLKHF_ALTDOWN) <> 0)) or
((P.VKCode = VK_ESCAPE) and ((GetKeyState(VK_CONTROL)
and $8000) <> 0));
end;
end;
if SwitchingTask then
begin
{If you want to disable task switch just uncomment next two lines}
// Result := 1;
// Exit;
{If not, put your code here...}
Application.Minimize;
end;
Result := CallNextHookEx(0, HookCode, MessageParam, StructParam);
end;

procedure SetHook;
begin
FHook := SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc, Hinstance, 0);
end;

procedure UnHook;
begin
if FHook > 0 then
UnHookWindowsHookEx(FHook);
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
SetHook;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
UnHook;
end;


Nincsenek megjegyzések:

Megjegyzés küldése