UIMenu.cpp 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  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