UIMenu.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200
  1. #include "StdAfx.h"
  2. #include "UIMenu.h"
  3. namespace DuiLib {
  4. /////////////////////////////////////////////////////////////////////////////////////
  5. //
  6. IMPLEMENT_DUICONTROL(CMenuUI)
  7. CMenuUI::CMenuUI():
  8. m_pWindow(NULL)
  9. {
  10. if (GetHeader() != NULL)
  11. GetHeader()->SetVisible(false);
  12. }
  13. CMenuUI::~CMenuUI()
  14. {
  15. }
  16. LPCTSTR CMenuUI::GetClass() const
  17. {
  18. return _T("MenuUI");
  19. }
  20. LPVOID CMenuUI::GetInterface(LPCTSTR pstrName)
  21. {
  22. if( _tcsicmp(pstrName, _T("Menu")) == 0 ) return static_cast<CMenuUI*>(this);
  23. return CListUI::GetInterface(pstrName);
  24. }
  25. UINT CMenuUI::GetListType()
  26. {
  27. return LT_MENU;
  28. }
  29. void CMenuUI::DoEvent(TEventUI& event)
  30. {
  31. return __super::DoEvent(event);
  32. }
  33. bool CMenuUI::Add(CControlUI* pControl)
  34. {
  35. CMenuElementUI* pMenuItem = static_cast<CMenuElementUI*>(pControl->GetInterface(_T("MenuElement")));
  36. if (pMenuItem == NULL)
  37. return false;
  38. for (int i = 0; i < pMenuItem->GetCount(); ++i)
  39. {
  40. if (pMenuItem->GetItemAt(i)->GetInterface(_T("MenuElement")) != NULL)
  41. {
  42. (static_cast<CMenuElementUI*>(pMenuItem->GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetInternVisible(false);
  43. }
  44. }
  45. return CListUI::Add(pControl);
  46. }
  47. bool CMenuUI::AddAt(CControlUI* pControl, int iIndex)
  48. {
  49. CMenuElementUI* pMenuItem = static_cast<CMenuElementUI*>(pControl->GetInterface(_T("MenuElement")));
  50. if (pMenuItem == NULL)
  51. return false;
  52. for (int i = 0; i < pMenuItem->GetCount(); ++i)
  53. {
  54. if (pMenuItem->GetItemAt(i)->GetInterface(_T("MenuElement")) != NULL)
  55. {
  56. (static_cast<CMenuElementUI*>(pMenuItem->GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetInternVisible(false);
  57. }
  58. }
  59. return CListUI::AddAt(pControl, iIndex);
  60. }
  61. int CMenuUI::GetItemIndex(CControlUI* pControl) const
  62. {
  63. CMenuElementUI* pMenuItem = static_cast<CMenuElementUI*>(pControl->GetInterface(_T("MenuElement")));
  64. if (pMenuItem == NULL)
  65. return -1;
  66. return __super::GetItemIndex(pControl);
  67. }
  68. bool CMenuUI::SetItemIndex(CControlUI* pControl, int iIndex)
  69. {
  70. CMenuElementUI* pMenuItem = static_cast<CMenuElementUI*>(pControl->GetInterface(_T("MenuElement")));
  71. if (pMenuItem == NULL)
  72. return false;
  73. return __super::SetItemIndex(pControl, iIndex);
  74. }
  75. bool CMenuUI::Remove(CControlUI* pControl)
  76. {
  77. CMenuElementUI* pMenuItem = static_cast<CMenuElementUI*>(pControl->GetInterface(_T("MenuElement")));
  78. if (pMenuItem == NULL)
  79. return false;
  80. return __super::Remove(pControl);
  81. }
  82. SIZE CMenuUI::EstimateSize(SIZE szAvailable)
  83. {
  84. int cxFixed = 0;
  85. int cyFixed = 0;
  86. for( int it = 0; it < GetCount(); it++ ) {
  87. CControlUI* pControl = static_cast<CControlUI*>(GetItemAt(it));
  88. if( !pControl->IsVisible() ) continue;
  89. SIZE sz = pControl->EstimateSize(szAvailable);
  90. cyFixed += sz.cy;
  91. if( cxFixed < sz.cx )
  92. cxFixed = sz.cx;
  93. }
  94. for (int it = 0; it < GetCount(); it++) {
  95. CControlUI* pControl = static_cast<CControlUI*>(GetItemAt(it));
  96. if (!pControl->IsVisible()) continue;
  97. pControl->SetFixedWidth(MulDiv(cxFixed, 100, GetManager()->GetDPIObj()->GetScale()));
  98. }
  99. return CDuiSize(cxFixed, cyFixed);
  100. }
  101. void CMenuUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  102. {
  103. CListUI::SetAttribute(pstrName, pstrValue);
  104. }
  105. /////////////////////////////////////////////////////////////////////////////////////
  106. //
  107. CMenuWnd::CMenuWnd():
  108. m_pOwner(NULL),
  109. m_pLayout(),
  110. m_xml(_T("")),
  111. isClosing(false)
  112. {
  113. m_dwAlignment = eMenuAlignment_Left | eMenuAlignment_Top;
  114. }
  115. CMenuWnd::~CMenuWnd()
  116. {
  117. }
  118. void CMenuWnd::Close(UINT nRet)
  119. {
  120. ASSERT(::IsWindow(m_hWnd));
  121. if (!::IsWindow(m_hWnd)) return;
  122. PostMessage(WM_CLOSE, (WPARAM)nRet, 0L);
  123. isClosing = true;
  124. }
  125. BOOL CMenuWnd::Receive(ContextMenuParam param)
  126. {
  127. switch (param.wParam)
  128. {
  129. case 1:
  130. Close();
  131. break;
  132. case 2:
  133. {
  134. HWND hParent = GetParent(m_hWnd);
  135. while (hParent != NULL)
  136. {
  137. if (hParent == param.hWnd)
  138. {
  139. Close();
  140. break;
  141. }
  142. hParent = GetParent(hParent);
  143. }
  144. }
  145. break;
  146. default:
  147. break;
  148. }
  149. return TRUE;
  150. }
  151. CMenuWnd* CMenuWnd::CreateMenu(CMenuElementUI* pOwner, STRINGorID xml, POINT point, CPaintManagerUI* pMainPaintManager, CStdStringPtrMap* pMenuCheckInfo /*= NULL*/, DWORD dwAlignment /*= eMenuAlignment_Left | eMenuAlignment_Top*/)
  152. {
  153. CMenuWnd* pMenu = new CMenuWnd;
  154. pMenu->Init(pOwner, xml, point, pMainPaintManager, pMenuCheckInfo, dwAlignment);
  155. return pMenu;
  156. }
  157. void CMenuWnd::DestroyMenu()
  158. {
  159. CStdStringPtrMap* mCheckInfos = CMenuWnd::GetGlobalContextMenuObserver().GetMenuCheckInfo();
  160. if (mCheckInfos != NULL)
  161. {
  162. for(int i = 0; i < mCheckInfos->GetSize(); i++) {
  163. MenuItemInfo* pItemInfo = (MenuItemInfo*)mCheckInfos->Find(mCheckInfos->GetAt(i));
  164. if(pItemInfo != NULL) {
  165. delete pItemInfo;
  166. pItemInfo = NULL;
  167. }
  168. }
  169. mCheckInfos->Resize(0);
  170. }
  171. }
  172. MenuItemInfo* CMenuWnd::SetMenuItemInfo(LPCTSTR pstrName, bool bChecked)
  173. {
  174. if(pstrName == NULL || lstrlen(pstrName) <= 0) return NULL;
  175. CStdStringPtrMap* mCheckInfos = CMenuWnd::GetGlobalContextMenuObserver().GetMenuCheckInfo();
  176. if (mCheckInfos != NULL)
  177. {
  178. MenuItemInfo* pItemInfo = (MenuItemInfo*)mCheckInfos->Find(pstrName);
  179. if(pItemInfo == NULL) {
  180. pItemInfo = new MenuItemInfo;
  181. lstrcpy(pItemInfo->szName, pstrName);
  182. pItemInfo->bChecked = bChecked;
  183. mCheckInfos->Insert(pstrName, pItemInfo);
  184. }
  185. else {
  186. pItemInfo->bChecked = bChecked;
  187. }
  188. return pItemInfo;
  189. }
  190. return NULL;
  191. }
  192. void CMenuWnd::Init(CMenuElementUI* pOwner, STRINGorID xml, POINT point,
  193. CPaintManagerUI* pMainPaintManager, CStdStringPtrMap* pMenuCheckInfo/* = NULL*/,
  194. DWORD dwAlignment/* = eMenuAlignment_Left | eMenuAlignment_Top*/)
  195. {
  196. m_BasedPoint = point;
  197. m_pOwner = pOwner;
  198. m_pLayout = NULL;
  199. m_xml = xml;
  200. m_dwAlignment = dwAlignment;
  201. // 如果是一级菜单的创建
  202. if (pOwner == NULL)
  203. {
  204. ASSERT(pMainPaintManager != NULL);
  205. CMenuWnd::GetGlobalContextMenuObserver().SetManger(pMainPaintManager);
  206. if (pMenuCheckInfo != NULL)
  207. CMenuWnd::GetGlobalContextMenuObserver().SetMenuCheckInfo(pMenuCheckInfo);
  208. }
  209. CMenuWnd::GetGlobalContextMenuObserver().AddReceiver(this);
  210. Create((m_pOwner == NULL) ? pMainPaintManager->GetPaintWindow() : m_pOwner->GetManager()->GetPaintWindow(), NULL, WS_POPUP , WS_EX_TOOLWINDOW | WS_EX_TOPMOST, CDuiRect());
  211. // HACK: Don't deselect the parent's caption
  212. HWND hWndParent = m_hWnd;
  213. while( ::GetParent(hWndParent) != NULL ) hWndParent = ::GetParent(hWndParent);
  214. ::ShowWindow(m_hWnd, SW_SHOW);
  215. ::SendMessage(hWndParent, WM_NCACTIVATE, TRUE, 0L);
  216. }
  217. LPCTSTR CMenuWnd::GetWindowClassName() const
  218. {
  219. return _T("DuiMenuWnd");
  220. }
  221. void CMenuWnd::Notify(TNotifyUI& msg)
  222. {
  223. if( CMenuWnd::GetGlobalContextMenuObserver().GetManager() != NULL)
  224. {
  225. if( msg.sType == _T("click") || msg.sType == _T("valuechanged") )
  226. {
  227. CMenuWnd::GetGlobalContextMenuObserver().GetManager()->SendNotify(msg, false);
  228. }
  229. }
  230. }
  231. CControlUI* CMenuWnd::CreateControl( LPCTSTR pstrClassName )
  232. {
  233. if (_tcsicmp(pstrClassName, _T("Menu")) == 0)
  234. {
  235. return new CMenuUI();
  236. }
  237. else if (_tcsicmp(pstrClassName, _T("MenuElement")) == 0)
  238. {
  239. return new CMenuElementUI();
  240. }
  241. return NULL;
  242. }
  243. void CMenuWnd::OnFinalMessage(HWND hWnd)
  244. {
  245. RemoveObserver();
  246. if( m_pOwner != NULL ) {
  247. for( int i = 0; i < m_pOwner->GetCount(); i++ ) {
  248. if( static_cast<CMenuElementUI*>(m_pOwner->GetItemAt(i)->GetInterface(_T("MenuElement"))) != NULL ) {
  249. (static_cast<CMenuElementUI*>(m_pOwner->GetItemAt(i)))->SetOwner(m_pOwner->GetParent());
  250. (static_cast<CMenuElementUI*>(m_pOwner->GetItemAt(i)))->SetVisible(false);
  251. (static_cast<CMenuElementUI*>(m_pOwner->GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetInternVisible(false);
  252. }
  253. }
  254. m_pOwner->m_pWindow = NULL;
  255. m_pOwner->m_uButtonState &= ~ UISTATE_PUSHED;
  256. m_pOwner->Invalidate();
  257. // 内部创建的内部删除
  258. delete this;
  259. }
  260. }
  261. LRESULT CMenuWnd::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  262. {
  263. bool bShowShadow = false;
  264. if( m_pOwner != NULL) {
  265. LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
  266. styleValue &= ~WS_CAPTION;
  267. ::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
  268. RECT rcClient;
  269. ::GetClientRect(*this, &rcClient);
  270. ::SetWindowPos(*this, NULL, rcClient.left, rcClient.top, rcClient.right - rcClient.left, \
  271. rcClient.bottom - rcClient.top, SWP_FRAMECHANGED);
  272. m_pm.Init(m_hWnd);
  273. m_pm.GetDPIObj()->SetScale(m_pOwner->GetManager()->GetDPIObj()->GetDPI());
  274. // The trick is to add the items to the new container. Their owner gets
  275. // reassigned by this operation - which is why it is important to reassign
  276. // the items back to the righfull owner/manager when the window closes.
  277. m_pLayout = new CMenuUI();
  278. m_pm.SetForceUseSharedRes(true);
  279. m_pLayout->SetManager(&m_pm, NULL, true);
  280. LPCTSTR pDefaultAttributes = m_pOwner->GetManager()->GetDefaultAttributeList(_T("Menu"));
  281. if( pDefaultAttributes ) {
  282. m_pLayout->ApplyAttributeList(pDefaultAttributes);
  283. }
  284. m_pLayout->GetList()->SetAutoDestroy(false);
  285. for( int i = 0; i < m_pOwner->GetCount(); i++ ) {
  286. if(m_pOwner->GetItemAt(i)->GetInterface(_T("MenuElement")) != NULL ){
  287. (static_cast<CMenuElementUI*>(m_pOwner->GetItemAt(i)))->SetOwner(m_pLayout);
  288. m_pLayout->Add(static_cast<CControlUI*>(m_pOwner->GetItemAt(i)));
  289. }
  290. }
  291. CShadowUI *pShadow = m_pOwner->GetManager()->GetShadow();
  292. pShadow->CopyShadow(m_pm.GetShadow());
  293. bShowShadow = m_pm.GetShadow()->IsShowShadow();
  294. m_pm.GetShadow()->ShowShadow(false);
  295. m_pm.SetLayered(m_pOwner->GetManager()->IsLayered());
  296. m_pm.AttachDialog(m_pLayout);
  297. m_pm.AddNotifier(this);
  298. ResizeSubMenu();
  299. }
  300. else {
  301. m_pm.Init(m_hWnd);
  302. m_pm.GetDPIObj()->SetScale(CMenuWnd::GetGlobalContextMenuObserver().GetManager()->GetDPIObj()->GetDPI());
  303. CDialogBuilder builder;
  304. CControlUI* pRoot = builder.Create(m_xml,UINT(0), this, &m_pm);
  305. bShowShadow = m_pm.GetShadow()->IsShowShadow();
  306. m_pm.GetShadow()->ShowShadow(false);
  307. m_pm.AttachDialog(pRoot);
  308. m_pm.AddNotifier(this);
  309. ResizeMenu();
  310. }
  311. GetMenuUI()->m_pWindow = this;
  312. m_pm.GetShadow()->ShowShadow(bShowShadow);
  313. m_pm.GetShadow()->Create(&m_pm);
  314. return 0;
  315. }
  316. CMenuUI* CMenuWnd::GetMenuUI()
  317. {
  318. return static_cast<CMenuUI*>(m_pm.GetRoot());
  319. }
  320. void CMenuWnd::ResizeMenu()
  321. {
  322. CControlUI* pRoot = m_pm.GetRoot();
  323. #if defined(WIN32) && !defined(UNDER_CE)
  324. MONITORINFO oMonitor = {};
  325. oMonitor.cbSize = sizeof(oMonitor);
  326. ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
  327. CDuiRect rcWork = oMonitor.rcWork;
  328. #else
  329. CDuiRect rcWork;
  330. GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWork);
  331. #endif
  332. SIZE szAvailable = { rcWork.right - rcWork.left, rcWork.bottom - rcWork.top };
  333. szAvailable = pRoot->EstimateSize(szAvailable);
  334. m_pm.SetInitSize(szAvailable.cx, szAvailable.cy);
  335. //必须是Menu标签作为xml的根节点
  336. CMenuUI *pMenuRoot = static_cast<CMenuUI*>(pRoot);
  337. ASSERT(pMenuRoot);
  338. SIZE szInit = m_pm.GetInitSize();
  339. CDuiRect rc;
  340. CDuiPoint point = m_BasedPoint;
  341. rc.left = point.x;
  342. rc.top = point.y;
  343. rc.right = rc.left + szInit.cx;
  344. rc.bottom = rc.top + szInit.cy;
  345. int nWidth = rc.GetWidth();
  346. int nHeight = rc.GetHeight();
  347. if (m_dwAlignment & eMenuAlignment_Right)
  348. {
  349. rc.right = point.x;
  350. rc.left = rc.right - nWidth;
  351. }
  352. if (m_dwAlignment & eMenuAlignment_Bottom)
  353. {
  354. rc.bottom = point.y;
  355. rc.top = rc.bottom - nHeight;
  356. }
  357. SetForegroundWindow(m_hWnd);
  358. MoveWindow(m_hWnd, rc.left, rc.top, rc.GetWidth(), rc.GetHeight(), FALSE);
  359. SetWindowPos(m_hWnd, HWND_TOPMOST, rc.left, rc.top, rc.GetWidth(), rc.GetHeight() + pMenuRoot->GetInset().bottom + pMenuRoot->GetInset().top, SWP_SHOWWINDOW);
  360. }
  361. void CMenuWnd::ResizeSubMenu()
  362. {
  363. // Position the popup window in absolute space
  364. RECT rcOwner = m_pOwner->GetPos();
  365. RECT rc = rcOwner;
  366. int cxFixed = 0;
  367. int cyFixed = 0;
  368. #if defined(WIN32) && !defined(UNDER_CE)
  369. MONITORINFO oMonitor = {};
  370. oMonitor.cbSize = sizeof(oMonitor);
  371. ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
  372. CDuiRect rcWork = oMonitor.rcWork;
  373. #else
  374. CDuiRect rcWork;
  375. GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWork);
  376. #endif
  377. SIZE szAvailable = { rcWork.right - rcWork.left, rcWork.bottom - rcWork.top };
  378. for( int it = 0; it < m_pOwner->GetCount(); it++ ) {
  379. if(m_pOwner->GetItemAt(it)->GetInterface(_T("MenuElement")) != NULL ){
  380. CControlUI* pControl = static_cast<CControlUI*>(m_pOwner->GetItemAt(it));
  381. SIZE sz = pControl->EstimateSize(szAvailable);
  382. cyFixed += sz.cy;
  383. if( cxFixed < sz.cx ) cxFixed = sz.cx;
  384. }
  385. }
  386. RECT rcWindow;
  387. GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWindow);
  388. rc.top = rcOwner.top;
  389. rc.bottom = rc.top + cyFixed;
  390. ::MapWindowRect(m_pOwner->GetManager()->GetPaintWindow(), HWND_DESKTOP, &rc);
  391. rc.left = rcWindow.right;
  392. rc.right = rc.left + cxFixed;
  393. rc.right += 2;
  394. bool bReachBottom = false;
  395. bool bReachRight = false;
  396. LONG chRightAlgin = 0;
  397. LONG chBottomAlgin = 0;
  398. RECT rcPreWindow = {0};
  399. MenuObserverImpl::Iterator iterator(CMenuWnd::GetGlobalContextMenuObserver());
  400. MenuMenuReceiverImplBase* pReceiver = iterator.next();
  401. while( pReceiver != NULL ) {
  402. CMenuWnd* pContextMenu = dynamic_cast<CMenuWnd*>(pReceiver);
  403. if( pContextMenu != NULL ) {
  404. GetWindowRect(pContextMenu->GetHWND(), &rcPreWindow);
  405. bReachRight = rcPreWindow.left >= rcWindow.right;
  406. bReachBottom = rcPreWindow.top >= rcWindow.bottom;
  407. if( pContextMenu->GetHWND() == m_pOwner->GetManager()->GetPaintWindow() || bReachBottom || bReachRight )
  408. break;
  409. }
  410. pReceiver = iterator.next();
  411. }
  412. if (bReachBottom)
  413. {
  414. rc.bottom = rcWindow.top;
  415. rc.top = rc.bottom - cyFixed;
  416. }
  417. if (bReachRight)
  418. {
  419. rc.right = rcWindow.left;
  420. rc.left = rc.right - cxFixed;
  421. }
  422. if( rc.bottom > rcWork.bottom )
  423. {
  424. rc.bottom = rc.top;
  425. rc.top = rc.bottom - cyFixed;
  426. }
  427. if (rc.right > rcWork.right)
  428. {
  429. rc.right = rcWindow.left;
  430. rc.left = rc.right - cxFixed;
  431. }
  432. if( rc.top < rcWork.top )
  433. {
  434. rc.top = rcOwner.top;
  435. rc.bottom = rc.top + cyFixed;
  436. }
  437. if (rc.left < rcWork.left)
  438. {
  439. rc.left = rcWindow.right;
  440. rc.right = rc.left + cxFixed;
  441. }
  442. MoveWindow(m_hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top + m_pLayout->GetInset().top + m_pLayout->GetInset().bottom, FALSE);
  443. }
  444. void CMenuWnd::setDPI(int DPI) {
  445. m_pm.SetDPI(DPI);
  446. }
  447. LRESULT CMenuWnd::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  448. {
  449. HWND hFocusWnd = (HWND)wParam;
  450. BOOL bInMenuWindowList = FALSE;
  451. ContextMenuParam param;
  452. param.hWnd = GetHWND();
  453. MenuObserverImpl::Iterator iterator(CMenuWnd::GetGlobalContextMenuObserver());
  454. MenuMenuReceiverImplBase* pReceiver = iterator.next();
  455. while( pReceiver != NULL ) {
  456. CMenuWnd* pContextMenu = dynamic_cast<CMenuWnd*>(pReceiver);
  457. if( pContextMenu != NULL && pContextMenu->GetHWND() == hFocusWnd ) {
  458. bInMenuWindowList = TRUE;
  459. break;
  460. }
  461. pReceiver = iterator.next();
  462. }
  463. if( !bInMenuWindowList ) {
  464. param.wParam = 1;
  465. CMenuWnd::GetGlobalContextMenuObserver().RBroadcast(param);
  466. return 0;
  467. }
  468. return 0;
  469. }
  470. LRESULT CMenuWnd::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  471. {
  472. SIZE szRoundCorner = m_pm.GetRoundCorner();
  473. if( !::IsIconic(*this) ) {
  474. CDuiRect rcWnd;
  475. ::GetWindowRect(*this, &rcWnd);
  476. rcWnd.Offset(-rcWnd.left, -rcWnd.top);
  477. rcWnd.right++; rcWnd.bottom++;
  478. HRGN hRgn = ::CreateRoundRectRgn(rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom, szRoundCorner.cx, szRoundCorner.cy);
  479. ::SetWindowRgn(*this, hRgn, TRUE);
  480. ::DeleteObject(hRgn);
  481. }
  482. bHandled = FALSE;
  483. return 0;
  484. }
  485. LRESULT CMenuWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  486. {
  487. LRESULT lRes = 0;
  488. BOOL bHandled = TRUE;
  489. switch( uMsg )
  490. {
  491. case WM_CREATE:
  492. lRes = OnCreate(uMsg, wParam, lParam, bHandled);
  493. break;
  494. case WM_KILLFOCUS:
  495. lRes = OnKillFocus(uMsg, wParam, lParam, bHandled);
  496. break;
  497. case WM_KEYDOWN:
  498. if( wParam == VK_ESCAPE || wParam == VK_LEFT)
  499. Close();
  500. break;
  501. case WM_SIZE:
  502. lRes = OnSize(uMsg, wParam, lParam, bHandled);
  503. break;
  504. case WM_CLOSE:
  505. if( m_pOwner != NULL )
  506. {
  507. m_pOwner->SetManager(m_pOwner->GetManager(), m_pOwner->GetParent(), false);
  508. m_pOwner->SetPos(m_pOwner->GetPos());
  509. m_pOwner->SetFocus();
  510. }
  511. break;
  512. case WM_RBUTTONDOWN:
  513. case WM_CONTEXTMENU:
  514. case WM_RBUTTONUP:
  515. case WM_RBUTTONDBLCLK:
  516. return 0L;
  517. break;
  518. default:
  519. bHandled = FALSE;
  520. break;
  521. }
  522. if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
  523. return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
  524. }
  525. /////////////////////////////////////////////////////////////////////////////////////
  526. //
  527. IMPLEMENT_DUICONTROL(CMenuElementUI)
  528. CMenuElementUI::CMenuElementUI():
  529. m_pWindow(NULL),
  530. m_bDrawLine(false),
  531. m_dwLineColor(DEFAULT_LINE_COLOR),
  532. m_bCheckItem(false),
  533. m_bShowExplandIcon(false)
  534. {
  535. m_cxyFixed.cy = ITEM_DEFAULT_HEIGHT;
  536. m_cxyFixed.cx = ITEM_DEFAULT_WIDTH;
  537. m_szIconSize.cy = ITEM_DEFAULT_ICON_SIZE;
  538. m_szIconSize.cx = ITEM_DEFAULT_ICON_SIZE;
  539. m_rcLinePadding.top = m_rcLinePadding.bottom = 0;
  540. m_rcLinePadding.left = DEFAULT_LINE_LEFT_INSET;
  541. m_rcLinePadding.right = DEFAULT_LINE_RIGHT_INSET;
  542. }
  543. CMenuElementUI::~CMenuElementUI()
  544. {}
  545. LPCTSTR CMenuElementUI::GetClass() const
  546. {
  547. return _T("MenuElementUI");
  548. }
  549. LPVOID CMenuElementUI::GetInterface(LPCTSTR pstrName)
  550. {
  551. if( _tcsicmp(pstrName, _T("MenuElement")) == 0 ) return static_cast<CMenuElementUI*>(this);
  552. return CListContainerElementUI::GetInterface(pstrName);
  553. }
  554. bool CMenuElementUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
  555. {
  556. SIZE cxyFixed = GetFixedSize();
  557. RECT rcLinePadding = GetLinePadding();
  558. RECT rcTemp = { 0 };
  559. if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return true;
  560. if(m_bDrawLine)
  561. {
  562. RECT rcLine = { m_rcItem.left + rcLinePadding.left, m_rcItem.top + cxyFixed.cy/2, m_rcItem.right - rcLinePadding.right, m_rcItem.top + cxyFixed.cy/2 };
  563. CRenderEngine::DrawLine(hDC, rcLine, 1, m_dwLineColor);
  564. }
  565. else
  566. {
  567. CRenderClip clip;
  568. CRenderClip::GenerateClip(hDC, rcTemp, clip);
  569. CMenuElementUI::DrawItemBk(hDC, m_rcItem);
  570. DrawItemText(hDC, m_rcItem);
  571. DrawItemIcon(hDC, m_rcItem);
  572. DrawItemExpland(hDC, m_rcItem);
  573. if( m_items.GetSize() > 0 ) {
  574. RECT rc = m_rcItem;
  575. RECT rcInset = GetInset();
  576. rc.left += rcInset.left;
  577. rc.top += rcInset.top;
  578. rc.right -= rcInset.right;
  579. rc.bottom -= rcInset.bottom;
  580. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  581. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  582. if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) {
  583. for( int it = 0; it < m_items.GetSize(); it++ ) {
  584. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  585. if( pControl == pStopControl ) return false;
  586. if( !pControl->IsVisible() ) continue;
  587. if( pControl->GetInterface(_T("MenuElement")) != NULL ) continue;
  588. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  589. if( pControl->IsFloat() ) {
  590. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  591. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  592. }
  593. }
  594. }
  595. else {
  596. CRenderClip childClip;
  597. CRenderClip::GenerateClip(hDC, rcTemp, childClip);
  598. for( int it = 0; it < m_items.GetSize(); it++ ) {
  599. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  600. if( pControl == pStopControl ) return false;
  601. if( !pControl->IsVisible() ) continue;
  602. if( pControl->GetInterface(_T("MenuElement")) != NULL ) continue;
  603. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  604. if( pControl->IsFloat() ) {
  605. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  606. CRenderClip::UseOldClipBegin(hDC, childClip);
  607. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  608. CRenderClip::UseOldClipEnd(hDC, childClip);
  609. }
  610. else {
  611. if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue;
  612. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  613. }
  614. }
  615. }
  616. }
  617. }
  618. if( m_pVerticalScrollBar != NULL ) {
  619. if( m_pVerticalScrollBar == pStopControl ) return false;
  620. if (m_pVerticalScrollBar->IsVisible()) {
  621. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) {
  622. if( !m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false;
  623. }
  624. }
  625. }
  626. if( m_pHorizontalScrollBar != NULL ) {
  627. if( m_pHorizontalScrollBar == pStopControl ) return false;
  628. if (m_pHorizontalScrollBar->IsVisible()) {
  629. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) {
  630. if( !m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false;
  631. }
  632. }
  633. }
  634. return true;
  635. }
  636. void CMenuElementUI::DrawItemIcon(HDC hDC, const RECT& rcItem)
  637. {
  638. if (!m_strIcon.IsEmpty() && !(m_bCheckItem && !GetChecked())) {
  639. SIZE cxyFixed = GetFixedSize();
  640. SIZE szIconSize = GetIconSize();
  641. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  642. RECT rcTextPadding = GetManager()->GetDPIObj()->Scale(pInfo->rcTextPadding);
  643. RECT rcDest =
  644. {
  645. (rcTextPadding.left - szIconSize.cx) / 2,
  646. (cxyFixed.cy - szIconSize.cy) / 2,
  647. (rcTextPadding.left - szIconSize.cx) / 2 + szIconSize.cx,
  648. (cxyFixed.cy - szIconSize.cy) / 2 + szIconSize.cy
  649. };
  650. CDuiString pStrImage;
  651. pStrImage.Format(_T("dest='%d,%d,%d,%d'"), rcDest.left, rcDest.top, rcDest.right, rcDest.bottom);
  652. DrawImage(hDC, m_strIcon, pStrImage);
  653. }
  654. }
  655. void CMenuElementUI::DrawItemExpland(HDC hDC, const RECT& rcItem)
  656. {
  657. if (m_bShowExplandIcon) {
  658. CDuiString strExplandIcon;
  659. strExplandIcon = GetManager()->GetDefaultAttributeList(_T("ExplandIcon"));
  660. if (strExplandIcon.IsEmpty()) {
  661. return;
  662. }
  663. SIZE cxyFixed = GetManager()->GetDPIObj()->Scale(m_cxyFixed);
  664. int padding = GetManager()->GetDPIObj()->Scale(ITEM_DEFAULT_EXPLAND_ICON_WIDTH) / 3;
  665. const TDrawInfo* pDrawInfo = GetManager()->GetDrawInfo((LPCTSTR)strExplandIcon, NULL);
  666. const TImageInfo *pImageInfo = GetManager()->GetImageEx(pDrawInfo->sImageName, NULL, 0, false, pDrawInfo->bGdiplus);
  667. if (!pImageInfo) {
  668. return;
  669. }
  670. RECT rcDest =
  671. {
  672. cxyFixed.cx - pImageInfo->nX - padding,
  673. (cxyFixed.cy - pImageInfo->nY) / 2,
  674. cxyFixed.cx - pImageInfo->nX - padding + pImageInfo->nX,
  675. (cxyFixed.cy - pImageInfo->nY) / 2 + pImageInfo->nY
  676. };
  677. GetManager()->GetDPIObj()->ScaleBack(&rcDest);
  678. CDuiString pStrImage;
  679. pStrImage.Format(_T("dest='%d,%d,%d,%d'"), rcDest.left, rcDest.top, rcDest.right, rcDest.bottom);
  680. DrawImage(hDC, strExplandIcon, pStrImage);
  681. }
  682. }
  683. void CMenuElementUI::DrawItemText(HDC hDC, const RECT& rcItem)
  684. {
  685. CDuiString sText = GetText();
  686. if( sText.IsEmpty() ) return;
  687. if( m_pOwner == NULL ) return;
  688. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  689. DWORD iTextColor = pInfo->dwTextColor;
  690. if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  691. iTextColor = pInfo->dwHotTextColor;
  692. }
  693. if( IsSelected() ) {
  694. iTextColor = pInfo->dwSelectedTextColor;
  695. }
  696. if( !IsEnabled() ) {
  697. iTextColor = pInfo->dwDisabledTextColor;
  698. }
  699. int nLinks = 0;
  700. RECT rcText = rcItem;
  701. RECT rcTextPadding = GetManager()->GetDPIObj()->Scale(pInfo->rcTextPadding);
  702. rcText.left += rcTextPadding.left;
  703. rcText.right -= rcTextPadding.right;
  704. rcText.top += rcTextPadding.top;
  705. rcText.bottom -= rcTextPadding.bottom;
  706. if( pInfo->bShowHtml )
  707. CRenderEngine::DrawHtmlText(hDC, m_pManager, rcText, sText, iTextColor, \
  708. NULL, NULL, nLinks, pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle);
  709. else
  710. CRenderEngine::DrawText(hDC, m_pManager, rcText, sText, iTextColor, \
  711. pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle);
  712. }
  713. SIZE CMenuElementUI::EstimateSize(SIZE szAvailable)
  714. {
  715. SIZE cxyFixed = GetManager()->GetDPIObj()->Scale(m_cxyFixed);
  716. SIZE cXY = {0};
  717. for( int it = 0; it < GetCount(); it++ ) {
  718. CControlUI* pControl = static_cast<CControlUI*>(GetItemAt(it));
  719. if( !pControl->IsVisible() ) continue;
  720. SIZE sz = pControl->EstimateSize(szAvailable);
  721. cXY.cy += sz.cy;
  722. if( cXY.cx < sz.cx ) cXY.cx = sz.cx;
  723. }
  724. if(cXY.cy == 0) {
  725. CDuiString sText = GetText();
  726. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  727. DWORD iTextColor = pInfo->dwTextColor;
  728. RECT rcText = { 0, 0, MAX(szAvailable.cx, m_cxyFixed.cx), 9999 };
  729. RECT rcTextPadding = GetManager()->GetDPIObj()->Scale(pInfo->rcTextPadding);
  730. rcText.left += rcTextPadding.left;
  731. rcText.right -= rcTextPadding.right;
  732. if( pInfo->bShowHtml ) {
  733. int nLinks = 0;
  734. CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, sText, iTextColor, NULL, NULL, nLinks, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle);
  735. }
  736. else {
  737. CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, sText, iTextColor, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle);
  738. }
  739. cXY.cx = rcText.right - rcText.left + rcTextPadding.left + rcTextPadding.right ;
  740. cXY.cy = rcText.bottom - rcText.top + rcTextPadding.top + rcTextPadding.bottom;
  741. }
  742. if( cxyFixed.cy != 0 ) cXY.cy = cxyFixed.cy;
  743. if ( cXY.cx < m_cxyFixed.cx )
  744. cXY.cx = m_cxyFixed.cx;
  745. return cXY;
  746. }
  747. void CMenuElementUI::DoEvent(TEventUI& event)
  748. {
  749. if( event.Type == UIEVENT_MOUSEENTER )
  750. {
  751. CListContainerElementUI::DoEvent(event);
  752. if( m_pWindow ) return;
  753. bool hasSubMenu = false;
  754. for( int i = 0; i < GetCount(); ++i )
  755. {
  756. if( GetItemAt(i)->GetInterface(_T("MenuElement")) != NULL )
  757. {
  758. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetVisible(true);
  759. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetInternVisible(true);
  760. hasSubMenu = true;
  761. }
  762. }
  763. if( hasSubMenu )
  764. {
  765. m_pOwner->SelectItem(GetIndex(), true);
  766. CreateMenuWnd();
  767. }
  768. else
  769. {
  770. ContextMenuParam param;
  771. param.hWnd = m_pManager->GetPaintWindow();
  772. param.wParam = 2;
  773. CMenuWnd::GetGlobalContextMenuObserver().RBroadcast(param);
  774. m_pOwner->SelectItem(GetIndex(), true);
  775. }
  776. return;
  777. }
  778. if (event.Type == UIEVENT_MOUSELEAVE) {
  779. bool hasSubMenu = false;
  780. for (int i = 0; i < GetCount(); ++i)
  781. {
  782. if (GetItemAt(i)->GetInterface(_T("MenuElement")) != NULL)
  783. {
  784. hasSubMenu = true;
  785. }
  786. }
  787. if (!hasSubMenu) {
  788. m_pOwner->SelectItem(-1, true);
  789. }
  790. }
  791. if( event.Type == UIEVENT_BUTTONUP )
  792. {
  793. if( IsEnabled() ){
  794. CListContainerElementUI::DoEvent(event);
  795. if( m_pWindow ) return;
  796. bool hasSubMenu = false;
  797. for( int i = 0; i < GetCount(); ++i ) {
  798. if( GetItemAt(i)->GetInterface(_T("MenuElement")) != NULL ) {
  799. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetVisible(true);
  800. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetInternVisible(true);
  801. hasSubMenu = true;
  802. }
  803. }
  804. if( hasSubMenu )
  805. {
  806. CreateMenuWnd();
  807. }
  808. else
  809. {
  810. SetChecked(!GetChecked());
  811. bool isClosing = false;
  812. CMenuUI* menuUI=static_cast<CMenuUI*>(GetManager()->GetRoot());
  813. isClosing = (menuUI->m_pWindow->isClosing);
  814. if (IsWindow(GetManager()->GetPaintWindow()) && !isClosing) {
  815. if (CMenuWnd::GetGlobalContextMenuObserver().GetManager() != NULL) {
  816. MenuCmd* pMenuCmd = new MenuCmd();
  817. lstrcpy(pMenuCmd->szName, GetName().GetData());
  818. lstrcpy(pMenuCmd->szUserData, GetUserData().GetData());
  819. lstrcpy(pMenuCmd->szText, GetText().GetData());
  820. pMenuCmd->bChecked = GetChecked();
  821. if (!PostMessage(CMenuWnd::GetGlobalContextMenuObserver().GetManager()->GetPaintWindow(), WM_MENUCLICK, (WPARAM)pMenuCmd, (LPARAM)this)) {
  822. delete pMenuCmd;
  823. pMenuCmd = NULL;
  824. }
  825. }
  826. }
  827. ContextMenuParam param;
  828. param.hWnd = m_pManager->GetPaintWindow();
  829. param.wParam = 1;
  830. CMenuWnd::GetGlobalContextMenuObserver().RBroadcast(param);
  831. }
  832. }
  833. return;
  834. }
  835. if ( event.Type == UIEVENT_KEYDOWN && event.chKey == VK_RIGHT )
  836. {
  837. if( m_pWindow ) return;
  838. bool hasSubMenu = false;
  839. for( int i = 0; i < GetCount(); ++i ) {
  840. if( GetItemAt(i)->GetInterface(_T("MenuElement")) != NULL ) {
  841. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetVisible(true);
  842. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetInternVisible(true);
  843. hasSubMenu = true;
  844. }
  845. }
  846. if( hasSubMenu ) {
  847. m_pOwner->SelectItem(GetIndex(), true);
  848. CreateMenuWnd();
  849. }
  850. else
  851. {
  852. ContextMenuParam param;
  853. param.hWnd = m_pManager->GetPaintWindow();
  854. param.wParam = 2;
  855. CMenuWnd::GetGlobalContextMenuObserver().RBroadcast(param);
  856. m_pOwner->SelectItem(GetIndex(), true);
  857. }
  858. return;
  859. }
  860. CListContainerElementUI::DoEvent(event);
  861. }
  862. CMenuWnd* CMenuElementUI::GetMenuWnd()
  863. {
  864. return m_pWindow;
  865. }
  866. void CMenuElementUI::CreateMenuWnd()
  867. {
  868. if( m_pWindow ) return;
  869. m_pWindow = new CMenuWnd();
  870. ASSERT(m_pWindow);
  871. ContextMenuParam param;
  872. param.hWnd = m_pManager->GetPaintWindow();
  873. param.wParam = 2;
  874. CMenuWnd::GetGlobalContextMenuObserver().RBroadcast(param);
  875. m_pWindow->Init(static_cast<CMenuElementUI*>(this), _T(""), CDuiPoint(), NULL);
  876. }
  877. void CMenuElementUI::SetLineType()
  878. {
  879. m_bDrawLine = true;
  880. if (m_cxyFixed.cy == 0 || m_cxyFixed.cy == ITEM_DEFAULT_HEIGHT)
  881. SetFixedHeight(DEFAULT_LINE_HEIGHT);
  882. SetMouseChildEnabled(false);
  883. SetMouseEnabled(false);
  884. SetEnabled(false);
  885. }
  886. void CMenuElementUI::SetLineColor(DWORD color)
  887. {
  888. m_dwLineColor = color;
  889. }
  890. DWORD CMenuElementUI::GetLineColor() const
  891. {
  892. return m_dwLineColor;
  893. }
  894. void CMenuElementUI::SetLinePadding(RECT rcPadding)
  895. {
  896. m_rcLinePadding = rcPadding;
  897. }
  898. RECT CMenuElementUI::GetLinePadding() const
  899. {
  900. RECT rcLinePadding = m_rcLinePadding;
  901. if(m_pManager != NULL) m_pManager->GetDPIObj()->Scale(&rcLinePadding);
  902. return rcLinePadding;
  903. }
  904. void CMenuElementUI::SetIcon(LPCTSTR strIcon)
  905. {
  906. m_strIcon = strIcon;
  907. }
  908. void CMenuElementUI::SetIconSize(LONG cx, LONG cy)
  909. {
  910. m_szIconSize.cx = cx;
  911. m_szIconSize.cy = cy;
  912. }
  913. SIZE CMenuElementUI::GetIconSize()
  914. {
  915. SIZE szIconSize = m_szIconSize;
  916. if(m_pManager != NULL) m_pManager->GetDPIObj()->Scale(&szIconSize);
  917. return szIconSize;
  918. }
  919. void CMenuElementUI::SetChecked(bool bCheck/* = true*/)
  920. {
  921. SetItemInfo(GetName(), bCheck);
  922. }
  923. bool CMenuElementUI::GetChecked() const
  924. {
  925. LPCTSTR pstrName = GetName();
  926. if(pstrName == NULL || lstrlen(pstrName) <= 0) return false;
  927. CStdStringPtrMap* mCheckInfos = CMenuWnd::GetGlobalContextMenuObserver().GetMenuCheckInfo();
  928. if (mCheckInfos != NULL)
  929. {
  930. MenuItemInfo* pItemInfo = (MenuItemInfo*)mCheckInfos->Find(pstrName);
  931. if(pItemInfo != NULL) {
  932. return pItemInfo->bChecked;
  933. }
  934. }
  935. return false;
  936. }
  937. void CMenuElementUI::SetCheckItem(bool bCheckItem/* = false*/)
  938. {
  939. m_bCheckItem = bCheckItem;
  940. }
  941. bool CMenuElementUI::GetCheckItem() const
  942. {
  943. return m_bCheckItem;
  944. }
  945. void CMenuElementUI::SetShowExplandIcon(bool bShow)
  946. {
  947. m_bShowExplandIcon = bShow;
  948. }
  949. void CMenuElementUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  950. {
  951. if( _tcsicmp(pstrName, _T("icon")) == 0){
  952. SetIcon(pstrValue);
  953. }
  954. else if( _tcsicmp(pstrName, _T("iconsize")) == 0 ) {
  955. LPTSTR pstr = NULL;
  956. LONG cx = 0, cy = 0;
  957. cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  958. cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  959. SetIconSize(cx, cy);
  960. }
  961. else if( _tcsicmp(pstrName, _T("checkitem")) == 0 ) {
  962. SetCheckItem(_tcsicmp(pstrValue, _T("true")) == 0 ? true : false);
  963. }
  964. else if( _tcsicmp(pstrName, _T("ischeck")) == 0 ) {
  965. CStdStringPtrMap* mCheckInfos = CMenuWnd::GetGlobalContextMenuObserver().GetMenuCheckInfo();
  966. if (mCheckInfos != NULL)
  967. {
  968. bool bFind = false;
  969. for(int i = 0; i < mCheckInfos->GetSize(); i++) {
  970. MenuItemInfo* itemInfo = (MenuItemInfo*)mCheckInfos->GetAt(i);
  971. if(lstrcmpi(itemInfo->szName, GetName()) == 0) {
  972. bFind = true;
  973. break;
  974. }
  975. }
  976. if(!bFind) SetChecked(_tcsicmp(pstrValue, _T("true")) == 0 ? true : false);
  977. }
  978. }
  979. else if( _tcsicmp(pstrName, _T("linetype")) == 0){
  980. if (_tcsicmp(pstrValue, _T("true")) == 0)
  981. SetLineType();
  982. }
  983. else if( _tcsicmp(pstrName, _T("expland")) == 0 ) {
  984. SetShowExplandIcon(_tcsicmp(pstrValue, _T("true")) == 0 ? true : false);
  985. }
  986. else if( _tcsicmp(pstrName, _T("linecolor")) == 0){
  987. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  988. LPTSTR pstr = NULL;
  989. SetLineColor(_tcstoul(pstrValue, &pstr, 16));
  990. }
  991. else if( _tcsicmp(pstrName, _T("linepadding")) == 0 ) {
  992. RECT rcInset = { 0 };
  993. LPTSTR pstr = NULL;
  994. rcInset.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  995. rcInset.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  996. rcInset.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  997. rcInset.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  998. SetLinePadding(rcInset);
  999. }
  1000. else if ( _tcsicmp(pstrName, _T("height")) == 0){
  1001. SetFixedHeight(_ttoi(pstrValue));
  1002. }
  1003. else
  1004. CListContainerElementUI::SetAttribute(pstrName, pstrValue);
  1005. }
  1006. MenuItemInfo* CMenuElementUI::GetItemInfo(LPCTSTR pstrName)
  1007. {
  1008. if(pstrName == NULL || lstrlen(pstrName) <= 0) return NULL;
  1009. CStdStringPtrMap* mCheckInfos = CMenuWnd::GetGlobalContextMenuObserver().GetMenuCheckInfo();
  1010. if (mCheckInfos != NULL)
  1011. {
  1012. MenuItemInfo* pItemInfo = (MenuItemInfo*)mCheckInfos->Find(pstrName);
  1013. if(pItemInfo != NULL) {
  1014. return pItemInfo;
  1015. }
  1016. }
  1017. return NULL;
  1018. }
  1019. MenuItemInfo* CMenuElementUI::SetItemInfo(LPCTSTR pstrName, bool bChecked)
  1020. {
  1021. if(pstrName == NULL || lstrlen(pstrName) <= 0) return NULL;
  1022. CStdStringPtrMap* mCheckInfos = CMenuWnd::GetGlobalContextMenuObserver().GetMenuCheckInfo();
  1023. if (mCheckInfos != NULL)
  1024. {
  1025. MenuItemInfo* pItemInfo = (MenuItemInfo*)mCheckInfos->Find(pstrName);
  1026. if(pItemInfo == NULL) {
  1027. pItemInfo = new MenuItemInfo;
  1028. lstrcpy(pItemInfo->szName, pstrName);
  1029. pItemInfo->bChecked = bChecked;
  1030. mCheckInfos->Insert(pstrName, pItemInfo);
  1031. }
  1032. else {
  1033. pItemInfo->bChecked = bChecked;
  1034. }
  1035. return pItemInfo;
  1036. }
  1037. return NULL;
  1038. }
  1039. } // namespace DuiLib