Я знаю, что это очень давно, но я наткнулся на это, и я знаю ответ.
В приложениях, которые вы видели (и писали), где перенос диалогового окна на передний план не выводил главное окно вместе с ним, разработчик просто пренебрег указанием владельца диалоговое окно.
Это относится как к модальным окнам, таким как диалоговые окна и окна сообщений, так и к немодальным окнам. Установка владельца немодального всплывающего окна также всегда сохраняет всплывающее окно над его владельцем.
В 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), вместо того, чтобы сделать его собственным. Приведенный выше код является правильным способом сделать существующее всплывающее окно собственным.