私はこれが非常に古いことを知っていますが、偶然出くわしただけで、答えを知っています.
ダイアログ ボックスを前面に表示してもメイン ウィンドウが表示されない、これまで見てきた (および作成した) アプリケーションでは、開発者はダイアログ ボックスの所有者を指定することを単に怠っています。
これは、ダイアログ ボックスやメッセージ ボックスなどのモーダル ウィンドウとモードレス ウィンドウの両方に適用されます。モードレス ポップアップの所有者を設定すると、ポップアップは常にその所有者の上に保持されます。
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]について次のように述べていることに注意してください。
子ウィンドウの親を変更するために、GWLP_HWNDPARENT インデックスを指定してSetWindowLongPtrを呼び出さないでください。代わりに、SetParent関数を使用してください。
上記の最後の 2 つのスニペットが間違っていることを暗示しているように見えるため、これはやや誤解を招く可能性があります。そうではありません。呼び出すSetParent
と、目的のポップアップが所有ウィンドウになるのではなく、親ウィンドウの子になります (そのビットを設定します)。WS_CHILD
上記のコードは、既存のポップアップを所有ウィンドウにする正しい方法です。