3

是否可以使应用系统的主要形式成为模态?我的应用程序将从远程公司 PC 上 FTP 文件。在此过程进行时,不应允许用户与桌面交互。

Application.MainFormOnTaskbar := True;
Application.ShowMainForm := False;
...
FormChild.ShowModal;
4

4 回答 4

12

将主窗体设为模态是没有意义的。实际上,如果您有一个带有(普通)主窗体的普通应用程序,然后显示一个模态窗体(例如对话框或TOpenDialog),那么“模态”意味着主窗体和应用程序的其余部分,变为“禁用”,直到模态表单关闭。(但其他应用程序根本不受此影响。)但这对主窗体没有意义,因为当显示主窗体时,您的应用程序没有“休息”可以禁用。事实上,一个普通的主窗体在某种意义上已经是模态的,如果你不打开任何其他窗体的话。

我认为您希望创建一个系统模式表单,即在显示时禁用桌面其余部分的表单。但这并不容易做到,因为现代版本的 Microsoft Windows 操作系统的安全原则。事实上,单个应用程序(通常)不应该像这样控制整个操作系统。

于 2011-02-17T12:38:06.693 回答
1

正如其他答案提到的那样,您想要做的事情很难理解,因为模态表单的目的是禁用下面的所有申请表,所以基本上申请表可能被认为是模态表单本身。

虽然如果您希望让您的应用程序成为当前 Windows 桌面(可能是非管理用户桌面)的唯一焦点,您需要:

  1. 通过使表单全屏隐藏任务栏
  2. 考虑到应用程序的可访问性,尽可能多地锁定 Windows 键(Ctrl、Alt、F1-F12、Windows、菜单)

使用新版本的窗口,您可以作为非特权用户执行所有这些操作,但使用全局窗口挂钩的 Ctrl+Alt+Del 组合除外。

uses
  Windows;

var
  hKeybaordHook: HHOOK = 0;

function KeyboardHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): HRESULT; stdcall;
type
  PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;
  TKBDLLHOOKSTRUCT = packed record
    vkCode: DWORD;
    scanCode: DWORD;
    flags: DWORD;
    time: DWORD;
    dwExtraInfo: DWORD;
  end;
const
  LLKHF_ALTDOWN = $20;
var
  pkbhs: PKBDLLHOOKSTRUCT;
begin
  pkbhs := PKBDLLHOOKSTRUCT(lParam);
  if nCode = HC_ACTION then
  begin
    Result := 1;
// CTRL
    if WordBool(GetAsyncKeyState(VK_CONTROL) and $8000) then Exit
// ALT
    else if LongBool(pkbhs^.flags and LLKHF_ALTDOWN) then Exit
// WIN KEYS
    else if (pkbhs^.vkCode = VK_LWIN) or (pkbhs^.vkCode = VK_RWIN) then Exit
// FUNCTION KEYS
    else if bDisableFunctionKeys and (pkbhs^.vkCode >= VK_F1) and (pkbhs^.vkCode <= VK_F24) then Exit;
{
// Disabling specific combinations
// CTRL+ESC
    else if (pkbhs^.vkCode = VK_ESCAPE) and WordBool(GetAsyncKeyState(VK_CONTROL) and $8000) then Exit
// ALT+TAB
    else if (pkbhs^.vkCode = VK_TAB) and LongBool(pkbhs^.flags and LLKHF_ALTDOWN) then Exit
// ALT+ESC
    else if (pkbhs^.vkCode = VK_ESCAPE) and LongBool(pkbhs^.flags and LLKHF_ALTDOWN) then Exit
}
  end;
  Result := CallNextHookEx(hKeybaordHook, nCode, wParam, lParam);
end;

procedure MainForm.FormShow(Sender: TObject);
const
  WH_KEYBOARD_LL = 13;
begin
  SetBounds(0, 0, Screen.Width, Screen.Height);

  if hKeybaordHook = 0 then
    hKeybaordHook := SetWindowsHookEx(WH_KEYBOARD_LL, @KeyboardHook, HInstance, 0);
end;

procedure MainForm.FormHide(Sender: TObject);
begin
  if (hKeybaordHook <> 0) and UnhookWindowsHookEx(hKeybaordHook) then
    hKeybaordHook := 0;
end;

您还可以将“SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe”注册表项值设置为一些虚拟文本,以禁用任务管理器(包括 Ctrl+Shift+Esc 组合)。

于 2011-02-17T13:02:37.377 回答
1

使用创建您自己的桌面CreateDesktop()(并创建一个状态窗口以在其上显示),然后用于检索用户的桌面,然后在文件传输开始和结束时OpenDesktop()在它们之间切换。SwitchDesktop()当您的自定义桌面处于活动状态时,用户无法访问他/她的桌面(例如,屏幕保护程序正是这样做的)。

于 2011-02-17T22:23:46.887 回答
-1

如果你想接管用户的桌面并阻止他们使用他们的计算机,你可以使用dWinLock

于 2011-02-17T14:58:37.030 回答