Сосредоточение правого окна - PullRequest
4 голосов
/ 16 декабря 2011

Сценарий таков, что у меня есть «основное приложение» и «вспомогательное приложение». «Вспомогательное приложение» всплывает на клавиатуре, делает все, а затем перефокусирует главное окно приложения. Проблема заключается в том, что если основное приложение открывает модальное диалоговое окно, когда помощник активен, а вспомогательный затем перефокусирует неправильное окно, модальное диалоговое окно скрывается и основное приложение выглядит «замороженным».

Какие-либо предложения стратегий для решения этой проблемы?

Ответы [ 2 ]

1 голос
/ 17 декабря 2011

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

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

var
  Wnd: HWND;     // handle to 'main app's main form
  mWnd: HWND;    // handle to possible modal form
  AppWnd: HWND;  // handle to hidden Application window
begin
  ..

  if not IsWindowEnabled(Wnd) then begin  // test if there's a modal form
    AppWnd := GetWindowLong(Wnd, GWL_HWNDPARENT); // TApplication window handle
    mWnd := GetLastActivePopup(AppWnd); // most recently active popup window

      // restore focus to mWnd     

  end else
    // restore focus to Wnd

(Конечно, не забудьте включить тесты для результата функций API.)

0 голосов
/ 16 декабря 2011

Попробуйте Application.Restore или Application.RestoreTopMosts. И когда это модальное диалоговое окно показывается вызовом WinAPI, тогда также попробуйте Application.Normalize(All)TopMosts перед.

Теперь этого может быть достаточно, но в моем собственном приложении, которое скрывает дескриптор приложения от панели задач, этого нет, и мне потребовалась следующая подпрограмма, которая является обработчиком события TApplicationEvents.OnActivate:

procedure TMainForm.AppEventsActivate(Sender: TObject);
var
  TopWindow: HWND;
begin
  TopWindow := GetLastActivePopup(Application.Handle);
  if (TopWindow <> 0) and (TopWindow <> Application.Handle) then
  begin
    BringToFront;
    SetForegroundWindow(TopWindow);
  end;
end;

Уточнение: код в Application.BringToFront почти такой же, но он не гарантирует также отображение основной формы в фоновом режиме. То есть Application.BringToFront может показывать только модальное диалоговое окно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...