[追加された編集:非常に退屈で、Win32、ダイアログボックスなどとは何の関係もないことが判明しました。エグゼクティブサマリー:通知エリアにアイコンを作成し、メインウィンドウを表示せず、「約」ボックスを持っているシンプルなWin32アプリケーションがあります。通知領域アイコンを右クリックして表示することができます。なぜなら、「約」ボックスが表示されて閉じられると、アプリケーションのメインメッセージループは終了メッセージを受け取って終了します。私はこれを引き起こすことが間違って行っている?)ダイアログボックスが閉じられるとすぐにWin32アプリケーションが終了する
を私は通知領域(「システムトレイ」)に座っていると、バックグラウンドでの処理の様々な関連はない - ここにビットを行う小さなプログラムを書いています。そのUIはほとんどありません。通知領域アイコンを右クリックするとメニューが表示され、「Exit」と「About」のオプションがあります。前者は終了し、後者はこのプログラムのモーダルダイアログを少しポップアップさせます。
アプリケーションはC++で書かれており、Win32を直接使用します(MFCなどはありません)。私は石の時代に立ち往生して謝っています。
唯一の問題は次のとおりです。「バージョン情報」ダイアログが閉じると、プログラムが終了します。これは何が原因でしょうか?
これを理解する上で、どのような詳細情報が最も有用かはわかりません。ここにいくつかの観察があります。
- ダイアログの[OK]ボタンをクリックした後、アプリケーションの終了時にWindowsメッセージが表示される順序は次のとおりです。
- ダイアログボックスのprocはWM_CTLCOLORBTNを取得します
- アプリケーションの(目に見えない)メインウィンドウはWM_ENABLE(TRUE)を取得します。
- ダイアログボックスは、WM_CTLCOLORBTN、WM_IMESETCONTEXT、WM_SETFOCUS、WM_WINDOWPOSCHANGING、WM_WINDOWPOSCHANGED、3xWM_GETICON、WM_NCACTIVATE、2xWM_GETICON、WM_ACTIVATE、WM_WINDOWPOSCHANGINGを取得します。
- アプリケーションウィンドウは、WM_WINDOWPOSCHANGING、WM_NCACTIVATE、メッセージ0x93,0x93,0x91,0x92,0x92(これらは何ですか?)、WM_ACTIVATEです。
- ダイアログボックスは、WM_KILLFOCUS、WM_IME_SETCONTEXTを取得します。
- アプリケーションのウィンドウはWM_IME_SETCONTEXTを取得します。
- ダイアログボックスはWM_IME_NOTIFYを取得します。アプリケーションのメインウィンドウも同様です。
- アプリケーションのウィンドウにWM_SETFOCUSが表示されます。
- ダイアログボックスにメッセージ0x90、WM_DESTROY、WM_NCDESTROYが表示されます。
- これらの後のメッセージは、ダイアログウィンドウのprocまたはメインアプリケーションウィンドウのいずれにも表示されません。
- その後、GetMessageはメインメッセージループ(メッセージはWM_QUIT)で0を返し、それはすべて終了します。
- 私のコードでPostQuitMessageを呼び出すのは、メインウィンドウのWndProcにある唯一の呼び出しです。メインウィンドウがWM_DESTROYになったときに発生し、このシナリオでは実際には呼び出されません。
はおそらく、私のコードでクレイジーなもの、または不足している何か、があります。ここにいくつかの抜粋があります(いくつかの詳細は関連性がないかもしれませんが、簡潔に省略されています)。
次のように私のWinMainの大まかな構造は次のとおりです。
WNDCLASSEX wc;
// fill in fields of wc
RegisterClassEx(&wc);
HWND w = CreateWindow(...);
NOTIFYICONDATA nid;
memset(&nid, 0, sizeof(nid));
// fill in fields of nid
Shell_NotifyIcon(NIM_ADD, &nid);
// (start a background thread to do the real work,
// which is of no interest here)
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
if (TranslateAccelerator(msg,hwnd, accel, &msg)) continue;
TranslateMesage(&msg);
DispatchMessage(&msg);
}
Shell_NotifyIcon(NUM_DELETE, &nid);
return (int)msg.wParam;
メインウィンドウのWndProcメソッドは次のようになります。
switch (message) {
case WM_USER_SHELLICON: // my own, attached to the icon's menu
if (LOWORD(lParam) == WM_RBUTTONDOWN) // ... create menu and return TRUE
break;
case WM_COMMAND:
// menu item
switch (LOWORD(wParam)) {
case IDM_ABOUT:
DialogBox(the_instance, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutProc);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default: return DefWindowProc(hWnd, message, wParam, lParam);
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default: return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
と、ダイアログボックスのProcは次のようになります。
switch (message) {
case WM_INITDIALOG:
// fill in a version string
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam)==IDOK || LOWORD(wParam)==IDCANCEL) {
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
よろしいですか。なんてひどい。ありがとう! –