SkinMenu.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. #include "StdAfx.h"
  2. #include "SkinMenu.h"
  3. //////////////////////////////////////////////////////////////////////////////////
  4. //常量定义
  5. //间隙变量
  6. #define SPACE_LEFT 8 //空隙大小
  7. #define SPACE_RIGHT 5 //空隙大小
  8. //大小变量
  9. #define MENU_BAR_CX 24 //标题高度
  10. #define MENU_ITEM_CY 24 //子项高度
  11. #define SEPARATOR_CY 3 //拆分高度
  12. #define MENU_BORDER 6 //菜单边宽
  13. //////////////////////////////////////////////////////////////////////////////////
  14. //菜单变量
  15. CMenuStringArray CSkinMenu::m_MenuItemString; //字符子项
  16. CMenuSeparatorArray CSkinMenu::m_MenuItemSeparator; //拆分子项
  17. HHOOK CSkinMenu::m_hMenuHook = NULL;
  18. WNDPROC OldWndProc = NULL;
  19. LRESULT lResult=0;
  20. //////////////////////////////////////////////////////////////////////////////////
  21. LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
  22. {
  23. switch(message)
  24. {
  25. case WM_CREATE:
  26. {
  27. DWORD dwStyle = ::GetWindowLong(hWnd ,GWL_STYLE);
  28. DWORD dwNewStyle = (dwStyle & ~WS_BORDER);
  29. ::SetWindowLong(hWnd ,GWL_STYLE ,dwNewStyle);
  30. DWORD dwExStyle = ::GetWindowLong(hWnd ,GWL_EXSTYLE);
  31. DWORD dwNewExStyle = (dwExStyle & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE));
  32. ::SetWindowLong(hWnd ,GWL_EXSTYLE, dwNewExStyle);
  33. break;
  34. }
  35. case WM_PRINT:
  36. {
  37. return CallWindowProc(OldWndProc,hWnd,WM_PRINTCLIENT,wParam,lParam);
  38. }
  39. case WM_ERASEBKGND:
  40. return TRUE;
  41. case WM_WINDOWPOSCHANGING:
  42. {
  43. LPWINDOWPOS lpPos = (LPWINDOWPOS)lParam;
  44. lpPos->cx -= MENU_BORDER;
  45. lpPos->cy -= MENU_BORDER;
  46. break;
  47. }
  48. }
  49. return CallWindowProc(OldWndProc,hWnd,message,wParam,lParam);
  50. }
  51. //////////////////////////////////////////////////////////////////////////
  52. //构造函数
  53. CSkinMenu::CSkinMenu()
  54. {
  55. m_pMenuBar = NULL;
  56. m_pMenuBack = NULL;
  57. m_pMenuHoven = NULL;
  58. m_pSeparator = NULL;
  59. m_pCheck = NULL;
  60. m_pArrow = NULL;
  61. m_colFrameNormal = RGB(112,123,136);
  62. m_nItemHeight = MENU_ITEM_CY;
  63. }
  64. //析构函数
  65. CSkinMenu::~CSkinMenu()
  66. {
  67. DestroyMenu();
  68. }
  69. //绘画函数
  70. VOID CSkinMenu::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  71. {
  72. //效验参数
  73. ASSERT(lpDrawItemStruct->CtlType==ODT_MENU);
  74. if (lpDrawItemStruct->CtlType!=ODT_MENU) return;
  75. //变量定义
  76. CRect rcItem=lpDrawItemStruct->rcItem;
  77. CDC * pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
  78. CSkinMenuItem * pSkinMenuItem=(CSkinMenuItem *)lpDrawItemStruct->itemData;
  79. CMemoryDC BufferDC(pDC,rcItem);
  80. //状态变量
  81. bool bChecked=((lpDrawItemStruct->itemState&ODS_CHECKED)!=0);
  82. bool bSelected=((lpDrawItemStruct->itemState&ODS_SELECTED)!=0);
  83. bool bGrayed=((lpDrawItemStruct->itemState&ODS_DISABLED)||(lpDrawItemStruct->itemState&ODS_GRAYED));
  84. //绘画背景
  85. COLORREF crMenuBar=RGB(255,255,255);
  86. COLORREF crBorder=RGB(213,233,242);
  87. COLORREF crNormalBack=RGB(255,255,255);
  88. //菜单左边
  89. if ( m_pMenuBar != NULL && m_pMenuBar->IsNull() == false )
  90. m_pMenuBar->Draw(&BufferDC,CRect(rcItem.left,rcItem.top,MENU_BAR_CX,rcItem.bottom));
  91. else
  92. BufferDC.FillSolidRect(rcItem.left,rcItem.top,MENU_BAR_CX,rcItem.Height(),crMenuBar);
  93. //菜单节点的背景
  94. if ( m_pMenuBack != NULL && m_pMenuBack->IsNull() == false )
  95. m_pMenuBack->Draw(&BufferDC,CRect(rcItem.left+MENU_BAR_CX,rcItem.top,rcItem.Width(),rcItem.bottom));
  96. else
  97. BufferDC.FillSolidRect(rcItem.left+MENU_BAR_CX,rcItem.top,rcItem.Width()-MENU_BAR_CX,rcItem.Height(),crNormalBack);
  98. //焦点边框
  99. if ((bSelected==true)&&(bGrayed==false)&&(pSkinMenuItem!=NULL)&&(pSkinMenuItem->m_MenuItemType!=MenuItemType_Separator))
  100. {
  101. if ( m_pMenuHoven != NULL && m_pMenuHoven->IsNull() == false )
  102. {
  103. CRect rcSelItem(rcItem);
  104. rcSelItem.left += 1;
  105. rcSelItem.top += 1;
  106. rcSelItem.bottom -= 1;
  107. m_pMenuHoven->Draw(&BufferDC,CRect(rcSelItem.left+1,rcSelItem.top+1,rcSelItem.Width()-1,rcSelItem.top+rcSelItem.Height()-1));
  108. }
  109. else
  110. BufferDC.FillSolidRect(rcItem.left+2,rcItem.top+2,rcItem.Width()-4,rcItem.Height()-4,crBorder);
  111. }
  112. //绘制箭头
  113. if ( pSkinMenuItem->m_hSubMenu != NULL )
  114. {
  115. if ( m_pArrow != NULL && m_pArrow->IsNull() == false )
  116. {
  117. CRect rcArrow(rcItem.right-5-m_pArrow->GetWidth(),rcItem.top+(rcItem.Height()-m_pArrow->GetHeight())/2,rcItem.right-5,rcItem.top+(rcItem.Height()+m_pArrow->GetHeight())/2);
  118. m_pArrow->DrawImage(&BufferDC,rcArrow.left,rcArrow.top);
  119. }
  120. }
  121. //选择标志
  122. if (bChecked)
  123. {
  124. if ( m_pCheck != NULL && m_pCheck->IsNull() == false )
  125. {
  126. CRect rcIcon(rcItem.left,rcItem.top,MENU_BAR_CX,rcItem.bottom);
  127. m_pCheck->DrawImage(&BufferDC,(rcIcon.Width()-m_pCheck->GetWidth())/2,rcIcon.top+(rcIcon.Height()-m_pCheck->GetHeight())/2);
  128. }
  129. }
  130. //其他菜单
  131. if (pSkinMenuItem==NULL)
  132. {
  133. //获取信息
  134. MENUITEMINFO MenuItemInfo;
  135. MenuItemInfo.cbSize=sizeof(MenuItemInfo);
  136. MenuItemInfo.fMask=MIIM_FTYPE|MIIM_BITMAP;
  137. GetMenuItemInfo(lpDrawItemStruct->itemID,&MenuItemInfo);
  138. return;
  139. }
  140. //界面菜单
  141. switch (pSkinMenuItem->m_MenuItemType)
  142. {
  143. case MenuItemType_String: //字符菜单
  144. {
  145. //变量定义
  146. CSkinMenuString * pSkinMenuString=(CSkinMenuString *)pSkinMenuItem;
  147. CRect rcIcon(rcItem.left,rcItem.top,MENU_BAR_CX,rcItem.bottom);
  148. if ( bSelected )
  149. {
  150. if ( pSkinMenuString->m_pImageH != NULL && pSkinMenuString->m_pImageH->IsNull() == false )
  151. pSkinMenuString->m_pImageH->DrawImage(&BufferDC,(rcIcon.Width()-pSkinMenuString->m_pImageH->GetWidth())/2,rcIcon.top+(rcIcon.Height()-pSkinMenuString->m_pImageH->GetHeight())/2);
  152. else if ( pSkinMenuString->m_pImageN != NULL && pSkinMenuString->m_pImageN->IsNull() == false )
  153. pSkinMenuString->m_pImageN->DrawImage(&BufferDC,(rcIcon.Width()-pSkinMenuString->m_pImageN->GetWidth())/2,rcIcon.top+(rcIcon.Height()-pSkinMenuString->m_pImageN->GetHeight())/2);
  154. }
  155. else
  156. {
  157. if ( pSkinMenuString->m_pImageN != NULL && pSkinMenuString->m_pImageN->IsNull() == false )
  158. pSkinMenuString->m_pImageN->DrawImage(&BufferDC,(rcIcon.Width()-pSkinMenuString->m_pImageN->GetWidth())/2,rcIcon.top+(rcIcon.Height()-pSkinMenuString->m_pImageN->GetHeight())/2);
  159. }
  160. //设置颜色
  161. BufferDC.SetBkMode(TRANSPARENT);
  162. BufferDC.SelectObject(GetCtrlFont());
  163. //设置颜色
  164. if (bGrayed==true) BufferDC.SetTextColor(m_colDisableText);
  165. else if (bSelected==true) BufferDC.SetTextColor(m_colSelectText);
  166. else BufferDC.SetTextColor(m_colNormalText);
  167. //绘画字符
  168. CRect rcString;
  169. rcString.top=rcItem.top;
  170. rcString.bottom=rcItem.bottom;
  171. rcString.right=rcItem.right-SPACE_RIGHT;
  172. rcString.left=rcItem.left+MENU_BAR_CX+SPACE_LEFT;
  173. BufferDC.DrawText(pSkinMenuString->m_strString,pSkinMenuString->m_strString.GetLength(),&rcString,DT_SINGLELINE|DT_VCENTER|DT_NOCLIP);
  174. break;
  175. }
  176. case MenuItemType_Separator: //拆分菜单
  177. {
  178. //绘画拆分
  179. if ( m_pSeparator != NULL && m_pSeparator->IsNull() == false )
  180. m_pSeparator->Draw(&BufferDC,CRect(rcItem.left+MENU_BAR_CX+SPACE_LEFT,rcItem.top+1,rcItem.right-SPACE_RIGHT,rcItem.Height()-2));
  181. else
  182. BufferDC.FillSolidRect(rcItem.left+MENU_BAR_CX+SPACE_LEFT,rcItem.top+1,rcItem.Width()-MENU_BAR_CX-SPACE_LEFT-SPACE_RIGHT,rcItem.Height()-2,m_crSeparator);
  183. //补齐分隔条处的边框颜色
  184. RenderEngine->DrawLine(BufferDC.GetSafeHdc(),CRect(rcItem.left,rcItem.top,rcItem.left+1,rcItem.top+rcItem.Height()+1),1,m_colFrameNormal);
  185. RenderEngine->DrawLine(BufferDC.GetSafeHdc(),CRect(rcItem.right-1,rcItem.top,rcItem.right,rcItem.top+rcItem.Height()+1),1,m_colFrameNormal);
  186. break;
  187. }
  188. }
  189. //绘制边框色
  190. int nSeparatorCount = GetSeparatorCount();
  191. CRect rcClient(0,0,rcItem.right,0);
  192. rcClient.bottom = rcItem.Height()*(GetMenuItemCount()-nSeparatorCount)+SEPARATOR_CY*nSeparatorCount;
  193. RenderEngine->DrawRect(BufferDC.GetSafeHdc(),rcClient,1,m_colFrameNormal);
  194. //绘画界面
  195. pDC->BitBlt(rcItem.left,rcItem.top,rcItem.Width(),rcItem.Height(),&BufferDC,rcItem.left,rcItem.top,SRCCOPY);
  196. //抠掉子节点区域,从而屏蔽系统绘制的倒三角
  197. if ( (pSkinMenuItem->m_hSubMenu != NULL) && (m_pArrow != NULL && m_pArrow->IsNull() == false))
  198. pDC->ExcludeClipRect(rcItem.left, rcItem.top, rcItem.right, rcItem.bottom);
  199. return;
  200. }
  201. //测量位置
  202. VOID CSkinMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
  203. {
  204. //效验参数
  205. ASSERT(lpMeasureItemStruct->CtlType==ODT_MENU);
  206. if (lpMeasureItemStruct->CtlType!=ODT_MENU) return;
  207. //获取数据
  208. CSkinMenuItem * pSkinMenuItem=(CSkinMenuItem *)lpMeasureItemStruct->itemData;
  209. if (pSkinMenuItem==NULL)
  210. {
  211. //获取信息
  212. MENUITEMINFO MenuItemInfo;
  213. MenuItemInfo.cbSize=sizeof(MenuItemInfo);
  214. MenuItemInfo.fMask=MIIM_FTYPE|MIIM_STRING;
  215. GetMenuItemInfo(lpMeasureItemStruct->itemID,&MenuItemInfo);
  216. return;
  217. }
  218. //界面菜单
  219. switch (pSkinMenuItem->m_MenuItemType)
  220. {
  221. case MenuItemType_String: //字符菜单
  222. {
  223. //变量定义
  224. CSkinMenuString * pSkinMenuString=(CSkinMenuString *)pSkinMenuItem;
  225. //设置 DC
  226. HDC hDC=GetDC(NULL);
  227. SelectObject(hDC,GetCtrlFont());
  228. //计算长度
  229. CSize SizeString;
  230. GetTextExtentPoint32(hDC,pSkinMenuString->m_strString,pSkinMenuString->m_strString.GetLength(),&SizeString);
  231. //计算位置
  232. lpMeasureItemStruct->itemHeight=m_nItemHeight;
  233. lpMeasureItemStruct->itemWidth=SizeString.cx+MENU_BAR_CX+SPACE_LEFT+SPACE_RIGHT;
  234. //释放资源
  235. ReleaseDC(NULL,hDC);
  236. break;
  237. }
  238. case MenuItemType_Separator: //拆分菜单
  239. {
  240. lpMeasureItemStruct->itemWidth=0;
  241. lpMeasureItemStruct->itemHeight=SEPARATOR_CY;
  242. break;
  243. }
  244. }
  245. return;
  246. }
  247. //创建菜单
  248. bool CSkinMenu::CreatePopupMenu()
  249. {
  250. m_hMenuHook = ::SetWindowsHookEx(WH_CALLWNDPROC,CSkinMenu::WindowsHook,GetModuleHandle(SKINUI_DLL_NAME),::GetCurrentThreadId());
  251. return CMenu::CreatePopupMenu()?true:false;
  252. }
  253. //销毁菜单
  254. BOOL CSkinMenu::DestroyMenu()
  255. {
  256. //销毁菜单
  257. BOOL bRes = CMenu::DestroyMenu();
  258. //释放子项
  259. for (INT_PTR i=0;i<m_MenuItemActive.GetCount();i++)
  260. {
  261. FreeMenuItem(m_MenuItemActive[i]);
  262. }
  263. m_MenuItemActive.RemoveAll();
  264. //释放子项
  265. for (INT_PTR i=0;i<m_MenuItemString.GetCount();i++)
  266. {
  267. RenderEngine->RemoveImage(m_MenuItemString.GetAt(i)->m_pImageN);
  268. RenderEngine->RemoveImage(m_MenuItemString.GetAt(i)->m_pImageH);
  269. SafeDelete(m_MenuItemString.GetAt(i));
  270. }
  271. m_MenuItemString.RemoveAll();
  272. //释放子项
  273. for (INT_PTR i=0;i<m_MenuItemSeparator.GetCount();i++)
  274. {
  275. SafeDelete(m_MenuItemSeparator.GetAt(i));
  276. }
  277. m_MenuItemSeparator.RemoveAll();
  278. //卸载钩子
  279. UnhookWindowsHookEx(m_hMenuHook);
  280. RenderEngine->RemoveImage(m_pMenuBar);
  281. RenderEngine->RemoveImage(m_pMenuBack);
  282. RenderEngine->RemoveImage(m_pMenuHoven);
  283. RenderEngine->RemoveImage(m_pSeparator);
  284. RenderEngine->RemoveImage(m_pCheck);
  285. RenderEngine->RemoveImage(m_pArrow);
  286. return bRes;
  287. }
  288. //弹出菜单
  289. bool CSkinMenu::TrackPopupMenu(CWnd * pWnd)
  290. {
  291. //获取光标
  292. CPoint MousePoint;
  293. GetCursorPos(&MousePoint);
  294. //弹出菜单
  295. CMenu::TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,MousePoint.x,MousePoint.y,pWnd);
  296. return true;
  297. }
  298. //弹出菜单
  299. bool CSkinMenu::TrackPopupMenu(INT nXPos, INT nYPos, CWnd * pWnd)
  300. {
  301. //弹出菜单
  302. CMenu::TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,nXPos,nYPos,pWnd,NULL)?true:false;
  303. return true;
  304. }
  305. //插入拆分
  306. bool CSkinMenu::AppendSeparator()
  307. {
  308. //获取子项
  309. CSkinMenuSeparator * pSkinMenuItem=(CSkinMenuSeparator *)AcitveMenuItem(MenuItemType_Separator);
  310. //插入菜单
  311. if (pSkinMenuItem!=NULL)
  312. {
  313. CMenu::AppendMenu(MF_OWNERDRAW,0,(LPCTSTR)(pSkinMenuItem));
  314. return true;
  315. }
  316. return false;
  317. }
  318. //插入字符
  319. bool CSkinMenu::AppendMenu(UINT nMenuID, LPCTSTR pszString, LPCTSTR lpszIconN, LPCTSTR lpszIconH, UINT nFlags)
  320. {
  321. //类型判断
  322. ASSERT((nFlags&MF_SEPARATOR)==0);
  323. if ((nFlags&MF_SEPARATOR)!=0) return false;
  324. //获取子项
  325. CSkinMenuString * pSkinMenuItem=(CSkinMenuString *)AcitveMenuItem(MenuItemType_String);
  326. //插入菜单
  327. if (pSkinMenuItem!=NULL)
  328. {
  329. RenderEngine->RemoveImage(pSkinMenuItem->m_pImageN);
  330. RenderEngine->RemoveImage(pSkinMenuItem->m_pImageH);
  331. pSkinMenuItem->m_pImageN = RenderEngine->GetImage(lpszIconN);
  332. pSkinMenuItem->m_pImageH = RenderEngine->GetImage(lpszIconH);
  333. pSkinMenuItem->m_strString=pszString;
  334. CMenu::AppendMenu(MF_OWNERDRAW|nFlags,nMenuID,(LPCTSTR)(pSkinMenuItem));
  335. return true;
  336. }
  337. return false;
  338. }
  339. //插入拆分
  340. bool CSkinMenu::InsertSeparator(UINT nPosition)
  341. {
  342. //获取子项
  343. CSkinMenuSeparator * pSkinMenuItem=(CSkinMenuSeparator *)AcitveMenuItem(MenuItemType_Separator);
  344. //插入菜单
  345. if (pSkinMenuItem!=NULL)
  346. {
  347. CMenu::InsertMenu(nPosition,MF_OWNERDRAW,0,(LPCTSTR)(pSkinMenuItem));
  348. return true;
  349. }
  350. return false;
  351. }
  352. //插入字符
  353. bool CSkinMenu::InsertMenu(UINT nMenuID, LPCTSTR pszString, UINT nPosition, LPCTSTR lpszIconN, LPCTSTR lpszIconH, UINT nFlags)
  354. {
  355. //类型判断
  356. ASSERT((nFlags&MF_SEPARATOR)==0);
  357. if ((nFlags&MF_SEPARATOR)!=0) return false;
  358. //获取子项
  359. CSkinMenuString * pSkinMenuItem=(CSkinMenuString *)AcitveMenuItem(MenuItemType_String);
  360. //插入菜单
  361. if (pSkinMenuItem!=NULL)
  362. {
  363. RenderEngine->RemoveImage(pSkinMenuItem->m_pImageN);
  364. RenderEngine->RemoveImage(pSkinMenuItem->m_pImageH);
  365. pSkinMenuItem->m_pImageN = RenderEngine->GetImage(lpszIconN);
  366. pSkinMenuItem->m_pImageH = RenderEngine->GetImage(lpszIconH);
  367. pSkinMenuItem->m_strString=pszString;
  368. pSkinMenuItem->m_hSubMenu = (HMENU)nMenuID;
  369. CMenu::InsertMenu(nPosition,MF_OWNERDRAW|nFlags,nMenuID,(LPCTSTR)(pSkinMenuItem));
  370. return true;
  371. }
  372. return false;
  373. }
  374. //删除菜单
  375. bool CSkinMenu::RemoveMenu(UINT nPosition, UINT nFlags)
  376. {
  377. return CMenu::RemoveMenu(nPosition,nFlags)?true:false;
  378. }
  379. //修改菜单
  380. bool CSkinMenu::ModifyMenu(UINT nMenuID, LPCTSTR pszString, UINT nPosition, LPCTSTR lpszIconN, LPCTSTR lpszIconH, UINT nFlags)
  381. {
  382. return 0;
  383. }
  384. //释放子项
  385. VOID CSkinMenu::FreeMenuItem(CSkinMenuItem * pSkinMenuItem)
  386. {
  387. //效验参数
  388. ASSERT(pSkinMenuItem!=NULL);
  389. if (pSkinMenuItem==NULL) return;
  390. //清理变量
  391. switch (pSkinMenuItem->m_MenuItemType)
  392. {
  393. case MenuItemType_String: //字符类型
  394. {
  395. //变量定义
  396. CSkinMenuString * pSkinMenuString=(CSkinMenuString *)pSkinMenuItem;
  397. //设置变量
  398. pSkinMenuString->m_strString.Empty();
  399. m_MenuItemString.Add(pSkinMenuString);
  400. break;
  401. }
  402. case MenuItemType_Separator: //拆分类型
  403. {
  404. //变量定义
  405. CSkinMenuSeparator * pSkinMenuSeparator=(CSkinMenuSeparator *)pSkinMenuItem;
  406. //设置变量
  407. m_MenuItemSeparator.Add(pSkinMenuSeparator);
  408. break;
  409. }
  410. }
  411. return;
  412. }
  413. //获取子项
  414. CSkinMenuItem * CSkinMenu::AcitveMenuItem(enMenuItemType MenuItemType)
  415. {
  416. //变量定义
  417. CSkinMenuItem * pSkinMenuItem=NULL;
  418. //创建子项
  419. switch (MenuItemType)
  420. {
  421. case MenuItemType_String: //字符类型
  422. {
  423. if (m_MenuItemString.GetCount()>0)
  424. {
  425. INT_PTR nItemCount=m_MenuItemString.GetCount();
  426. pSkinMenuItem=m_MenuItemString[nItemCount-1];
  427. m_MenuItemString.RemoveAt(nItemCount-1);
  428. }
  429. else
  430. {
  431. pSkinMenuItem=new CSkinMenuString;
  432. if (pSkinMenuItem==NULL) return NULL;
  433. }
  434. break;
  435. }
  436. case MenuItemType_Separator: //拆分类型
  437. {
  438. if (m_MenuItemSeparator.GetCount()>0)
  439. {
  440. INT_PTR nItemCount=m_MenuItemSeparator.GetCount();
  441. pSkinMenuItem=m_MenuItemSeparator[nItemCount-1];
  442. m_MenuItemSeparator.RemoveAt(nItemCount-1);
  443. }
  444. else
  445. {
  446. pSkinMenuItem=new CSkinMenuSeparator;
  447. if (pSkinMenuItem==NULL) return NULL;
  448. }
  449. break;
  450. }
  451. default:
  452. {
  453. ASSERT(FALSE);
  454. return NULL;
  455. }
  456. }
  457. //加入队列
  458. m_MenuItemActive.Add(pSkinMenuItem);
  459. return pSkinMenuItem;
  460. }
  461. LRESULT CALLBACK CSkinMenu::WindowsHook( int code,WPARAM wParam,LPARAM lParam )
  462. {
  463. PCWPSTRUCT lpCwp = (PCWPSTRUCT)lParam;
  464. while(code == HC_ACTION && lpCwp->message==WM_CREATE)
  465. {
  466. TCHAR sClassName[10];
  467. int Count =::GetClassName(lpCwp->hwnd,sClassName,CountArray(sClassName));
  468. //检查是否菜单窗口
  469. if( Count == 6 && _tcscmp(sClassName,TEXT("#32768"))==0)
  470. {
  471. WNDPROC lastWndProc = (WNDPROC)GetWindowLong(lpCwp->hwnd,GWL_WNDPROC);
  472. if(lastWndProc != WndProc)
  473. {
  474. #pragma warning(disable:4311)
  475. SetWindowLong(lpCwp->hwnd,GWL_WNDPROC, (LONG)WndProc);
  476. OldWndProc = lastWndProc;
  477. break;
  478. }
  479. }
  480. break;
  481. }
  482. return CallNextHookEx(m_hMenuHook,code,wParam,lParam);
  483. }
  484. BOOL CSkinMenu::SetMenuBarImage( LPCTSTR lpszFileName,CONST LPRECT lprcNinePart/*=NULL*/ )
  485. {
  486. RenderEngine->RemoveImage(m_pMenuBar);
  487. m_pMenuBar = RenderEngine->GetImage(lpszFileName);
  488. if (NULL == m_pMenuBar)
  489. return FALSE;
  490. else
  491. {
  492. m_pMenuBar->SetNinePart(lprcNinePart);
  493. return TRUE;
  494. }
  495. }
  496. BOOL CSkinMenu::SetMenuBackImage( LPCTSTR lpszFileName,CONST LPRECT lprcNinePart/*=NULL*/ )
  497. {
  498. RenderEngine->RemoveImage(m_pMenuBack);
  499. m_pMenuBack = RenderEngine->GetImage(lpszFileName);
  500. if (NULL == m_pMenuBack)
  501. return FALSE;
  502. else
  503. {
  504. m_pMenuBack->SetNinePart(lprcNinePart);
  505. return TRUE;
  506. }
  507. }
  508. BOOL CSkinMenu::SetMenuHovenImage( LPCTSTR lpszFileName,CONST LPRECT lprcNinePart/*=NULL*/ )
  509. {
  510. RenderEngine->RemoveImage(m_pMenuHoven);
  511. m_pMenuHoven = RenderEngine->GetImage(lpszFileName);
  512. if (NULL == m_pMenuHoven)
  513. return FALSE;
  514. else
  515. {
  516. m_pMenuHoven->SetNinePart(lprcNinePart);
  517. return TRUE;
  518. }
  519. }
  520. BOOL CSkinMenu::SetSeparatorImage( LPCTSTR lpszFileName,CONST LPRECT lprcNinePart/*=NULL*/ )
  521. {
  522. RenderEngine->RemoveImage(m_pSeparator);
  523. m_pSeparator = RenderEngine->GetImage(lpszFileName);
  524. if (NULL == m_pSeparator)
  525. return FALSE;
  526. else
  527. {
  528. m_pSeparator->SetNinePart(lprcNinePart);
  529. return TRUE;
  530. }
  531. }
  532. BOOL CSkinMenu::SetCheckImage( LPCTSTR lpszFileName )
  533. {
  534. RenderEngine->RemoveImage(m_pCheck);
  535. m_pCheck = RenderEngine->GetImage(lpszFileName);
  536. if (NULL == m_pCheck)
  537. return FALSE;
  538. else
  539. {
  540. return TRUE;
  541. }
  542. }
  543. BOOL CSkinMenu::SetArrowImage( LPCTSTR lpszFileName )
  544. {
  545. RenderEngine->RemoveImage(m_pArrow);
  546. m_pArrow = RenderEngine->GetImage(lpszFileName);
  547. if (NULL == m_pArrow)
  548. return FALSE;
  549. else
  550. {
  551. return TRUE;
  552. }
  553. }
  554. int CSkinMenu::GetSeparatorCount()
  555. {
  556. int nSeparatorCount = 0;
  557. for (int i=0;i<m_MenuItemActive.GetCount();i++)
  558. {
  559. if ( m_MenuItemActive.GetAt(i)->m_MenuItemType == MenuItemType_Separator )
  560. {
  561. nSeparatorCount++;
  562. }
  563. }
  564. return nSeparatorCount;
  565. }
  566. //////////////////////////////////////////////////////////////////////////////////