- ベストアンサー
ポップアップメニューの作り方とは?
- NotifyIconでタスクバーに呼び出したアイコンの上で右クリックするとポップアップメニューが表示されるようにしたい。
- ポップアップメニューの作り方が分からず困っています。
- 環境はMicrosoft Visual C++ SDKを使用しています。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
★最後のアドバイス >アイコンの左上にメニューが正確に表示させるにはどうしたらいいのでしょうか。お願いします。例えを出しておきます。 ↑ 最初にタスクバーの位置が『下』に必ずあるとします。 この状態では『タスクトレイ』が右側にあるのでショートカット・メニューを出すときに 『TPM_RIGHTALIGN』と『TPM_BOTTOMALIGN』の定数をしています。 これで TrackPopupMenu() で指定した座標がメニューの右下となります。 サンプル: point.x = LOWORD( lParam ); point.y = LOWORD( lParam ); TrackPopupMenu( hSubMenu, (TPM_RIGHTALIGN | TPM_BOTTOMALIGN), point.x, point.y, 0, hWnd, NULL ); その他: ・タスクバーの位置が『上』『左』『右』にも対応するには次のようになります。 方法は (1)タスクバーの位置を取得 (2)タスクバーの位置から TrackPopupMenu() に渡す定数を分岐 これで出来ると思います。 なお、 上側…(TPM_RIGHTALIGN | TPM_TOPALIGN) 下側…(TPM_RIGHTALIGN | TPM_BOTTOMALIGN) ←下側:限定ならこれ 左側…(TPM_LEFTALIGN ~ TPM_BOTTOMALIGN) 右側…(TPM_RIGHTALIGN | TPM_BOTTOMALIGN) このようになります。 ・以上。
その他の回答 (4)
- Oh-Orange
- ベストアンサー率63% (854/1345)
★補足要求します。 >「MENUDATAが定義されていません。」と出るのですがどうしたらいいのでしょうか。お願いします。 ↑ 『MENUDATA』という記号定数が定義されていません。 >・環境 >Microsoft Visual C++ SDK ↑ コンパイラは無料版ですか? 有料版ならばリソース・エディタが付属しているためリソースを作成すると XXXXX.rc と resource.h というヘッダが自動的に作成されます。この『resource.h』にはリソースで 使用している記号定数(コントロールのIDやメニューのIDなど)が定義されます。 ・さてと skyforce さんはどのようにしてリソースを作っていますか? もし、フリーソフト等を使ってリソースを作成している場合は、そのソフトがメニューのIDを 記号定数で定義するのか、文字列で定義するのかを確認して下さい。そうしないと先に進みません。 ちなみに回答 No.2 の補足にあるリソースを見る限りでは記号定数でメニューIDを定義しています。 記号定数なら『resource.h』ヘッダなどのファイルに『#define MENUDATA (数)』と1行追加します。 (数)は重複しない整数値を指定します。自由です。 ・あと質問にある『hMenu = LoadMenu(hInst,"MENUDATA");』が正しい記述ならばリソースの記述が 間違っていることになります。この場合はリソースを次のように修正して下さい。 間違い⇒『MENUDATA MENU DISCARDABLE 』 正しい⇒『"MENUDATA" MENU DISCARDABLE 』 ・どちらが正しいのか判断して下さい。 判断の基準はメニューのIDを記号定数で指定するのか、文字列定数で指定するのかを先に決めます。 あなたはどのようにメニューIDを指定しているのですか? ハッキリして下さい。 ここをハッキリとしないと問題は一生解決しません。 ・それでは補足にどうぞ。あと回答 No.2 も読み直して下さい。
お礼
>間違っていることになります。この場合はリソースを次のように修正 >して下さい。 >間違い⇒『MENUDATA MENU DISCARDABLE 』 >正しい⇒『"MENUDATA" MENU DISCARDABLE 』 IDの指定されてた所がおかしかったみたいです。 リソースのID:["MENUDATA"]をID:[MENUDATA]にしたところうまくいきました。 ありがとうございます。 最後にタスクトレイのアイコンをクリックしたときに アイコンの左上にメニューが正確に表示させるにはどうしたらいいのでしょうか。お願いします。例えを出しておきます。 http://www.geocities.jp/wingcold2236/001.html
- Oh-Orange
- ベストアンサー率63% (854/1345)
★リソースを見ました。 ・やっぱり指定方法が間違っています。 それもリソースとソースの2つがそれぞれ違います。 次のようにして下さい。 ●ソースコード hMenu = LoadMenu( hInst, MAKEINTRESOURCE(MENUDATA) ); ※リソースで『MENUDATA』という記号定数を使っているので MAKEINTRESOURCE() マクロを使います。 ●リソース部分 MENUDATA MENU DISCARDABLE BEGIN POPUP "" BEGIN MENUITEM "終了", 65535 END END ※ショートカットメニューの場合は POPUP 内のBEGIN~ENDに記述します。 ●上記よりメニューの出し方をまとめると hMenu = LoadMenu( hInst, MAKEINTRESOURCE(MENUDATA) ); hSubMenu = GetSubMenu( hMenu, 0 ); point.x = LOWORD( lParam ); point.y = LOWORD( lParam ); TrackPopupMenu( hSubMenu, TPM_LEFTALIGN, point.x, point.y, 0, hWnd, NULL ); となります。 これでショートカットメニューが出ます。 今後、ショートカットメニューのリソースの記述に注意して下さい。
補足
返事が遅くなってしまい申し訳ございません。 「MENUDATAが定義されていません。」と出るのですがどうしたらいいのでしょうか。お願いします。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★1つ疑問が…。 >hMenu = LoadMenu(hInst,"MENUDATA"); ↑ この行の『MENUDATA』は文字列で良いのですか? 記号定数の『MENUDATA』だと文字列で指定するとメニューは表示されず、 文字列での『MENUDATA』だと記号定数で指定してもメニューは表示されません。 ここに注意。 ・以上。確認を。
補足
リソースファイルのMenuから呼び出すようにしたのですが・・・。 //リソース//Script1.rc // // Menu // MENUDATA MENU DISCARDABLE BEGIN MENUITEM "終了", 65535 END
- Oh-Orange
- ベストアンサー率63% (854/1345)
★お聞きしたい事が1つ。 ・Shell_NotifyIcon() 関数でタスクトレイにアイコンを登録するとき uCallbackMessage はちゃんと設定していますか? 通知するメッセージのIDコードですよ。 ・仮に uCallbackMessage=WM_TASKTRAY という定数をセットしていたとします。 この場合はウインドウ・プロシージャ関数で次のようにします。 サンプル: LRESULT CALLBACK WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch ( uMsg ){ case WM_TASKTRAY: // ユーザ定義のメッセージ処理 if ( wParam == ID_TRAYICON ){ // アイコンの識別コード switch ( lParam ){ case WM_RBUTTONDOWN: /* ここにショートカット・メニューを出す処理 */ break; } } break; default:return DefWindowProc( hWnd, uMsg, wParam, lParam ); } return 0; } 以上。
補足
回答ありがとうございます。 nid.uCallbackMessageは nid.uCallbackMessage = MYTRAY_MESSAGE; とつけております。 switch (msg) { case MYTRAY_MESSAGE: if(wParam == ID_MYTRAY){ switch(lParam){ case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: hMenu = LoadMenu(hInst,"MENUDATA"); hSubMenu = GetSubMenu(hMenu,0); point.x = LOWORD(lParam); point.y = LOWORD(lParam); TrackPopupMenu(hSubMenu,TPM_LEFTALIGN,point.x,point.y,0,hWnd,NULL); break; ///////////////以下省略////////////// というような感じです。
お礼
うまくいきました。 ありがとうございます。