More ... | 編集履歴:差分2011/07/02 09:50:52 JST以来のツールバーにドロップダウンメニュー表示の変更箇所
ツールバーにドロップダウンメニュー表示 - [[$$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 を受け取ります。 |