現(xiàn)在許多用戶界面都使用工具欄制作菜單條,小弟最近對(duì)此感興趣,便從網(wǎng)上求助,可是得到的幫助大多是BCGControlBar的源代碼或者是SizableRebar的源代碼,對(duì)于只希望是自己的界面具有該功能的朋友來(lái)說(shuō),這也許是不錯(cuò)的選擇,只要看一下demo,然后直接調(diào)用別人的類庫(kù)就可以了,但對(duì)于我等對(duì)此話題感興趣,希望弄懂其來(lái)龍去脈的讀者來(lái)說(shuō),直接看這些沒(méi)有詳細(xì)解釋的源代碼,要從中弄出個(gè)所以然來(lái),實(shí)不是件容易的是,至少對(duì)于像我這樣的菜鳥(niǎo)來(lái)說(shuō)是這樣的,本文出于此種原因,希望對(duì)還在尋求此幫助的讀者能提供一些幫助。
下面我們邊看邊侃:
在接收到toolbarbutton按下消息時(shí),我們一般使用TrackPopupMenuEx彈出菜單,問(wèn)題的關(guān)鍵是,在菜單未關(guān)閉時(shí),TrackPopupMenuEx并不返回,并攔截鼠標(biāo)和鍵盤消息,使用spy可以看到,此時(shí)的工具欄收不到任何消息,當(dāng)然無(wú)從改變熱點(diǎn),這就需要我們自己探測(cè)鼠標(biāo)位置并在鼠標(biāo)移動(dòng)到下一個(gè)熱點(diǎn)時(shí)關(guān)閉上一個(gè)菜單并顯示下一個(gè)菜單。這里我們使用鉤子函數(shù)SetWindowsHookEx在調(diào)用TrackPupupMenuEx前安裝WH_MSGFILTER鉤子,代碼如下:
m_hMsgHook = SetWindowsHookEx( WH_MSGFILTER, MessageProc, 0, GetCurrentThreadId() );
MssageProc是鉤子函數(shù),代碼如下:
void TrackPopup(HWND hWndToolBar, int iButton)
{
while (iButton >= 0)
{
SendMessage(hWndToolBar,TB_SETHOTITEM,iButton,0);
iPopup = iButton;
//安裝鉤子
g_hMsgHook = SetWindowsHookEx(WH_MSGFILTER, MessageProc, 0, GetCurrentThreadId());
//彈出菜單
TrackPopupMenuEx(…);
//卸載鉤子
UnhookWindowsHookEx(g_hMsgHook);
iButton = iNextPop; //下一個(gè)彈出項(xiàng),若為負(fù),則退出
}
SendMessage(hWndToolBar,TB_SETHOTITEM,-1,0);
}
(經(jīng)驗(yàn)與建議:如果button使用樣式TBSTYLE_DROPDOWN,請(qǐng)不要在消息TBN_DROPDOWN中直接調(diào)用該函數(shù),應(yīng)使用中間消息,然后使用PostMessa個(gè)發(fā)送該消息,以使TBN_DROPDOWN可以直接返回,否則消除第一個(gè)高亮熱點(diǎn)是很麻煩的事。)
iPopup為當(dāng)前彈出項(xiàng),iNextPop為下一個(gè)彈出項(xiàng),這些變量需要在函數(shù)HookMessageProc中處理,示例代碼如下:
新聞熱點(diǎn)
疑難解答
圖片精選