Toolbar製作選單條過程詳解 (轉)
Toolbar製作選單條過程詳解
現在許多介面都使用工具欄製作選單條,小弟最近對此感興趣,便從網上求助,可是得到的幫助大多是BCGControlBar的或者是SizableRebar的原始碼,對於只希望是自己的介面具有該功能的朋友來說,這也許是不錯的選擇,只要看一下demo,然後直接別人的類庫就可以了,但對於我等對此話題感興趣,希望弄懂其來龍去脈的讀者來說,直接看這些沒有詳細解釋的原始碼,要從中弄出個所以然來,實不是件容易的是,至少對於像我這樣的菜鳥來說是這樣的,本文出於此種原因,希望對還在尋求此幫助的讀者能提供一些幫助。
下面我們邊看邊侃:
在接收到toolbarbutton按下訊息時,我們一般使用TrackPopupMenuEx彈出選單,問題的關鍵是,在選單未關閉時,TrackPopupMenuEx並不返回,並攔截滑鼠和鍵盤訊息,使用spy可以看到,此時的工具欄收不到任何訊息,當然無從改變熱點,這就需要我們自己探測滑鼠位置並在滑鼠移動到下一個熱點時關閉上一個選單並顯示下一個選單。這裡我們使用鉤子SetHookEx在呼叫TrackPupupMenuEx前WH_MSGFILTER鉤子,程式碼如下:
m_hMsgHook = SetWindowsHookEx( WH_MSGFILTER, MessageProc, 0, GetCurrentThreadId() );
MssageProc是鉤子函式,程式碼如下:
LRESULT CALLBACK MessageProc(int code, WPARAM wParam, LPARAM lParam)
{
if (code == MSGF_MENU)
{
HookMessageProc(lParam);
}
return CallNextHookEx(m_hMsgHook, code, wParam, lParam);
}
函式檢查訊息,如果是來自選單,則將訊息傳遞給函式HookMessageProc處理,我們所要做的就是在該函式中檢測訊息WM_MOUSEMOVE,並測試滑鼠位置,如果滑鼠已經移動到另一個按鈕上,則關閉選單並顯示下一個選單,關閉選單使用訊息WM_CANCELMODE,當選單關閉後,我們要釋放鉤子,在下一個選單彈出時重新安裝鉤子,彈出選單示例程式碼如下:
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; //下一個彈出項,若為負,則退出
}
SendMessage(hWndToolBar,TB_SETHOTITEM,-1,0);
}
(與建議:如果button使用樣式,請不要在訊息TBN_DROPDOWN中直接呼叫該函式,應使用中間訊息,然後使用PostMessa個傳送該訊息,以使TBN_DROPDOWN可以直接返回,否則消除第一個高亮熱點是很麻煩的事。)
iPopup為當前彈出項,iNextPop為下一個彈出項,這些變數需要在函式HookMessageProc中處理,示例程式碼如下:
void HookMessageProc(MSG * pMsg)
{
if (pMsg->message == WM_MOUSEMOVE)
{
int iButton, iCount;
POINT pt = { LO(pMsg->lParam), HIWORD(pMsg->lParam) };
ScreenToClient(hWndToolbar, &pt);
iButton = SendMessage(hWndToolbar, TB_HITTEST, 0, &pt);
iCount = SendMessage(hWndToolbar, TB_BUTTONCOUNT, 0, 0);
if (iPopup != iButton && iButton < iCount && iButton >= 0)
{
iNextPop = iButton;
SendMessage(hWndMain, WM_CANCELMODE, 0, 0);
(經驗與建議:不要試圖在此處呼叫TrackPopup,我曾試圖取消該函式內的while迴圈,直接在此呼叫該函式,結果是在TrackPopupMenuEx未返回之前,該函式已被呼叫)
}
else
{
iNextPop = -1;
}
}
}
這裡,僅僅處理了滑鼠移動訊息,真正的選單還應處理鍵盤導航訊息,詳細的程式碼可以參考
BCGControlBar(?id=1382)
或SizableRebar(
),
有了這底層,這些處理過程應該不再困難,文章所涉及到的一些函式可以參考msdn。
Msdn上相關資料:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-962729/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- BabyLinux製作過程詳解(轉)Linux
- CSS水平導航選單製作詳解CSS
- CSS 水平導航選單製作詳解CSS
- 二級下拉導航選單製作詳解
- 導航條選單的製作-邱奎-專題視訊課程
- Redis複製過程詳解Redis
- 自定義右鍵選單實現過程詳解
- Laravel + Vue 製作一款標籤選擇器(詳細過程)LaravelVue
- 轉:DNS解析過程詳解DNS
- 一條 sql 的執行過程詳解SQL
- LumaQQ安裝過程詳解(轉)
- MapReduce 過程詳解 (用WordCount作為例子)
- 用Delphi製作個性化的選單 (轉)
- 我把 Toolbar 轉了一下變成了選單
- [轉]:xmake編譯配置過程詳解編譯
- Nginx支援Socket轉發過程詳解Nginx
- [譯] 製作 Vue 3 的過程Vue
- 轉[Android]APK打包過程詳解(一)AndroidAPK
- 轉[Android]APK打包過程詳解(二)AndroidAPK
- MapReduce過程詳解
- Delphi製作帶圖示的彈出式選單 (轉)
- Axure 教程:製作摺疊選單
- html-製作導航選單HTML
- 無需表格製作CSS選單CSS
- 用CSS製作隱藏選單CSS
- javascript實現tab選項卡過程分解詳解JavaScript
- 遊戲製作詳解自----OpenGL入門教程(九)(轉)遊戲
- 遊戲製作詳解自----OpenGL入門教程(五)(轉)遊戲
- 遊戲製作詳解自----OpenGL入門教程(四)(轉)遊戲
- [轉]反向代理過程與Nginx特點詳解Nginx
- 製作可以自動隱藏的彈出式選單 (轉)
- 純css製作導航下拉選單CSS
- 如何用CSS製作橫向選單?CSS
- 奧巴馬籌款網站的製作過程網站
- C/C++ Qt ToolBar 選單元件應用C++QT元件
- QQ黑市揭密:被盜到出售過程詳解(轉)
- PHP 協程實現過程詳解PHP
- Path實現常見toolbar點選彈出選單效果