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

Posted

技术标签:

【中文标题】可以使用 Delphi 在 W7 中禁用任务切换键盘快捷键吗?【英文标题】:Can task-switching keyboard shortcuts be disabled in W7 using Delphi? 【发布时间】:2011-05-01 18:46:34 【问题描述】:

多年来,我的应用程序一直采用一种模式,客户可以“禁用对操作系统的访问”。显然,此功能违背了常规(至少就 Windows 而言),但在某些安装中,我的应用程序是唯一对机器操作员可见的程序,并且在这种情况下,此功能很有用。

我使用的技术是由几个“层”构建的:

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

要禁用我使用的任务栏:

// 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 );

这很好用,在 W7 上看起来仍然很好。 几年前研究如何禁用任务切换发现了“假装”您的应用程序是屏幕保护程序的唯一技术(除了将您的应用程序重命名为“explorer.exe”并启动它等可怕的事情):

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

这似乎在 W7 中没有效果(我认为它适用于 XP 等),这并不奇怪。 有谁知道另一种更好的方法来启用/禁用 Alt-Tab(和其他特殊的 Windows 键)工作?

【问题讨论】:

那么 ctrl-alt-del 呢? 【参考方案1】:

如果找到解决方案:

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;

这会禁用(如您所见!)

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

【讨论】:

@Andreas 你检查了所有的 Win+组合键吗?根据我的经验,某些组合不会被拦截(例如 Win-L)。 @Eugene:哦,我的错。出于安全原因,Win+L 的处理方式当然不同。但我的主张仍然成立,用“几乎所有”代替“全部”。感谢您指出这一点! @Andreas:此代码无法捕捉到 Ctrl-Alt-Del,它可用于启动任务管理器,该任务管理器可以启动另一个应用程序,从而杀死您的好钩子。 @Jeroen:我知道。但至少它回答了这个问题标题中的问题...... 难道没有“组策略”设置也可以处理很多这样的事情吗? Brian,请检查服务器故障,了解系统管理员使用操作系统设置锁定计算机的方式,而不是依赖软件供应商对每个单独的软件包进行锁定。【参考方案2】:

正如 David 所指出的,这称为“Kiosk 模式”。可以在 About.com 上找到几篇好文章(part 1 和 part 2)。

【讨论】:

使用第一个链接上的技巧将不起作用:Windows 7 不再允许您以这种方式捕获 Ctrl-Alt-Del。第二个链接要求您替换 Gina.dll,它替换了完整的登录界面(包括任何第三方,例如启用指纹登录),这可能是一个大问题。 @Jeroen “kiosk 模式”通常意味着对系统的完全控制,因此更换 GINA dll 不是问题。然而事实证明,OP 不需要 kios 模式。【参考方案3】:

有Windows Embedded Standard 7,您可以将其打包成真正的信息亭模式。

【讨论】:

谢谢,我知道 WE。我需要的不是完整的“信息亭”模式,而是阻止好奇或愚蠢的手指。【参考方案4】:

dWinLock 也提供了解决方案。 IIRC,他们安装了一个可以停止 Ctrl+Alt+Del 的服务。

【讨论】:

我认为 dwinLock 在 Win7 中无法正常工作。虽然他们现在声明支持Win7,所以我想有一个新版本。我用过,非常非常流畅。 @Warren:一个有用的解决方案。我看到他们提到“32 位”不清楚这是对操作系统还是应用程序的限制,所以我给他们发了电子邮件。 @Warren:是的,它支持在 W7/64 下运行的 Delphi 32 位应用程序

以上是关于可以使用 Delphi 在 W7 中禁用任务切换键盘快捷键吗?的主要内容,如果未能解决你的问题,请参考以下文章

“使用 windows xp 风格的 dpi 缩放”禁用 W7 上任务栏的自动自动隐藏。解决方法?

win7中的所有快捷键?

Winform怎么禁用win键,alt+atb

Delphi中无边框窗体应用程序使任务栏右键菜单有效的方法

Delphi工具栏按钮在单元和表单视图之间切换消失了?

在DELPHI中切换窗口问题