Search code examples
windowsdelphiwindows-8screen

Delphi application - Block windows-key (Start) on Windows 8


I' programming a Delphi application. My goal is to cover ALL screen with my application to force user to fill my form. Application will be run as scheduled task.

My problem is, that normally, Windows does not allow applications to block other users action.

In Windows 7 I can run my application as scr file (screen saver), with no title bar and set StayOnTop. In this case, other application even if visible on "Window key" (start), stays behind my application, so my goal is reached. Unfortunately, in Windows 8 this solution does not work because "window key" shows start screen, when I can run anything and this "anything" stays on top.

I tried some trick with code below, but without success.

  h := FindWindowEx(FindWindow('Shell_TrayWnd', nil),0,'Button',nil);
  ShowWindow(h,0); 
  Windows.SetParent(h,0);

How to block 'window key' (start button) action in the entire Windows 8 system?


Solution

  • I didn't test it on windows 8, but in principle one can use a keyboard hook to discard the key-press.

    Something similar to the following:

    const   
        WH_KEYBOARD_LL   =   13;
        LLKHF_ALTDOWN    =   $00000020;
        LLKHF_INJECTED   =   $00000010;
    
    type
        tagKBDLLHOOKSTRUCT   =   record
            vkCode:   DWORD;
            scanCode:   DWORD;
            flags:   DWORD;
            time:   DWORD;
            dwExtraInfo:   DWORD;
          end;
        KBDLLHOOKSTRUCT   =   tagKBDLLHOOKSTRUCT;
        LPKBDLLHOOKSTRUCT   =   ^KBDLLHOOKSTRUCT;
        PKBDLLHOOKSTRUCT   =   ^KBDLLHOOKSTRUCT;
    
    var
        hhkLowLevelKybd:   HHOOK;
    
    function LowLevelKeyBoardProc(nCode:   Integer;   awParam:   WPARAM;   alParam:   LPARAM):   LRESULT;   stdcall;
    var
        fEatKeyStroke:   Boolean;
        p:   PKBDLLHOOKSTRUCT;
    begin
        fEatKeystroke   :=   False;
        if active and(  nCode   =   HC_ACTION)   then
        begin
            case   awParam   of
                WM_KEYDOWN,
                WM_SYSKEYDOWN,
                WM_KEYUP,
                WM_SYSKEYUP:
                    begin
                        p   :=   PKBDLLHOOKSTRUCT(alParam);
                        if DisableWinKeys then
                         begin
                          if p^.vkCode   =   VK_LWIN
                            then fEatKeystroke   :=   True;
                          if p^.vkCode   =   VK_RWIN
                            then fEatKeystroke   :=   True;
                         end;
                    end;
            end;
        end;
        if   fEatKeyStroke   then
            Result := 1
        else
            Result := CallNextHookEx(hhkLowLevelKybd, nCode, awParam, alParam);
    end;
    
    procedure InstallHook;
    begin
      if hhkLowLevelKybd <> 0 then exit;
      hhkLowLevelKybd := SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc,   hInstance,   0);
    end;
    
    procedure UninstallHook;
    begin
      if hhkLowLevelKybd = 0 then exit;
      UnhookWindowsHookEx(hhkLowLevelKybd);
      hhkLowLevelKybd := 0;
    end;