麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Java > 正文

Toolbar制作菜單條過程詳解

2020-01-31 16:52:27
字體:
來源:轉載
供稿:網友
文章來源:互聯網 作者:ggg82/CSDN

  現在許多用戶界面都使用工具欄制作菜單條,小弟最近對此感興趣,便從網上求助,可是得到的幫助大多是BCGControlBar的源代碼或者是SizableRebar的源代碼,對于只希望是自己的界面具有該功能的朋友來說,這也許是不錯的選擇,只要看一下demo,然后直接調用別人的類庫就可以了,但對于我等對此話題感興趣,希望弄懂其來龍去脈的讀者來說,直接看這些沒有詳細解釋的源代碼,要從中弄出個所以然來,實不是件容易的是,至少對于像我這樣的菜鳥來說是這樣的,本文出于此種原因,希望對還在尋求此幫助的讀者能提供一些幫助。

   下面我們邊看邊侃:

  在接收到toolbarbutton按下消息時,我們一般使用TrackPopupMenuEx彈出菜單,問題的關鍵是,在菜單未關閉時,TrackPopupMenuEx并不返回,并攔截鼠標和鍵盤消息,使用spy可以看到,此時的工具欄收不到任何消息,當然無從改變熱點,這就需要我們自己探測鼠標位置并在鼠標移動到下一個熱點時關閉上一個菜單并顯示下一個菜單。這里我們使用鉤子函數SetWindowsHookEx在調用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);

}

 ?。ń涷炁c建議:如果button使用樣式TBSTYLE_DROPDOWN,請不要在消息TBN_DROPDOWN中直接調用該函數,應使用中間消息,然后使用PostMessa個發送該消息,以使TBN_DROPDOWN可以直接返回,否則消除第一個高亮熱點是很麻煩的事。)

  iPopup為當前彈出項,iNextPop為下一個彈出項,這些變量需要在函數HookMessageProc中處理,示例代碼如下:



void HookMessageProc(MSG * pMsg)
{
if (pMsg->message == WM_MOUSEMOVE)
{
int iButton, iCount;
POINT pt = { LOWORD(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);
}
else
{
iNextPop = -1;
}
}
}
 ?。ń涷炁c建議:不要試圖在此處調用TrackPopup,我曾試圖取消該函數內的while循環,直接在此調用該函數,結果是在TrackPopupMenuEx未返回之前,該函數已被調用)

  這里,僅僅處理了鼠標移動消息,真正的菜單還應處理鍵盤導航消息,詳細的代碼可以參考
BCGControlBar(http://www.vckbase.com/code/downcode.asp?id=1382)
或SizableRebar(http://www.codeproject.com/docking/sizablerebar/SizableRebar_demo.zip


  有了這底層框架,這些處理過程應該不再困難,文章所涉及到的一些API函數可以參考msdn。
Msdn上相關資料:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/faq/iemenubar.asp
http://www.microsoft.com/msj/0199/c/c0199.aspx
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 欧美成人精品一级 | 欧洲精品久久久 | 一区二区精品视频在线观看 | 91九色视频在线观看 | 午夜精品福利视频 | 黄色成人短视频 | 久久草在线观看视频 | 毛片av网| 九九热播视频 | 黄色小视频免费在线观看 | 久久恋| 欧美成人精品h版在线观看 国产一级淫片在线观看 | 日本中文字幕高清 | 色妇视频 | 日韩电影av在线 | 成年免费大片黄在线观看岛国 | 91精品国产刺激国语对白 | 日韩毛片免费观看 | 九九热在线视频观看这里只有精品 | 成人国产综合 | 免费观看一区二区三区视频 | 99精品无人区乱码在线观看 | 久久久成人精品视频 | 国产一级淫片免费看 | 91精品国产网站 | 欧产日产国产精品99 | 国产一区二区精品在线观看 | 欧美视频国产 | 国产精品久久久不卡 | 手机国产乱子伦精品视频 | 成人一区二区三区在线 | 在线播放视频一区二区 | 国产亚洲精品久久久久久网站 | 日本最新免费二区三区 | 99精品国产视频 | av免费提供| 亚洲成人精品久久 | 美女黄色影院 | 日本高清在线播放 | 国产人成精品一区二区三 | 欧美黑人伦理 |