Как сделать системно-модальное окно? - PullRequest
3 голосов
/ 17 февраля 2011

Можно ли сделать основную форму приложения системной модальной ? Мое приложение будет FTP файл с удаленного ПК компании. Пользователям не должно быть разрешено взаимодействовать с рабочим столом во время этого процесса.

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

Ответы [ 4 ]

12 голосов
/ 17 февраля 2011

Не имеет смысла делать основную форму модальной. Действительно, если у вас есть обычное приложение с (нормальной) основной формой, а затем отображается модальная форма (например, диалоговое окно или TOpenDialog), то «модальность» означает, что основная форма, а остальные ваше приложение становится «отключенным», пока модальная форма не будет закрыта. (Но это никак не влияет на другие приложения.) Но это не имеет смысла для основной формы, потому что, когда отображается основная форма, не остается «остатка» вашего приложения для отключения. На самом деле нормальная основная форма в каком-то смысле уже модальна, если вы не открываете другие формы.

Я думаю, что вы хотите создать модальную системную форму , то есть форму, которая отключает остальную часть рабочего стола при отображении. Но это не так просто сделать из-за принципов безопасности современных версий операционной системы Microsoft Windows. Действительно, ни одно приложение (как правило) не должно взять под контроль всю ОС, как это.

1 голос
/ 18 февраля 2011

Создайте свой собственный рабочий стол, используя CreateDesktop() (и создайте окно состояния для отображения на нем), затем используйте OpenDesktop(), чтобы восстановить рабочий стол пользователя, затем переключайтесь между ними, используя SwitchDesktop(), когда передача файлов начинается и заканчивается.Пока ваш пользовательский рабочий стол активен, пользователь не может получить доступ к своему рабочему столу (например, экранная заставка делает это).

1 голос
/ 17 февраля 2011

Поскольку в других ответах упоминается, что вы хотите сделать, это трудно понять, так как цель модальной формы - отключить все формы ниже, поэтому в основном форму заявки можно считать самой модальной формой.

Хотя, если вы хотите сделать свое приложение единственным получателем фокуса на текущем рабочем столе Windows (возможно, не администраторском рабочем столе пользователя), вам необходимо:

  1. Скройте панель задач, сделав форму полноэкранной
  2. Блокируйте столько оконных клавиш, сколько вы можете себе позволить, учитывая доступность вашего приложения (Ctrl, Alt, F1-F12, Windows, Menu)

В новых версиях 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;

Вы также можете установить значение ключа реестра «ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ \ Microsoft \ Windows NT \ CurrentVersion \ Опции выполнения файла образа \ taskmgr.exe» для некоторого фиктивного текста, чтобы отключить диспетчер задач (включая комбинацию Ctrl + Shift + Esc).

0 голосов
/ 17 февраля 2011

Если вы хотите захватить рабочий стол пользователя и запретить ему использовать его компьютер, вы можете использовать dWinLock .

...