如何制作系统模式窗口?

时间:2011-02-17 12:32:06

标签: delphi modal-dialog kiosk

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

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

4 个答案:

答案 0 :(得分:12)

制作主窗体模态是没有意义的。实际上,如果你有一个普通的应用程序使用(普通)主窗体,然后显示一个模态窗体(例如一个对话框,或一个TOpenDialog),那么“模态”意味着主窗体,以及您的应用程序的其余部分将被“禁用”,直到模式窗体关闭。 (但是其他应用程序根本不受影响。)但这对主窗体没有意义,因为当显示主窗体时,应用程序没有“休息”禁用。事实上,如果你不打开任何其他形式,正常的主要形式在某种意义上就是模态的。

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

答案 1 :(得分:1)

正如其他答案所提及的那样,您很难理解,因为模态形式的目的是禁用下面的所有申请表格,因此申请表格本身可能被视为模式表格。

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

  1. 通过使表单全屏隐藏任务栏
  2. 考虑到应用程序的可访问性(Ctrl,Alt,F1-F12,Windows,菜单),锁定尽可能多的Windows键
  3. 对于新版本的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组合)。

答案 2 :(得分:1)

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

答案 3 :(得分:-1)

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