UIMenu.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. #ifndef __UIMENU_H__
  2. #define __UIMENU_H__
  3. #pragma once
  4. #include "../Utils/observer_impl_base.h"
  5. namespace DuiLib {
  6. struct ContextMenuParam
  7. {
  8. // 1: remove all
  9. // 2: remove the sub menu
  10. WPARAM wParam;
  11. HWND hWnd;
  12. };
  13. struct MenuItemInfo
  14. {
  15. TCHAR szName[256];
  16. bool bChecked;
  17. };
  18. struct MenuCmd
  19. {
  20. TCHAR szName[256];
  21. TCHAR szUserData[1024];
  22. TCHAR szText[1024];
  23. BOOL bChecked;
  24. };
  25. enum MenuAlignment
  26. {
  27. eMenuAlignment_Left = 1 << 1,
  28. eMenuAlignment_Top = 1 << 2,
  29. eMenuAlignment_Right = 1 << 3,
  30. eMenuAlignment_Bottom = 1 << 4,
  31. };
  32. enum MenuItemDefaultInfo
  33. {
  34. ITEM_DEFAULT_HEIGHT = 30, //每一个item的默认高度(只在竖状排列时自定义)
  35. ITEM_DEFAULT_WIDTH = 150, //窗口的默认宽度
  36. ITEM_DEFAULT_ICON_WIDTH = 26, //默认图标所占宽度
  37. ITEM_DEFAULT_ICON_SIZE = 16, //默认图标的大小
  38. ITEM_DEFAULT_EXPLAND_ICON_WIDTH = 20, //默认下级菜单扩展图标所占宽度
  39. ITEM_DEFAULT_EXPLAND_ICON_SIZE = 9, //默认下级菜单扩展图标的大小
  40. DEFAULT_LINE_LEFT_INSET = ITEM_DEFAULT_ICON_WIDTH + 3, //默认分隔线的左边距
  41. DEFAULT_LINE_RIGHT_INSET = 7, //默认分隔线的右边距
  42. DEFAULT_LINE_HEIGHT = 6, //默认分隔线所占高度
  43. DEFAULT_LINE_COLOR = 0xFFBCBFC4 //默认分隔线颜色
  44. };
  45. ///////////////////////////////////////////////
  46. class MenuMenuReceiverImplBase;
  47. class MenuMenuObserverImplBase
  48. {
  49. public:
  50. virtual void AddReceiver(MenuMenuReceiverImplBase* receiver) = 0;
  51. virtual void RemoveReceiver(MenuMenuReceiverImplBase* receiver) = 0;
  52. virtual BOOL RBroadcast(ContextMenuParam param) = 0;
  53. };
  54. /////////////////////////////////////////////////
  55. class MenuMenuReceiverImplBase
  56. {
  57. public:
  58. virtual void AddObserver(MenuMenuObserverImplBase* observer) = 0;
  59. virtual void RemoveObserver() = 0;
  60. virtual BOOL Receive(ContextMenuParam param) = 0;
  61. };
  62. /////////////////////////////////////////////////
  63. class MenuReceiverImpl;
  64. class UILIB_API MenuObserverImpl : public MenuMenuObserverImplBase
  65. {
  66. friend class Iterator;
  67. public:
  68. MenuObserverImpl():
  69. m_pMainWndPaintManager(NULL),
  70. m_pMenuCheckInfo(NULL)
  71. {
  72. pReceivers_ = new ReceiversVector;
  73. }
  74. ~MenuObserverImpl()
  75. {
  76. if (pReceivers_ != NULL)
  77. {
  78. delete pReceivers_;
  79. pReceivers_ = NULL;
  80. }
  81. }
  82. virtual void AddReceiver(MenuMenuReceiverImplBase* receiver)
  83. {
  84. if (receiver == NULL)
  85. return;
  86. pReceivers_->push_back(receiver);
  87. receiver->AddObserver(this);
  88. }
  89. virtual void RemoveReceiver(MenuMenuReceiverImplBase* receiver)
  90. {
  91. if (receiver == NULL)
  92. return;
  93. ReceiversVector::iterator it = pReceivers_->begin();
  94. for (; it != pReceivers_->end(); ++it)
  95. {
  96. if (*it == receiver)
  97. {
  98. pReceivers_->erase(it);
  99. break;
  100. }
  101. }
  102. }
  103. virtual BOOL RBroadcast(ContextMenuParam param)
  104. {
  105. ReceiversVector::reverse_iterator it = pReceivers_->rbegin();
  106. for (; it != pReceivers_->rend(); ++it)
  107. {
  108. (*it)->Receive(param);
  109. }
  110. return BOOL();
  111. }
  112. class Iterator
  113. {
  114. MenuObserverImpl & _tbl;
  115. DWORD index;
  116. MenuMenuReceiverImplBase* ptr;
  117. public:
  118. Iterator( MenuObserverImpl & table )
  119. : _tbl( table ), index(0), ptr(NULL)
  120. {}
  121. Iterator( const Iterator & v )
  122. : _tbl( v._tbl ), index(v.index), ptr(v.ptr)
  123. {}
  124. MenuMenuReceiverImplBase* next()
  125. {
  126. if ( index >= _tbl.pReceivers_->size() )
  127. return NULL;
  128. for ( ; index < _tbl.pReceivers_->size(); )
  129. {
  130. ptr = (*(_tbl.pReceivers_))[ index++ ];
  131. if ( ptr )
  132. return ptr;
  133. }
  134. return NULL;
  135. }
  136. };
  137. virtual void SetManger(CPaintManagerUI* pManager)
  138. {
  139. if (pManager != NULL)
  140. m_pMainWndPaintManager = pManager;
  141. }
  142. virtual CPaintManagerUI* GetManager() const
  143. {
  144. return m_pMainWndPaintManager;
  145. }
  146. virtual void SetMenuCheckInfo(CStdStringPtrMap* pInfo)
  147. {
  148. if (pInfo != NULL)
  149. m_pMenuCheckInfo = pInfo;
  150. else
  151. m_pMenuCheckInfo = NULL;
  152. }
  153. virtual CStdStringPtrMap* GetMenuCheckInfo() const
  154. {
  155. return m_pMenuCheckInfo;
  156. }
  157. protected:
  158. typedef std::vector<MenuMenuReceiverImplBase*> ReceiversVector;
  159. ReceiversVector *pReceivers_;
  160. CPaintManagerUI* m_pMainWndPaintManager;
  161. CStdStringPtrMap* m_pMenuCheckInfo;
  162. };
  163. ////////////////////////////////////////////////////
  164. class UILIB_API MenuReceiverImpl : public MenuMenuReceiverImplBase
  165. {
  166. public:
  167. MenuReceiverImpl()
  168. {
  169. pObservers_ = new ObserversVector;
  170. }
  171. ~MenuReceiverImpl()
  172. {
  173. if (pObservers_ != NULL)
  174. {
  175. delete pObservers_;
  176. pObservers_ = NULL;
  177. }
  178. }
  179. virtual void AddObserver(MenuMenuObserverImplBase* observer)
  180. {
  181. pObservers_->push_back(observer);
  182. }
  183. virtual void RemoveObserver()
  184. {
  185. if (!pObservers_) return;
  186. ObserversVector::iterator it = pObservers_->begin();
  187. for (; it != pObservers_->end(); ++it)
  188. {
  189. (*it)->RemoveReceiver(this);
  190. }
  191. }
  192. virtual BOOL Receive(ContextMenuParam param)
  193. {
  194. return BOOL();
  195. }
  196. protected:
  197. typedef std::vector<MenuMenuObserverImplBase*> ObserversVector;
  198. ObserversVector* pObservers_;
  199. };
  200. /////////////////////////////////////////////////////////////////////////////////////
  201. //
  202. class CListUI;
  203. class CMenuWnd;
  204. class UILIB_API CMenuUI : public CListUI
  205. {
  206. DECLARE_DUICONTROL(CMenuUI)
  207. public:
  208. CMenuUI();
  209. virtual ~CMenuUI();
  210. CMenuWnd* m_pWindow;
  211. LPCTSTR GetClass() const;
  212. LPVOID GetInterface(LPCTSTR pstrName);
  213. UINT GetListType();
  214. virtual void DoEvent(TEventUI& event);
  215. virtual bool Add(CControlUI* pControl);
  216. virtual bool AddAt(CControlUI* pControl, int iIndex);
  217. virtual int GetItemIndex(CControlUI* pControl) const;
  218. virtual bool SetItemIndex(CControlUI* pControl, int iIndex);
  219. virtual bool Remove(CControlUI* pControl);
  220. SIZE EstimateSize(SIZE szAvailable);
  221. void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) ;
  222. };
  223. /////////////////////////////////////////////////////////////////////////////////////
  224. //
  225. class CMenuElementUI;
  226. class UILIB_API CMenuWnd : public CWindowWnd, public MenuReceiverImpl, public INotifyUI, public IDialogBuilderCallback
  227. {
  228. public:
  229. static MenuObserverImpl& GetGlobalContextMenuObserver()
  230. {
  231. static MenuObserverImpl s_context_menu_observer;
  232. return s_context_menu_observer;
  233. }
  234. static CMenuWnd* CreateMenu(CMenuElementUI* pOwner, STRINGorID xml, POINT point,
  235. CPaintManagerUI* pMainPaintManager, CStdStringPtrMap* pMenuCheckInfo = NULL,
  236. DWORD dwAlignment = eMenuAlignment_Left | eMenuAlignment_Top);
  237. static void DestroyMenu();
  238. static MenuItemInfo* SetMenuItemInfo(LPCTSTR pstrName, bool bChecked);
  239. public:
  240. CMenuWnd();
  241. ~CMenuWnd();
  242. void Close(UINT nRet = IDOK);
  243. bool isClosing;
  244. /*
  245. * @pOwner 一级菜单不要指定这个参数,这是菜单内部使用的
  246. * @xml 菜单的布局文件
  247. * @point 菜单的左上角坐标
  248. * @pMainPaintManager 菜单的父窗体管理器指针
  249. * @pMenuCheckInfo 保存菜单的单选和复选信息结构指针
  250. * @dwAlignment 菜单的出现位置,默认出现在鼠标的右下侧。
  251. */
  252. void Init(CMenuElementUI* pOwner, STRINGorID xml, POINT point,
  253. CPaintManagerUI* pMainPaintManager, CStdStringPtrMap* pMenuCheckInfo = NULL,
  254. DWORD dwAlignment = eMenuAlignment_Left | eMenuAlignment_Top);
  255. LPCTSTR GetWindowClassName() const;
  256. void OnFinalMessage(HWND hWnd);
  257. void Notify(TNotifyUI& msg);
  258. CControlUI* CreateControl(LPCTSTR pstrClassName);
  259. LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  260. LRESULT OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  261. LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  262. LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
  263. BOOL Receive(ContextMenuParam param);
  264. // 获取根菜单控件,用于动态添加子菜单
  265. CMenuUI* GetMenuUI();
  266. // 重新调整菜单的大小
  267. void ResizeMenu();
  268. // 重新调整子菜单的大小
  269. void ResizeSubMenu();
  270. void setDPI(int DPI);
  271. public:
  272. POINT m_BasedPoint;
  273. STRINGorID m_xml;
  274. CPaintManagerUI m_pm;
  275. CMenuElementUI* m_pOwner;
  276. CMenuUI* m_pLayout;
  277. DWORD m_dwAlignment; //菜单对齐方式
  278. };
  279. class CListContainerElementUI;
  280. class UILIB_API CMenuElementUI : public CListContainerElementUI
  281. {
  282. DECLARE_DUICONTROL(CMenuElementUI)
  283. friend CMenuWnd;
  284. public:
  285. CMenuElementUI();
  286. ~CMenuElementUI();
  287. LPCTSTR GetClass() const;
  288. LPVOID GetInterface(LPCTSTR pstrName);
  289. bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl);
  290. void DrawItemText(HDC hDC, const RECT& rcItem);
  291. SIZE EstimateSize(SIZE szAvailable);
  292. void DoEvent(TEventUI& event);
  293. CMenuWnd* GetMenuWnd();
  294. void CreateMenuWnd();
  295. void SetLineType();
  296. void SetLineColor(DWORD color);
  297. DWORD GetLineColor() const;
  298. void SetLinePadding(RECT rcInset);
  299. RECT GetLinePadding() const;
  300. void SetIcon(LPCTSTR strIcon);
  301. void SetIconSize(LONG cx, LONG cy);
  302. SIZE GetIconSize();
  303. void DrawItemIcon(HDC hDC, const RECT& rcItem);
  304. void SetChecked(bool bCheck = true);
  305. bool GetChecked() const;
  306. void SetCheckItem(bool bCheckItem = false);
  307. bool GetCheckItem() const;
  308. void SetShowExplandIcon(bool bShow);
  309. void DrawItemExpland(HDC hDC, const RECT& rcItem);
  310. void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
  311. MenuItemInfo* GetItemInfo(LPCTSTR pstrName);
  312. MenuItemInfo* SetItemInfo(LPCTSTR pstrName, bool bChecked);
  313. protected:
  314. CMenuWnd* m_pWindow;
  315. bool m_bDrawLine; //画分隔线
  316. DWORD m_dwLineColor; //分隔线颜色
  317. RECT m_rcLinePadding; //分割线的左右边距
  318. SIZE m_szIconSize; //画图标
  319. CDuiString m_strIcon;
  320. bool m_bCheckItem;
  321. bool m_bShowExplandIcon;
  322. };
  323. } // namespace DuiLib
  324. #endif // __UIMENU_H__