使用Delphi可以在W7中禁用任务切换键盘快捷键吗?

Bri*_*ost 9 windows delphi taskbar task-switching

我的应用程序已经有一种模式多年,客户可以"禁用对操作系统的访问".显然这个功能与谷物相悖(至少就Windows而言),但有些安装我的应用程序是唯一一个应该可见的机器操作员程序,在这种情况下这样的功能是有用的.

我使用的技术是从几个"层"构建的:

  1. 隐藏任务栏和按钮.
  2. 禁用任务切换.
  3. 禁用我的主表单系统图标.

要禁用我使用的任务栏:

// Get a handle to the taskbar and its button..
Taskbar := FindWindow('Shell_TrayWnd', Nil);
StartButton := FindWindow('Button', Nil);

// Hide the taskbar and button
if Taskbar <> 0 then
  ShowWindow( Taskbar, SW_HIDE );
if StartButton <> 0 then
  ShowWindow( StartButton, SW_HIDE );

// Set the work area to the whole screen
R := Rect( 0,0,Screen.Width,Screen.Height );
SystemParametersInfo(
  SPI_SETWORKAREA,
  0,
  @R,
  0 );
Run Code Online (Sandbox Code Playgroud)

这很好用,但在W7上似乎还算不错.研究如何在几年前禁用任务切换发现了唯一一种"假装"你的应用程序是屏幕保护程序的技术(除了将应用程序重命名为'explorer.exe'并启动它等等)之外的其他方法:

procedure EnableTaskSwitching( AState : boolean );
// Enables / disables task switching
begin
  SystemParametersInfo(
    SPI_SCREENSAVERRUNNING,
    Cardinal( not AState),
    nil,
    0 );
end;
Run Code Online (Sandbox Code Playgroud)

毫不奇怪,这似乎对W7没有影响(我认为它适用于XP等).有没有人知道启用/禁用Alt-Tab(以及其他特殊的Windows键)的另一种更好的方法?

And*_*and 9

如果找到解决方案:

function LowLevelKeyboardProc(nCode: integer; wParam: WPARAM; lParam: LPARAM):
  LRESULT; stdcall;
type
  PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;
  TKBDLLHOOKSTRUCT = record
    vkCode: cardinal;
    scanCode: cardinal;
    flags: cardinal;
    time: cardinal;
    dwExtraInfo: Cardinal;
  end;

  PKeyboardLowLevelHookStruct = ^TKeyboardLowLevelHookStruct;
  TKeyboardLowLevelHookStruct = TKBDLLHOOKSTRUCT;
const
  LLKHF_ALTDOWN = $20;
var
  hs: PKeyboardLowLevelHookStruct;
  ctrlDown: boolean;
begin

  if nCode = HC_ACTION then
  begin

    hs := PKeyboardLowLevelHookStruct(lParam);
    ctrlDown := GetAsyncKeyState(VK_CONTROL) and $8000 <> 0;
    if (hs^.vkCode = VK_ESCAPE) and ctrlDown then
      Exit(1);
    if (hs^.vkCode = VK_TAB) and ((hs^.flags and LLKHF_ALTDOWN) <> 0) then
      Exit(1);
    if (hs^.vkCode = VK_ESCAPE) and ((hs^.flags and LLKHF_ALTDOWN) <> 0) then
      Exit(1);
    if (hs^.vkCode = VK_LWIN) or (hs^.vkCode = VK_RWIN) then
      Exit(1);

  end;

  result := CallNextHookEx(0, nCode, wParam, lParam);

end;

procedure TForm1.FormShow(Sender: TObject);
begin
  SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc, 0, 0);
end;
Run Code Online (Sandbox Code Playgroud)

这会禁用(如您所见!)

  • Ctrl + Esc(显示开始菜单)
  • Alt + Tab(任务切换)
  • Alt + Esc(任务切换)
  • 赢(显示开始菜单)
  • Win + Tab(3D任务切换)
  • 赢+ D,赢+ M,赢+空间,赢+箭,赢+ P,赢+ U,赢+ E,赢+ F,赢+数字,...
  • 几乎任何组合,包括Windows键(但不是全部,例如Win + L)


Eug*_*its 6

正如大卫所指出的,这被称为"Kiosk模式".在About.com上可以找到几篇好文章(第1部分第2部分).