私は、(モデルレス)ダイアログをCreateWindow
で作成されたウィンドウの子として埋め込む方法がなければならないことを知っています。私の場合、スクロール可能なコンテナウィンドウにそれらを埋め込みたいので、このコンテナウィンドウはメインウィンドウの子です(図参照)。モードレスダイアログを子ウィンドウとしてWindows APIに埋め込む
私が遭遇した最初の問題は、私はまだTABキーや他のダイアログの特定のナビゲーションを使用できるようにしたいということ、です。しかしどうですか?
私のメッセージループ:
while (GetMessage(&msg, NULL, 0, 0)) {
if (IsDialogMessage(msg.hwnd, &msg)) continue;
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
編集:テスト目的のために、私はループを修正:Using the TAB key to navigate in non-dialogs, redux
:それは正しい方法は、ここで見つけることができるようにする方法をwhile (GetMessage(&msg, NULL, 0, 0)) {
if (IsEmbeddedDialogWindow(msg.hwnd)) {
if (IsDialogMessage(msg.hwnd, &msg)) continue;
}
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
while (GetMessage(&msg, NULL, 0, 0)) {
if (IsScrollableContainerWindow(msg.hwnd)) {
if (IsDialogMessage(msg.hwnd, &msg)) continue;
}
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
さらに詳しい情報
このメッセージループでは、メッセージが処理されないかのようにいくつかのダイアログテキストを入力すると何も起こりません。 IsDialogMessage
が削除された場合、埋め込みダイアログの編集コントロールにテキストを入力できますが、ダイアログナビゲーションは意図したとおりに機能しません。もちろん、ダイアログの子コントロールにはWS_TABSTOP
スタイルが設定されています。
スクロール可能なコンテナはCreateWindowEx
スタイルで作成され、スタイルは WS_CHILD, WS_VISIBLE, WS_VSCROLL, WS_TABSTOP, WS_EX_CONTROLPARENT
であり、このコンテナの子としてダイアログが作成されます。
HWND hWndContainer = GroupBarPanelCreate(WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, WS_EX_CONTROLPARENT, hWndMain, 0, 0, 400, 400);
GROUPBAR_PANEL* GroupBarPanel = (GROUPBAR_PANEL*) GetWindowLongPtr(hWndContainer, 0);
// Test embedding dialogs
for (unsigned int i = 0; i < 10; i++) {
HWND hWndDlg = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWndContainer, About, 0);
GroupBarPanelInternalAddLast(GroupBarPanel, hWndChild, hWndDlg, nullptr);
}
マイGroupBarPanelInternalAddLast
キャプションや境界線を除去することによって、モードレスダイアログのスタイルを変更し、WS_CHILD
、WS_VISIBLE
とWS_TABSTOP
が設定されていることを確認(SetWindowLong(hWndDlg, GWL_STYLE, ...)
)。 (WS_EX_CONTROLPARENT
スタイルもテスト済み)SetParent(hWndDlg, hWndContainer)
モードレスダイアログの親を変更しました。
だから私はここで何をしないのですか?私が知っているように、コンテナウィンドウプロシージャや組み込み(テスト目的のサブクラス化された)ダイアログプロシージャは、ほとんど決してWM_SETFOCUS
またはWM_KILLFOCUS
メッセージを受け取ることはありませんが、それはなぜですか?
解決策:トップレベルウィンドウでIsDialogMessageを呼び出します。
while (GetMessage(&msg, NULL, 0, 0)) {
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
if (IsDialogMessage(hWndTopLevel, &msg)) {
continue;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
'IsDialogMessage'は、メッセージが対象とするウィンドウではなく、候補ダイアログの' HWND'を渡す必要があります。 –
これは、 'WS_EX_CONTROLPARENT'スタイルを持ち、他のダイアログの親であるウィンドウの' HWND'を与えなければなりません。 –
作成時に入力フォーカスを手動で設定する必要があります。そうしないと、キーボード操作が機能しません。私はこれが確実に動作するように作られているとは確信していません。なぜ、代わりに通常のウィンドウを作成していないのですか? – IInspectable