右クリックによるフローティングメニュー

Windowsのデスクトップやエクスプローラなどでマウスの右ボタンをクリックすると、ポップアップメニュー(フローティングメニュー)が出てきますね。今回は、自作プログラムでやってみます。単にメニューを作って右クリックされたら画面に出すだけ、なのですが2点ほど注意点があるようです。

メニュー作成

APIでメニューを作るには、CreateMenu()でメニューのハンドルを作成してAppendMenu()でメニューの項目を追加していきます。AppnedMenu()にメニューハンドルと項目の種類、WM_COMMAND時に送るIDと項目を指定すれば項目が追加されていくので、項目を順に並べてメニューを作っていきましょう。メニューを作ったらTrackPopupMenu()でポップアップできます。ただし、フローティングメニューではトップレベルにダミーのメニューを作りそこに表示するメニューを追加してトップレベルメニューを表示する、という形になるようです(フローティングメニュー自体を表示しようとしてもうまく行かない)。

  hMenu=CreateMenu(); /* トップレベルメニュー */
  hMenuP=CreateMenu(); /* フローティングメニュー */

  /* フローティングメニュー作成 */
  AppendMenu(hMenuP,MF_STRING,1,"Message");
  AppendMenu(hMenuP,MF_STRING,2,"Exit");

  /* フローティングメニューをメニューに登録 */
  AppendMenu(hMenu,MF_POPUP,(UINT)hMenuP,NULL);

これで「Message」と「Exit」という文字列を持つフローティングメニューhwMenuPとそのメニューを載せるhwMenuが出来ました。後は、マウスの右クリックでTrackPopupMenu()にメニューを表示する座標(通常はマウスのカーソル座標)を指定しポップアップさせれば良いのですが、この時に指定する座標は「スクリーン座標」なので注意が必要です。WM_RBUTTONDOWNlParamに入っているカーソル座標は「ウインドウ上の」座標なので、これをClientToScreen()でスクリーン座標に変換します。

  case WM_RBUTTONDOWN:

      /* スクリーン上のマウスカーソル座標取得 */
      pt.x=LOWORD(lParam);
      pt.y=HIWORD(lParam);
      ClientToScreen(hwnd,&pt);

      /* カーソル位置にメニューを出す */
      TrackPopupMenu(hMenuP,0,pt.x,pt.y,0,hwnd,NULL);

      return 0;

メニューが選択されると、AppendMenuで指定したIDとともにWM_COMMANDメッセージがウインドウにが送られてくるので処理します。

  case WM_COMMAND:

      switch (LOWORD(wParam)) {

          case 1: /* Messageメニュー */

              MessageBox(hwnd,"Test","Test",MB_OK);

              break;

          case 2: /* Exitメニュー */

              DestroyWindow(hwMain);

              break;

      }

      return 0;

プログラム

プログラムソース表示

実行後にウインドウ内で右クリックするとメニューが出てきます。


プログラミング資料庫 > Windowsプログラミング研究室