Правильная обработка модального окна «Минимизировать» поведение - PullRequest
6 голосов
/ 10 июня 2011

У меня следующая проблема: мы создаем довольно большое приложение (win32, Delphi 6 Enterprise). В некоторых частях приложения используются модальные окна, обычно содержащие детали выбора главного окна.

Мы включили модификацию обработки сообщений WM_SYSCOMMAND, чтобы, если окно было модальным, то сообщение SW_SHOWMINNOACTIVE было отправлено в главное окно приложения. Это приводит к минимизации всего приложения, а не только модальной формы.

Однако в конкретном случае возникает проблема: если окно вызова установлено в полноэкранный режим, то после восстановления модальное окно появится ПОД (отключенным) развернутым главным окном (это, кажется, происходит в Windows 7)

Моя проблема в два раза:

Во-первых, мне кажется, что при восстановлении приложения я не получаю никакого сообщения syscommand, поэтому я не могу ввести код для восстановления Z-порядка, потому что я не знаю, где его разместить. Во-вторых, мне кажется, что, если все приложение свернуто, нажатие на кнопку приложения на панели задач должно восстановить его в том же состоянии, а не с модальным окном под ним. Есть ли способ это исправить?

Редактировать: мы провели дополнительное тестирование, и, похоже, мы действительно можем обнаружить проблему в обработчике WM_ACTIVATE для основной формы. Мы также можем определить модальное окно на этом этапе. Однако я не могу найти способ восстановить его до вершины Z-порядка.

Edit2: вот код, который минимизирует приложение, когда модальная форма свернута:

procedure TfmGITForm.WMSysCommand(var Message: TWMSysCommand);
begin
  if (fsModal in FormState) or
      not Application.MainForm.Visible then
  begin
    case Message.CmdType of
      SC_MINIMIZE:
      begin
        ShowWindow(Application.Handle, SW_SHOWMINNOACTIVE);
      end;
      SC_RESTORE:
      begin
        ShowWindow(Application.Handle, SW_SHOWNORMAL);
        inherited;
      end;
    else
      inherited;
    end;    // case
  end
  else
    inherited;
end;

Все наши формы происходят от этого.

Ответы [ 2 ]

3 голосов
/ 10 июня 2011

Переопределите функцию CreateParams диалогового окна и установите Params.WndParent в полноэкранное окно (или Owner.Handle, если вы владеете вещами должным образом).По умолчанию Application.Handle, что приведет к возникновению подобных проблем.Свойства PopupParent, представленные в более поздних выпусках Delphi, делают то же самое.

1 голос
/ 10 июня 2011

Это связано с оконным ореолом Windows, который появился в (я думаю) XP. У меня те же проблемы в приложении D5 на этих операционных системах. Питер Белоу предложил в то время следующую работу, и она все еще хорошо мне помогает:

procedure DisableProcessWindowsGhosting;
type
  TDisableProcessWindowsGhostingProc = procedure; stdcall;
const
  sUser32 = 'User32.dll';
var
  ModH: HMODULE;
  _DisableProcessWindowsGhosting: TDisableProcessWindowsGhostingProc;
begin
  ModH := GetModuleHandle(sUser32);
  if ModH <> 0 then begin
    @_DisableProcessWindowsGhosting := nil;
    @_DisableProcessWindowsGhosting := GetProcAddress(ModH,
        'DisableProcessWindowsGhosting');
    if Assigned(_DisableProcessWindowsGhosting) then begin
      _DisableProcessWindowsGhosting;
    end;
  end;
end;

Я называю это в начале обработчика OnCreate основной формы приложения.

...