UIMenu.cpp 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216
  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. // 【抗锯齿圆角】菜单是独立 popup 窗口,无蒙版时绝不能继承 owner 的分层标志:
  297. // 无蒙版分层走「alpha==0 && RGB!=0 → 255」的补齐路径,纯黑文字(RGB=0)会变透明。
  298. // 菜单此前从未分层(owner 曾恒为非分层),保持 GDI 渲染不变 = 行为零变化。
  299. m_pm.SetLayered(false);
  300. m_pm.AttachDialog(m_pLayout);
  301. m_pm.AddNotifier(this);
  302. ResizeSubMenu();
  303. }
  304. else {
  305. m_pm.Init(m_hWnd);
  306. m_pm.GetDPIObj()->SetScale(CMenuWnd::GetGlobalContextMenuObserver().GetManager()->GetDPIObj()->GetDPI());
  307. CDialogBuilder builder;
  308. CControlUI* pRoot = builder.Create(m_xml,UINT(0), this, &m_pm);
  309. bShowShadow = m_pm.GetShadow()->IsShowShadow();
  310. m_pm.GetShadow()->ShowShadow(false);
  311. m_pm.AttachDialog(pRoot);
  312. m_pm.AddNotifier(this);
  313. ResizeMenu();
  314. }
  315. GetMenuUI()->m_pWindow = this;
  316. m_pm.GetShadow()->ShowShadow(bShowShadow);
  317. m_pm.GetShadow()->Create(&m_pm);
  318. return 0;
  319. }
  320. CMenuUI* CMenuWnd::GetMenuUI()
  321. {
  322. return static_cast<CMenuUI*>(m_pm.GetRoot());
  323. }
  324. void CMenuWnd::ResizeMenu()
  325. {
  326. CControlUI* pRoot = m_pm.GetRoot();
  327. #if defined(WIN32) && !defined(UNDER_CE)
  328. MONITORINFO oMonitor = {};
  329. oMonitor.cbSize = sizeof(oMonitor);
  330. ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
  331. CDuiRect rcWork = oMonitor.rcWork;
  332. #else
  333. CDuiRect rcWork;
  334. GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWork);
  335. #endif
  336. SIZE szAvailable = { rcWork.right - rcWork.left, rcWork.bottom - rcWork.top };
  337. szAvailable = pRoot->EstimateSize(szAvailable);
  338. m_pm.SetInitSize(szAvailable.cx, szAvailable.cy);
  339. //必须是Menu标签作为xml的根节点
  340. CMenuUI *pMenuRoot = static_cast<CMenuUI*>(pRoot);
  341. ASSERT(pMenuRoot);
  342. SIZE szInit = m_pm.GetInitSize();
  343. CDuiRect rc;
  344. CDuiPoint point = m_BasedPoint;
  345. rc.left = point.x;
  346. rc.top = point.y;
  347. rc.right = rc.left + szInit.cx;
  348. rc.bottom = rc.top + szInit.cy;
  349. int nWidth = rc.GetWidth();
  350. int nHeight = rc.GetHeight();
  351. if (m_dwAlignment & eMenuAlignment_Right)
  352. {
  353. rc.right = point.x;
  354. rc.left = rc.right - nWidth;
  355. }
  356. if (m_dwAlignment & eMenuAlignment_Bottom)
  357. {
  358. rc.bottom = point.y;
  359. rc.top = rc.bottom - nHeight;
  360. }
  361. SetForegroundWindow(m_hWnd);
  362. MoveWindow(m_hWnd, rc.left, rc.top, rc.GetWidth(), rc.GetHeight(), FALSE);
  363. SetWindowPos(m_hWnd, HWND_TOPMOST, rc.left, rc.top, rc.GetWidth(), rc.GetHeight() + pMenuRoot->GetInset().bottom + pMenuRoot->GetInset().top, SWP_SHOWWINDOW);
  364. }
  365. void CMenuWnd::ResizeSubMenu()
  366. {
  367. // Position the popup window in absolute space
  368. RECT rcOwner = m_pOwner->GetPos();
  369. RECT rc = rcOwner;
  370. int cxFixed = 0;
  371. int cyFixed = 0;
  372. #if defined(WIN32) && !defined(UNDER_CE)
  373. MONITORINFO oMonitor = {};
  374. oMonitor.cbSize = sizeof(oMonitor);
  375. ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor);
  376. CDuiRect rcWork = oMonitor.rcWork;
  377. #else
  378. CDuiRect rcWork;
  379. GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWork);
  380. #endif
  381. SIZE szAvailable = { rcWork.right - rcWork.left, rcWork.bottom - rcWork.top };
  382. for( int it = 0; it < m_pOwner->GetCount(); it++ ) {
  383. if(m_pOwner->GetItemAt(it)->GetInterface(_T("MenuElement")) != NULL ){
  384. CControlUI* pControl = static_cast<CControlUI*>(m_pOwner->GetItemAt(it));
  385. SIZE sz = pControl->EstimateSize(szAvailable);
  386. cyFixed += sz.cy;
  387. if( cxFixed < sz.cx ) cxFixed = sz.cx;
  388. }
  389. }
  390. RECT rcWindow;
  391. GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWindow);
  392. rc.top = rcOwner.top;
  393. rc.bottom = rc.top + cyFixed;
  394. ::MapWindowRect(m_pOwner->GetManager()->GetPaintWindow(), HWND_DESKTOP, &rc);
  395. rc.left = rcWindow.right;
  396. rc.right = rc.left + cxFixed;
  397. rc.right += 2;
  398. bool bReachBottom = false;
  399. bool bReachRight = false;
  400. LONG chRightAlgin = 0;
  401. LONG chBottomAlgin = 0;
  402. RECT rcPreWindow = {0};
  403. MenuObserverImpl::Iterator iterator(CMenuWnd::GetGlobalContextMenuObserver());
  404. MenuMenuReceiverImplBase* pReceiver = iterator.next();
  405. while( pReceiver != NULL ) {
  406. CMenuWnd* pContextMenu = dynamic_cast<CMenuWnd*>(pReceiver);
  407. if( pContextMenu != NULL ) {
  408. GetWindowRect(pContextMenu->GetHWND(), &rcPreWindow);
  409. bReachRight = rcPreWindow.left >= rcWindow.right;
  410. bReachBottom = rcPreWindow.top >= rcWindow.bottom;
  411. if( pContextMenu->GetHWND() == m_pOwner->GetManager()->GetPaintWindow() || bReachBottom || bReachRight )
  412. break;
  413. }
  414. pReceiver = iterator.next();
  415. }
  416. if (bReachBottom)
  417. {
  418. rc.bottom = rcWindow.top;
  419. rc.top = rc.bottom - cyFixed;
  420. }
  421. if (bReachRight)
  422. {
  423. rc.right = rcWindow.left;
  424. rc.left = rc.right - cxFixed;
  425. }
  426. if( rc.bottom > rcWork.bottom )
  427. {
  428. rc.bottom = rc.top;
  429. rc.top = rc.bottom - cyFixed;
  430. }
  431. if (rc.right > rcWork.right)
  432. {
  433. rc.right = rcWindow.left;
  434. rc.left = rc.right - cxFixed;
  435. }
  436. if( rc.top < rcWork.top )
  437. {
  438. rc.top = rcOwner.top;
  439. rc.bottom = rc.top + cyFixed;
  440. }
  441. if (rc.left < rcWork.left)
  442. {
  443. rc.left = rcWindow.right;
  444. rc.right = rc.left + cxFixed;
  445. }
  446. MoveWindow(m_hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top + m_pLayout->GetInset().top + m_pLayout->GetInset().bottom, FALSE);
  447. }
  448. void CMenuWnd::setDPI(int DPI) {
  449. m_pm.SetDPI(DPI);
  450. }
  451. LRESULT CMenuWnd::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  452. {
  453. HWND hFocusWnd = (HWND)wParam;
  454. BOOL bInMenuWindowList = FALSE;
  455. ContextMenuParam param;
  456. param.hWnd = GetHWND();
  457. MenuObserverImpl::Iterator iterator(CMenuWnd::GetGlobalContextMenuObserver());
  458. MenuMenuReceiverImplBase* pReceiver = iterator.next();
  459. while( pReceiver != NULL ) {
  460. CMenuWnd* pContextMenu = dynamic_cast<CMenuWnd*>(pReceiver);
  461. if( pContextMenu != NULL && pContextMenu->GetHWND() == hFocusWnd ) {
  462. bInMenuWindowList = TRUE;
  463. break;
  464. }
  465. pReceiver = iterator.next();
  466. }
  467. if( !bInMenuWindowList ) {
  468. param.wParam = 1;
  469. CMenuWnd::GetGlobalContextMenuObserver().RBroadcast(param);
  470. return 0;
  471. }
  472. return 0;
  473. }
  474. LRESULT CMenuWnd::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  475. {
  476. SIZE szRoundCorner = m_pm.GetRoundCorner();
  477. if( !::IsIconic(*this) ) {
  478. CDuiRect rcWnd;
  479. ::GetWindowRect(*this, &rcWnd);
  480. rcWnd.Offset(-rcWnd.left, -rcWnd.top);
  481. rcWnd.right++; rcWnd.bottom++;
  482. HRGN hRgn = ::CreateRoundRectRgn(rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom, szRoundCorner.cx, szRoundCorner.cy);
  483. ::SetWindowRgn(*this, hRgn, TRUE);
  484. ::DeleteObject(hRgn);
  485. }
  486. bHandled = FALSE;
  487. return 0;
  488. }
  489. LRESULT CMenuWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  490. {
  491. LRESULT lRes = 0;
  492. BOOL bHandled = TRUE;
  493. switch( uMsg )
  494. {
  495. case WM_CREATE:
  496. lRes = OnCreate(uMsg, wParam, lParam, bHandled);
  497. break;
  498. case WM_KILLFOCUS:
  499. lRes = OnKillFocus(uMsg, wParam, lParam, bHandled);
  500. break;
  501. case WM_KEYDOWN:
  502. if( wParam == VK_ESCAPE || wParam == VK_LEFT)
  503. Close();
  504. break;
  505. case WM_SIZE:
  506. lRes = OnSize(uMsg, wParam, lParam, bHandled);
  507. break;
  508. case WM_CLOSE:
  509. if( m_pOwner != NULL )
  510. {
  511. m_pOwner->SetManager(m_pOwner->GetManager(), m_pOwner->GetParent(), false);
  512. m_pOwner->SetPos(m_pOwner->GetPos());
  513. m_pOwner->SetFocus();
  514. }
  515. break;
  516. case WM_CONTEXTMENU:
  517. case WM_RBUTTONUP:
  518. if(m_bCaptured) {
  519. m_bCaptured = false;
  520. ReleaseCapture();
  521. if( m_pOwner != NULL )
  522. {
  523. m_pOwner->SetManager(m_pOwner->GetManager(), m_pOwner->GetParent(), false);
  524. m_pOwner->SetPos(m_pOwner->GetPos());
  525. m_pOwner->SetFocus();
  526. }
  527. }
  528. break;
  529. case WM_RBUTTONDOWN:
  530. case WM_RBUTTONDBLCLK:
  531. m_bCaptured = true;
  532. SetCapture(m_hWnd);
  533. return 0L;
  534. default:
  535. bHandled = FALSE;
  536. break;
  537. }
  538. if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes;
  539. return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
  540. }
  541. /////////////////////////////////////////////////////////////////////////////////////
  542. //
  543. IMPLEMENT_DUICONTROL(CMenuElementUI)
  544. CMenuElementUI::CMenuElementUI():
  545. m_pWindow(NULL),
  546. m_bDrawLine(false),
  547. m_dwLineColor((DWORD)DEFAULT_LINE_COLOR),
  548. m_bCheckItem(false),
  549. m_bShowExplandIcon(false)
  550. {
  551. m_cxyFixed.cy = ITEM_DEFAULT_HEIGHT;
  552. m_cxyFixed.cx = ITEM_DEFAULT_WIDTH;
  553. m_szIconSize.cy = ITEM_DEFAULT_ICON_SIZE;
  554. m_szIconSize.cx = ITEM_DEFAULT_ICON_SIZE;
  555. m_rcLinePadding.top = m_rcLinePadding.bottom = 0;
  556. m_rcLinePadding.left = DEFAULT_LINE_LEFT_INSET;
  557. m_rcLinePadding.right = DEFAULT_LINE_RIGHT_INSET;
  558. }
  559. CMenuElementUI::~CMenuElementUI()
  560. {}
  561. LPCTSTR CMenuElementUI::GetClass() const
  562. {
  563. return _T("MenuElementUI");
  564. }
  565. LPVOID CMenuElementUI::GetInterface(LPCTSTR pstrName)
  566. {
  567. if( _tcsicmp(pstrName, _T("MenuElement")) == 0 ) return static_cast<CMenuElementUI*>(this);
  568. return CListContainerElementUI::GetInterface(pstrName);
  569. }
  570. bool CMenuElementUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
  571. {
  572. SIZE cxyFixed = GetFixedSize();
  573. RECT rcLinePadding = GetLinePadding();
  574. RECT rcTemp = { 0 };
  575. if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return true;
  576. if(m_bDrawLine)
  577. {
  578. RECT rcLine = { m_rcItem.left + rcLinePadding.left, m_rcItem.top + cxyFixed.cy/2, m_rcItem.right - rcLinePadding.right, m_rcItem.top + cxyFixed.cy/2 };
  579. CRenderEngine::DrawLine(hDC, rcLine, 1, m_dwLineColor);
  580. }
  581. else
  582. {
  583. CRenderClip clip;
  584. CRenderClip::GenerateClip(hDC, rcTemp, clip);
  585. CMenuElementUI::DrawItemBk(hDC, m_rcItem);
  586. DrawItemText(hDC, m_rcItem);
  587. DrawItemIcon(hDC, m_rcItem);
  588. DrawItemExpland(hDC, m_rcItem);
  589. if( m_items.GetSize() > 0 ) {
  590. RECT rc = m_rcItem;
  591. RECT rcInset = GetInset();
  592. rc.left += rcInset.left;
  593. rc.top += rcInset.top;
  594. rc.right -= rcInset.right;
  595. rc.bottom -= rcInset.bottom;
  596. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  597. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  598. if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) {
  599. for( int it = 0; it < m_items.GetSize(); it++ ) {
  600. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  601. if( pControl == pStopControl ) return false;
  602. if( !pControl->IsVisible() ) continue;
  603. if( pControl->GetInterface(_T("MenuElement")) != NULL ) continue;
  604. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  605. if( pControl->IsFloat() ) {
  606. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  607. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  608. }
  609. }
  610. }
  611. else {
  612. CRenderClip childClip;
  613. CRenderClip::GenerateClip(hDC, rcTemp, childClip);
  614. for( int it = 0; it < m_items.GetSize(); it++ ) {
  615. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  616. if( pControl == pStopControl ) return false;
  617. if( !pControl->IsVisible() ) continue;
  618. if( pControl->GetInterface(_T("MenuElement")) != NULL ) continue;
  619. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  620. if( pControl->IsFloat() ) {
  621. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  622. CRenderClip::UseOldClipBegin(hDC, childClip);
  623. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  624. CRenderClip::UseOldClipEnd(hDC, childClip);
  625. }
  626. else {
  627. if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue;
  628. if( !pControl->Paint(hDC, rcPaint, pStopControl) ) return false;
  629. }
  630. }
  631. }
  632. }
  633. }
  634. if( m_pVerticalScrollBar != NULL ) {
  635. if( m_pVerticalScrollBar == pStopControl ) return false;
  636. if (m_pVerticalScrollBar->IsVisible()) {
  637. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) {
  638. if( !m_pVerticalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false;
  639. }
  640. }
  641. }
  642. if( m_pHorizontalScrollBar != NULL ) {
  643. if( m_pHorizontalScrollBar == pStopControl ) return false;
  644. if (m_pHorizontalScrollBar->IsVisible()) {
  645. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) {
  646. if( !m_pHorizontalScrollBar->Paint(hDC, rcPaint, pStopControl) ) return false;
  647. }
  648. }
  649. }
  650. return true;
  651. }
  652. void CMenuElementUI::DrawItemIcon(HDC hDC, const RECT& rcItem)
  653. {
  654. if (!m_strIcon.IsEmpty() && !(m_bCheckItem && !GetChecked())) {
  655. SIZE cxyFixed = GetFixedSize();
  656. SIZE szIconSize = GetIconSize();
  657. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  658. RECT rcTextPadding = GetManager()->GetDPIObj()->Scale(pInfo->rcTextPadding);
  659. RECT rcDest =
  660. {
  661. (rcTextPadding.left - szIconSize.cx) / 2,
  662. (cxyFixed.cy - szIconSize.cy) / 2,
  663. (rcTextPadding.left - szIconSize.cx) / 2 + szIconSize.cx,
  664. (cxyFixed.cy - szIconSize.cy) / 2 + szIconSize.cy
  665. };
  666. CDuiString pStrImage;
  667. pStrImage.Format(_T("dest='%d,%d,%d,%d'"), rcDest.left, rcDest.top, rcDest.right, rcDest.bottom);
  668. DrawImage(hDC, m_strIcon, pStrImage);
  669. }
  670. }
  671. void CMenuElementUI::DrawItemExpland(HDC hDC, const RECT& rcItem)
  672. {
  673. if (m_bShowExplandIcon) {
  674. CDuiString strExplandIcon;
  675. strExplandIcon = GetManager()->GetDefaultAttributeList(_T("ExplandIcon"));
  676. if (strExplandIcon.IsEmpty()) {
  677. return;
  678. }
  679. SIZE cxyFixed = GetManager()->GetDPIObj()->Scale(m_cxyFixed);
  680. int padding = GetManager()->GetDPIObj()->Scale(ITEM_DEFAULT_EXPLAND_ICON_WIDTH) / 3;
  681. const TDrawInfo* pDrawInfo = GetManager()->GetDrawInfo((LPCTSTR)strExplandIcon, NULL);
  682. const TImageInfo *pImageInfo = GetManager()->GetImageEx(pDrawInfo->sImageName, NULL, 0, false, pDrawInfo->bGdiplus);
  683. if (!pImageInfo) {
  684. return;
  685. }
  686. RECT rcDest =
  687. {
  688. cxyFixed.cx - pImageInfo->nX - padding,
  689. (cxyFixed.cy - pImageInfo->nY) / 2,
  690. cxyFixed.cx - pImageInfo->nX - padding + pImageInfo->nX,
  691. (cxyFixed.cy - pImageInfo->nY) / 2 + pImageInfo->nY
  692. };
  693. GetManager()->GetDPIObj()->ScaleBack(&rcDest);
  694. CDuiString pStrImage;
  695. pStrImage.Format(_T("dest='%d,%d,%d,%d'"), rcDest.left, rcDest.top, rcDest.right, rcDest.bottom);
  696. DrawImage(hDC, strExplandIcon, pStrImage);
  697. }
  698. }
  699. void CMenuElementUI::DrawItemText(HDC hDC, const RECT& rcItem)
  700. {
  701. CDuiString sText = GetText();
  702. if( sText.IsEmpty() ) return;
  703. if( m_pOwner == NULL ) return;
  704. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  705. DWORD iTextColor = pInfo->dwTextColor;
  706. if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  707. iTextColor = pInfo->dwHotTextColor;
  708. }
  709. if( IsSelected() ) {
  710. iTextColor = pInfo->dwSelectedTextColor;
  711. }
  712. if( !IsEnabled() ) {
  713. iTextColor = pInfo->dwDisabledTextColor;
  714. }
  715. int nLinks = 0;
  716. RECT rcText = rcItem;
  717. RECT rcTextPadding = GetManager()->GetDPIObj()->Scale(pInfo->rcTextPadding);
  718. rcText.left += rcTextPadding.left;
  719. rcText.right -= rcTextPadding.right;
  720. rcText.top += rcTextPadding.top;
  721. rcText.bottom -= rcTextPadding.bottom;
  722. if( pInfo->bShowHtml )
  723. CRenderEngine::DrawHtmlText(hDC, m_pManager, rcText, sText, iTextColor, \
  724. NULL, NULL, nLinks, pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle);
  725. else
  726. CRenderEngine::DrawText(hDC, m_pManager, rcText, sText, iTextColor, \
  727. pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle);
  728. }
  729. SIZE CMenuElementUI::EstimateSize(SIZE szAvailable)
  730. {
  731. SIZE cxyFixed = GetManager()->GetDPIObj()->Scale(m_cxyFixed);
  732. SIZE cXY = {0};
  733. for( int it = 0; it < GetCount(); it++ ) {
  734. CControlUI* pControl = static_cast<CControlUI*>(GetItemAt(it));
  735. if( !pControl->IsVisible() ) continue;
  736. SIZE sz = pControl->EstimateSize(szAvailable);
  737. cXY.cy += sz.cy;
  738. if( cXY.cx < sz.cx ) cXY.cx = sz.cx;
  739. }
  740. if(cXY.cy == 0) {
  741. CDuiString sText = GetText();
  742. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  743. DWORD iTextColor = pInfo->dwTextColor;
  744. RECT rcText = { 0, 0, MAX(szAvailable.cx, m_cxyFixed.cx), 9999 };
  745. RECT rcTextPadding = GetManager()->GetDPIObj()->Scale(pInfo->rcTextPadding);
  746. rcText.left += rcTextPadding.left;
  747. rcText.right -= rcTextPadding.right;
  748. if( pInfo->bShowHtml ) {
  749. int nLinks = 0;
  750. CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, sText, iTextColor, NULL, NULL, nLinks, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle);
  751. }
  752. else {
  753. CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, sText, iTextColor, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle);
  754. }
  755. cXY.cx = rcText.right - rcText.left + rcTextPadding.left + rcTextPadding.right ;
  756. cXY.cy = rcText.bottom - rcText.top + rcTextPadding.top + rcTextPadding.bottom;
  757. }
  758. if( cxyFixed.cy != 0 ) cXY.cy = cxyFixed.cy;
  759. if ( cXY.cx < m_cxyFixed.cx )
  760. cXY.cx = m_cxyFixed.cx;
  761. return cXY;
  762. }
  763. void CMenuElementUI::DoEvent(TEventUI& event)
  764. {
  765. if( event.Type == UIEVENT_MOUSEENTER )
  766. {
  767. CListContainerElementUI::DoEvent(event);
  768. if( m_pWindow ) return;
  769. bool hasSubMenu = false;
  770. for( int i = 0; i < GetCount(); ++i )
  771. {
  772. if( GetItemAt(i)->GetInterface(_T("MenuElement")) != NULL )
  773. {
  774. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetVisible(true);
  775. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetInternVisible(true);
  776. hasSubMenu = true;
  777. }
  778. }
  779. if( hasSubMenu )
  780. {
  781. m_pOwner->SelectItem(GetIndex(), true);
  782. CreateMenuWnd();
  783. }
  784. else
  785. {
  786. ContextMenuParam param;
  787. param.hWnd = m_pManager->GetPaintWindow();
  788. param.wParam = 2;
  789. CMenuWnd::GetGlobalContextMenuObserver().RBroadcast(param);
  790. m_pOwner->SelectItem(GetIndex(), true);
  791. }
  792. return;
  793. }
  794. if (event.Type == UIEVENT_MOUSELEAVE) {
  795. bool hasSubMenu = false;
  796. for (int i = 0; i < GetCount(); ++i)
  797. {
  798. if (GetItemAt(i)->GetInterface(_T("MenuElement")) != NULL)
  799. {
  800. hasSubMenu = true;
  801. }
  802. }
  803. if (!hasSubMenu) {
  804. m_pOwner->SelectItem(-1, true);
  805. }
  806. }
  807. if( event.Type == UIEVENT_BUTTONUP )
  808. {
  809. if( IsEnabled() ){
  810. CListContainerElementUI::DoEvent(event);
  811. if( m_pWindow ) return;
  812. bool hasSubMenu = false;
  813. for( int i = 0; i < GetCount(); ++i ) {
  814. if( GetItemAt(i)->GetInterface(_T("MenuElement")) != NULL ) {
  815. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetVisible(true);
  816. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetInternVisible(true);
  817. hasSubMenu = true;
  818. }
  819. }
  820. if( hasSubMenu )
  821. {
  822. CreateMenuWnd();
  823. }
  824. else
  825. {
  826. SetChecked(!GetChecked());
  827. bool isClosing = false;
  828. CMenuUI* menuUI=static_cast<CMenuUI*>(GetManager()->GetRoot());
  829. isClosing = (menuUI->m_pWindow->isClosing);
  830. if (IsWindow(GetManager()->GetPaintWindow()) && !isClosing) {
  831. if (CMenuWnd::GetGlobalContextMenuObserver().GetManager() != NULL) {
  832. MenuCmd* pMenuCmd = new MenuCmd();
  833. lstrcpy(pMenuCmd->szName, GetName().GetData());
  834. lstrcpy(pMenuCmd->szUserData, GetUserData().GetData());
  835. lstrcpy(pMenuCmd->szText, GetText().GetData());
  836. pMenuCmd->bChecked = GetChecked();
  837. if (!PostMessage(CMenuWnd::GetGlobalContextMenuObserver().GetManager()->GetPaintWindow(), WM_MENUCLICK, (WPARAM)pMenuCmd, (LPARAM)this)) {
  838. delete pMenuCmd;
  839. pMenuCmd = NULL;
  840. }
  841. }
  842. }
  843. ContextMenuParam param;
  844. param.hWnd = m_pManager->GetPaintWindow();
  845. param.wParam = 1;
  846. CMenuWnd::GetGlobalContextMenuObserver().RBroadcast(param);
  847. }
  848. }
  849. return;
  850. }
  851. if ( event.Type == UIEVENT_KEYDOWN && event.chKey == VK_RIGHT )
  852. {
  853. if( m_pWindow ) return;
  854. bool hasSubMenu = false;
  855. for( int i = 0; i < GetCount(); ++i ) {
  856. if( GetItemAt(i)->GetInterface(_T("MenuElement")) != NULL ) {
  857. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetVisible(true);
  858. (static_cast<CMenuElementUI*>(GetItemAt(i)->GetInterface(_T("MenuElement"))))->SetInternVisible(true);
  859. hasSubMenu = true;
  860. }
  861. }
  862. if( hasSubMenu ) {
  863. m_pOwner->SelectItem(GetIndex(), true);
  864. CreateMenuWnd();
  865. }
  866. else
  867. {
  868. ContextMenuParam param;
  869. param.hWnd = m_pManager->GetPaintWindow();
  870. param.wParam = 2;
  871. CMenuWnd::GetGlobalContextMenuObserver().RBroadcast(param);
  872. m_pOwner->SelectItem(GetIndex(), true);
  873. }
  874. return;
  875. }
  876. CListContainerElementUI::DoEvent(event);
  877. }
  878. CMenuWnd* CMenuElementUI::GetMenuWnd()
  879. {
  880. return m_pWindow;
  881. }
  882. void CMenuElementUI::CreateMenuWnd()
  883. {
  884. if( m_pWindow ) return;
  885. m_pWindow = new CMenuWnd();
  886. ASSERT(m_pWindow);
  887. ContextMenuParam param;
  888. param.hWnd = m_pManager->GetPaintWindow();
  889. param.wParam = 2;
  890. CMenuWnd::GetGlobalContextMenuObserver().RBroadcast(param);
  891. m_pWindow->Init(static_cast<CMenuElementUI*>(this), _T(""), CDuiPoint(), NULL);
  892. }
  893. void CMenuElementUI::SetLineType()
  894. {
  895. m_bDrawLine = true;
  896. if (m_cxyFixed.cy == 0 || m_cxyFixed.cy == ITEM_DEFAULT_HEIGHT)
  897. SetFixedHeight(DEFAULT_LINE_HEIGHT);
  898. SetMouseChildEnabled(false);
  899. SetMouseEnabled(false);
  900. SetEnabled(false);
  901. }
  902. void CMenuElementUI::SetLineColor(DWORD color)
  903. {
  904. m_dwLineColor = color;
  905. }
  906. DWORD CMenuElementUI::GetLineColor() const
  907. {
  908. return m_dwLineColor;
  909. }
  910. void CMenuElementUI::SetLinePadding(RECT rcPadding)
  911. {
  912. m_rcLinePadding = rcPadding;
  913. }
  914. RECT CMenuElementUI::GetLinePadding() const
  915. {
  916. RECT rcLinePadding = m_rcLinePadding;
  917. if(m_pManager != NULL) m_pManager->GetDPIObj()->Scale(&rcLinePadding);
  918. return rcLinePadding;
  919. }
  920. void CMenuElementUI::SetIcon(LPCTSTR strIcon)
  921. {
  922. m_strIcon = strIcon;
  923. }
  924. void CMenuElementUI::SetIconSize(LONG cx, LONG cy)
  925. {
  926. m_szIconSize.cx = cx;
  927. m_szIconSize.cy = cy;
  928. }
  929. SIZE CMenuElementUI::GetIconSize()
  930. {
  931. SIZE szIconSize = m_szIconSize;
  932. if(m_pManager != NULL) m_pManager->GetDPIObj()->Scale(&szIconSize);
  933. return szIconSize;
  934. }
  935. void CMenuElementUI::SetChecked(bool bCheck/* = true*/)
  936. {
  937. SetItemInfo(GetName(), bCheck);
  938. }
  939. bool CMenuElementUI::GetChecked() const
  940. {
  941. LPCTSTR pstrName = GetName();
  942. if(pstrName == NULL || lstrlen(pstrName) <= 0) return false;
  943. CStdStringPtrMap* mCheckInfos = CMenuWnd::GetGlobalContextMenuObserver().GetMenuCheckInfo();
  944. if (mCheckInfos != NULL)
  945. {
  946. MenuItemInfo* pItemInfo = (MenuItemInfo*)mCheckInfos->Find(pstrName);
  947. if(pItemInfo != NULL) {
  948. return pItemInfo->bChecked;
  949. }
  950. }
  951. return false;
  952. }
  953. void CMenuElementUI::SetCheckItem(bool bCheckItem/* = false*/)
  954. {
  955. m_bCheckItem = bCheckItem;
  956. }
  957. bool CMenuElementUI::GetCheckItem() const
  958. {
  959. return m_bCheckItem;
  960. }
  961. void CMenuElementUI::SetShowExplandIcon(bool bShow)
  962. {
  963. m_bShowExplandIcon = bShow;
  964. }
  965. void CMenuElementUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  966. {
  967. if( _tcsicmp(pstrName, _T("icon")) == 0){
  968. SetIcon(pstrValue);
  969. }
  970. else if( _tcsicmp(pstrName, _T("iconsize")) == 0 ) {
  971. LPTSTR pstr = NULL;
  972. LONG cx = 0, cy = 0;
  973. cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  974. cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  975. SetIconSize(cx, cy);
  976. }
  977. else if( _tcsicmp(pstrName, _T("checkitem")) == 0 ) {
  978. SetCheckItem(_tcsicmp(pstrValue, _T("true")) == 0 ? true : false);
  979. }
  980. else if( _tcsicmp(pstrName, _T("ischeck")) == 0 ) {
  981. CStdStringPtrMap* mCheckInfos = CMenuWnd::GetGlobalContextMenuObserver().GetMenuCheckInfo();
  982. if (mCheckInfos != NULL)
  983. {
  984. bool bFind = false;
  985. for(int i = 0; i < mCheckInfos->GetSize(); i++) {
  986. MenuItemInfo* itemInfo = (MenuItemInfo*)mCheckInfos->GetAt(i);
  987. if(lstrcmpi(itemInfo->szName, GetName()) == 0) {
  988. bFind = true;
  989. break;
  990. }
  991. }
  992. if(!bFind) SetChecked(_tcsicmp(pstrValue, _T("true")) == 0 ? true : false);
  993. }
  994. }
  995. else if( _tcsicmp(pstrName, _T("linetype")) == 0){
  996. if (_tcsicmp(pstrValue, _T("true")) == 0)
  997. SetLineType();
  998. }
  999. else if( _tcsicmp(pstrName, _T("expland")) == 0 ) {
  1000. SetShowExplandIcon(_tcsicmp(pstrValue, _T("true")) == 0 ? true : false);
  1001. }
  1002. else if( _tcsicmp(pstrName, _T("linecolor")) == 0){
  1003. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1004. LPTSTR pstr = NULL;
  1005. SetLineColor(_tcstoul(pstrValue, &pstr, 16));
  1006. }
  1007. else if( _tcsicmp(pstrName, _T("linepadding")) == 0 ) {
  1008. RECT rcInset = { 0 };
  1009. LPTSTR pstr = NULL;
  1010. rcInset.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  1011. rcInset.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  1012. rcInset.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  1013. rcInset.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  1014. SetLinePadding(rcInset);
  1015. }
  1016. else if ( _tcsicmp(pstrName, _T("height")) == 0){
  1017. SetFixedHeight(_ttoi(pstrValue));
  1018. }
  1019. else
  1020. CListContainerElementUI::SetAttribute(pstrName, pstrValue);
  1021. }
  1022. MenuItemInfo* CMenuElementUI::GetItemInfo(LPCTSTR pstrName)
  1023. {
  1024. if(pstrName == NULL || lstrlen(pstrName) <= 0) return NULL;
  1025. CStdStringPtrMap* mCheckInfos = CMenuWnd::GetGlobalContextMenuObserver().GetMenuCheckInfo();
  1026. if (mCheckInfos != NULL)
  1027. {
  1028. MenuItemInfo* pItemInfo = (MenuItemInfo*)mCheckInfos->Find(pstrName);
  1029. if(pItemInfo != NULL) {
  1030. return pItemInfo;
  1031. }
  1032. }
  1033. return NULL;
  1034. }
  1035. MenuItemInfo* CMenuElementUI::SetItemInfo(LPCTSTR pstrName, bool bChecked)
  1036. {
  1037. if(pstrName == NULL || lstrlen(pstrName) <= 0) return NULL;
  1038. CStdStringPtrMap* mCheckInfos = CMenuWnd::GetGlobalContextMenuObserver().GetMenuCheckInfo();
  1039. if (mCheckInfos != NULL)
  1040. {
  1041. MenuItemInfo* pItemInfo = (MenuItemInfo*)mCheckInfos->Find(pstrName);
  1042. if(pItemInfo == NULL) {
  1043. pItemInfo = new MenuItemInfo;
  1044. lstrcpy(pItemInfo->szName, pstrName);
  1045. pItemInfo->bChecked = bChecked;
  1046. mCheckInfos->Insert(pstrName, pItemInfo);
  1047. }
  1048. else {
  1049. pItemInfo->bChecked = bChecked;
  1050. }
  1051. return pItemInfo;
  1052. }
  1053. return NULL;
  1054. }
  1055. } // namespace DuiLib