[Top Page][All Pages][Recent Changes]

Edit History:View

Content of ツールバーにドロップダウンメニュー表示 at 2011/07/02 09:50:52 JST

View diff from current version

Return to the edit history

  ツールバーにドロップダウンメニュー表示
  
  
  [[$$toc]]
  - →[[HSP3・サンプルスクリプト]]に戻る
  
  ----
  
  HSP3.0で動作確認
  
  * スクリプト
  
  {{{
  ; <<<< HSP 3.0 サンプル >>>>
  ;
  ;   ツールバーボタンにドロップダウンメニューを表示
  ;
  
      #uselib "comctl32.dll"
      #func InitCommonControls "InitCommonControls"
  
      #uselib "user32.dll"
      #func CreatePopupMenu  "CreatePopupMenu"
      #func TrackPopupMenuEx "TrackPopupMenuEx" int,int,int,int,int,int
      #func AppendMenu       "AppendMenuA"      int,int,int,sptr
      #func DestroyMenu      "DestroyMenu"      int
      #func ClientToScreen   "ClientToScreen"   int,int
  
      #define WM_COMMAND          0x0111
      #define WM_NOTIFY           0x004E
  
      #define TBN_DROPDOWN        -710
  
      #define TB_BUTTONSTRUCTSIZE 0x041E
      #define TB_ADDBITMAP        0x0413
      #define TB_AUTOSIZE         0x0421
      #define TB_ADDBUTTONS       0x0414
      #define TB_SETEXTENDEDSTYLE 0x0454
      #define TB_GETRECT          0x0433
  
      #define TBSTYLE_EX_DRAWDDARROWS 1
  
      screen 0, 300, 200
      oncmd  gosub *OnCommand, WM_COMMAND
      oncmd  gosub *OnNotify,  WM_NOTIFY
      onexit gosub *OnClose
  
      ; ==== ツールバー ====
  
      ; コモンコントロールライブラリの初期化
      InitCommonControls
  
      ; ツールバー作成
      winobj "ToolbarWindow32","",0,$50000801,0,0
      hTool = objinfo_hwnd(stat)
  
      sendmsg hTool, TB_BUTTONSTRUCTSIZE, 20, 0
      sendmsg hTool, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS
  
      tbadd(0) = -1        ; HINST_COMMCTRL
      tbadd(1) = 0         ; IDB_STD_SMALL_COLOR
      sendmsg hTool, TB_ADDBITMAP, 0, varptr(tbadd)
  
      tbb( 0) =  6, 1, ($8<<8)|0x04, 0, 0  ;「新規作成」ボタン
      tbb( 5) =  7, 2, 0x04, 0, 0          ;「開く」ボタン
      tbb(10) =  8, 3, 0x04, 0, 0          ;「保存」ボタン
      tbb(15) =  0, 0, 1<<8, 0, 0          ;「セパレータ」ボタン
      tbb(20) =  0, 4, 0x04, 0, 0          ;「切り取り」ボタン
      tbb(25) =  1, 5, 0x04, 0, 0          ;「コピー」ボタン
      tbb(30) =  2, 6, 0x04, 0, 0          ;「貼り付け」ボタン
      tbb(35) =  0, 0, 1<<8, 0, 0          ;「セパレータ」ボタン
      tbb(40) =  3, 7, 0x04, 0, 0          ;「アンドゥ」ボタン
      tbb(45) = 12, 8, 0x04, 0, 0          ;「検索」ボタン
      sendmsg hTool, TB_ADDBUTTONS, 10, varptr(tbb)
  
      sendmsg hTool, TB_AUTOSIZE, 0, 0
  
      ; ドロップダウンボタン用のメニュー作成
      CreatePopupMenu : hmenu = stat
      AppendMenu hmenu,    0, 101, "新規1"
      AppendMenu hmenu,    0, 102, "新規2"
      AppendMenu hmenu, $800,   0, ""     ; 区切り線
      AppendMenu hmenu,    0, 104, "ファイルから..."
  
      stop
  
  *OnCommand
      itemId = wParam & $FFFF
      dialog "コマンドID:"+itemId
      return
  
  *OnNotify
      dupptr nmhdr, lParam, 12
      if (nmhdr(0) == hTool) & (nmhdr(2) == TBN_DROPDOWN) {
          gosub *OnToolDropDown
      }
      return
  
  *OnToolDropDown
      dupptr nmtoolbar, lParam, 44
      itemId = nmtoolbar(3)
      if itemId == 1 {
          dim rc, 4
          sendmsg hTool, TB_GETRECT, itemId, varptr(rc)
          pt = rc(0), rc(3)
          ClientToScreen hTool, varptr(pt)
          TrackPopupMenuEx hmenu, 0, pt(0), pt(1), hwnd, 0
      }
      return
  
  *OnClose
      if hmenu : DestroyMenu hmenu
      end
  }}}
  
  * 解説
  
  ツールバー(ドロップダウンメニュー無し)については次のリンクを参照。
  
  - http://chokuto.ifdef.jp/urawaza/toolbar1.html
  - http://chokuto.ifdef.jp/urawaza/toolbar2.html
  
  ショートカットメニューについては次のリンクを参照。
  
  - http://chokuto.ifdef.jp/urawaza/shortcutmenu.html
  
  ここでは、ツールバーボタンの横に付けられるアローボタン(ドロップダウンメニューを表示するボタン)について解説。
  
  まず、アローボタンつきのツールバーを作成するには、comctl.dllのバージョンが4.71以上でなければならないので、あしからず。
  
  アローボタン付きツールバーを作成するには、ツールバーが TBSTYLE_EX_DRAWDDARROWS 拡張スタイルを持っていなければいけないのですが、拡張スタイルの設定は TB_SETEXTENDEDSTYLE メッセージを使わなくてはいけません。一般的に使われるような CreateWindowEx 呼び出し時の拡張スタイルパラメータでの指定はできませんし、SetWindowLong 等で書き換えてもダメです。
  
  上のスクリプトの
  {{{
  sendmsg hTool, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS
  }}}
  となっている部分が拡張スタイル設定にあたります。
  
  ツールボタンにアローボタンを付けるには、ボタンを追加する際に、 TBBUTTON 構造体の fsStyle メンバに BTNS_DROPDOWN フラグ(8) を指定する必要があります。(BTNS_DROPDOWN は TBSTYLE_DROPDOWN と書かれていることもあります。)
  上のスクリプトでは、最初のボタンだけにアローボタンを付けるようにしています。
  {{{
  tbb( 0)  =  6, 1, ($8<<8)|0x04, 0, 0      ;「新規作成」ボタン
  }}}
  の「($8<<8)」の部分が、 BTNS_DROPDOWN スタイルの設定です。
  
  以上で、アローボタンつきのツールボタンが表示されます。次に、アローボタンが押されたときの処理について解説しましょう。
  
  このアローボタンが押されると、 WM_NOTIFY メッセージが送られてきます。このときの通知コードは TBN_DROPDOWN (-710) となっています。lParam パラメータは NMTOOLBAR 構造体のアドレスです。上のスクリプトでは、nmtoolbar という変数に割り当てています。HSP3では dupptr 命令が追加されて、任意アドレスを変数に割り当てることができるようになったので、便利です。
  {{{
  typedef struct tagNMTOOLBAR {
    NMHDR hdr;         // => nmtoolbar(0)〜nmtoolbar(2)
    int iItem;         // => nmtoolbar(3)
    TBBUTTON tbButton; // => nmtoolbar(4)〜nmtoolbar(8)
    int cchText;       // => nmtoolbar(9)
    LPTSTR pszText;    // => nmtoolbar(10)
    RECT rcButton;     // => nmtoolbar(11)〜nmtoolbar(14) (新しく追加されたメンバ)
  } NMTOOLBAR;
  }}}
  
  iItem メンバ(この場合は nmtoolbar(3))にアイテムIDが格納されているので、複数のアローボタンを表示させている場合には、これによってどのメニューを表示させるかを決定できます。
  
  アイテムIDが決定できたら、ドロップダウンメニューを表示させるわけですが、どこに表示させるかを決める必要がありますね。これには、まず、TB_GETRECT メッセージでボタンの領域を取得します。この領域はクライアント座標で表されたものなので、領域の左下の点の座標 (rc(0), rc(3)) を、ClientToScreen 関数を使ってスクリーン座標に変換しています。
  
  メニューを表示する座標が分かったら、あとは TrackPopupMenuEx でメニューを表示するだけです。メニューアイテムが選択されると WM_COMMAND を受け取ります。