Почему щелчок дочернего окна не всегда выводит приложение на передний план? - PullRequest
5 голосов
/ 09 сентября 2008

Когда приложение находится за другим приложением и Я нажимаю на значок панели задач моего приложения, и я ожидаю, что все приложение перейти к вершине z-порядка, даже если приложение модальное, диалоговое окно WS_POPUP открыт.

Однако, в некоторых случаях, для некоторых из моих (и других) диалоговых окон, только диалоговое окно выходит вперед; остальная часть приложения остается позади.

Я посмотрел на Spy ++ и те, которые работают правильно, я вижу WM_WINDOWPOSCHANGING отправляется родителю диалога. Для тех, которые оставьте остальную часть приложения, WM_WINDOWPOSCHANGING не отправлено родителю диалога.

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

Короче говоря, оба окна WS_POPUPWINDOW, созданные с помощью DialogBoxParam (), передав идентичные HWND в качестве третьего аргумента.

Кто-нибудь еще заметил эту странную странную причину в программах Windows? Какие сообщения посылает TaskBar в приложение, когда я нажимаю на его кнопку? Кто несет ответственность за то, чтобы все окон приложения выходили на первый план?

В моем случае базовое происхождение - это кадр MDI ... это как-то учитывается?

Ответы [ 3 ]

4 голосов
/ 22 ноября 2009

Я знаю, что это очень давно, но я наткнулся на это, и я знаю ответ.

В приложениях, которые вы видели (и писали), где перенос диалогового окна на передний план не выводил главное окно вместе с ним, разработчик просто пренебрег указанием владельца диалоговое окно.

Это относится как к модальным окнам, таким как диалоговые окна и окна сообщений, так и к немодальным окнам. Установка владельца немодального всплывающего окна также всегда сохраняет всплывающее окно над его владельцем.

В Win32 API функции для вызова диалогового окна или окна сообщения принимают окно владельца в качестве параметра:

INT_PTR DialogBox(
    HINSTANCE hInstance,
    LPCTSTR lpTemplate,
    HWND hWndParent,      /* this is the owner */
    DLGPROC lpDialogFunc
);

int MessageBox(
    HWND hWnd,            /* this is the owner */
    LPCTSTR lpText,
    LPCTSTR lpCaption,
    UINT uType
);

Аналогично, в .NET WinForms можно указать владельца:

public DialogResult ShowDialog(
    IWin32Window owner
)

public static DialogResult Show(
    IWin32Window owner,
    string text
) /* ...and other overloads that include this first parameter */

Кроме того, в WinForms можно легко установить владельца немодального окна:

public void Show(
    IWin32Window owner,
)

или, что эквивалентно:

form.Owner = this;
form.Show();

В прямом WinAPI-коде владелец немодального окна может быть установлен при создании окна:

HWND CreateWindow(
    LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle,
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent, /* this is the owner if dwStyle does not contain WS_CHILD */
    HMENU hMenu,
    HINSTANCE hInstance,
    LPVOID lpParam
);

или позже:

SetWindowLong(hWndPopup, GWL_HWNDPARENT, (LONG)hWndOwner);

или (64-битная совместимость)

SetWindowLongPtr(hWndPopup, GWLP_HWNDPARENT, (LONG_PTR)hWndOwner);

Обратите внимание, что MSDN говорит следующее о SetWindowLong [Ptr] :

Не вызывайте SetWindowLongPtr с индексом GWLP_HWNDPARENT, чтобы изменить родительский элемент дочернего окна. Вместо этого используйте функцию SetParent .

Это несколько вводит в заблуждение, так как, похоже, подразумевает, что последние два фрагмента выше неправильны. Это не так Вызов SetParent превратит намеченное всплывающее окно в child родительского окна (с установкой его WS_CHILD bit), вместо того, чтобы сделать его собственным. Приведенный выше код является правильным способом сделать существующее всплывающее окно собственным.

1 голос
/ 19 сентября 2008

При нажатии на значок на панели задач Windows отправит WM_ACTIVATE сообщение в ваше приложение.

Вы уверены, что ваш код передает сообщение WM_ACTIVATE в DefWindowProc оконную процедуру для обработки?

0 голосов
/ 09 сентября 2008

Правильно ли установлено родительское окно диалога?

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

Раймонд Чен, где ты!

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