UIMenu.cpp 34 KB

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