如何制作系统模式窗口?

发布于 2024-10-18 03:40:05 字数 236 浏览 1 评论 0原文

是否可以将应用程序的主窗体设为系统模式?我的应用程序将从远程公司 PC 上通过 FTP 传输文件。在此过程进行期间,不应允许用户与桌面交互。

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

Is it possible to make the main form of an application system modal? My application will FTP a file from a remote company PC. Users should not be allowed to interact with the desktop while this process is in progress.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冷情 2024-10-25 03:40:06

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

If you want to take over the user's desktop and prevent them from using their computer, you could use dWinLock.

羞稚 2024-10-25 03:40:05

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

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

It doesn't make sense to make the main form modal. Indeed, if you have an ordinary application with a (normal) main form, and then displays a modal form (e.g. a dialog box, or a TOpenDialog), then the "modality" means that the main form, and the rest of your application, becomes "disabled" until the modal form is closed. (But other applications aren't affected at all by this.) But this doesn't make sense for the main form, because when the main form is shown, there is no "rest" of your application to disable. In fact, a normal main form is in a sense already modal, if you do not open any other forms.

I think that you wish to create a system modal form, that is, a form that disables the rest of the desktop when shown. But this isn't too easy to do, because of the security principles of modern versions of the Microsoft Windows operating system. Indeed, a single application isn't (normally) supposed to take control over the entire OS like this.

不及他 2024-10-25 03:40:05

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

Create your own desktop using CreateDesktop() (and create a status window to display on it), then use OpenDesktop() to retreive the user's desktop, then switch between them using SwitchDesktop() when the file transfer begins and ends. While your custom desktop is active, the user cannot access his/her desktop (the screensaver does exactly this, for instance).

罗罗贝儿 2024-10-25 03:40:05

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

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

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

使用新版本的 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 组合)。

As other answers mention that you want to do is difficult to comprehend as modal form's purpose is to disable all application forms below so basically application form might be considered a modal form itself.

Although if you wish to make your application the only receiver of focus on current windows desktop (possibly non-administrative user desktop), you need to:

  1. Hide the taskbar by making your form fullscreen
  2. Lock as many windows keys as you can afford considering accessibility of your application (Ctrl, Alt, F1-F12, Windows, Menu)

With new versions of windows you can do all of that as non-priviledged user, except Ctrl+Alt+Del combination using global window hooks.

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;

You can also set "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe" registry key value to some dummy text, to disable task manager (including Ctrl+Shift+Esc combination).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文