soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SMenu.cpp
1#include "souistd.h"
2#include "SApp.h"
3#include "helper/SMenu.h"
4#include "helper/SplitString.h"
5#include "gdialpha.h"
6#include <souicoll.h>
7
8SNSBEGIN
9
11 : iIcon(-1)
12 , vHotKey(0)
13 , dwUserData(0)
14 , hIcon(NULL)
15{
16}
17
19{
20 if (hIcon)
21 DestroyIcon(hIcon);
22}
23
24//////////////////////////////////////////////////////////////////////////
25
27 : m_pItemSkin(GETBUILTINSKIN(SKIN_SYS_MENU_SKIN))
28 , m_pSepSkin(GETBUILTINSKIN(SKIN_SYS_MENU_SEP))
29 , m_pCheckSkin(GETBUILTINSKIN(SKIN_SYS_MENU_CHECK))
30 , m_pIconSkin(NULL)
31 , m_nItemHei(25, SLayoutSize::defUnit)
32 , m_nMaxWidth(250, SLayoutSize::defUnit)
33 , m_nIconMargin(2, SLayoutSize::defUnit)
34 , m_nTextMargin(5, SLayoutSize::defUnit)
35 , m_scale(100)
36{
37 m_szIcon[0].setSize(CX_ICON, SLayoutSize::defUnit);
38 m_szIcon[1].setSize(CY_ICON, SLayoutSize::defUnit);
39
40 m_crTxtNormal = GetSysColor(COLOR_MENUTEXT) | 0xff000000;
41 m_crTxtSel = GetSysColor(COLOR_HIGHLIGHTTEXT) | 0xff000000;
42 m_crTxtGray = GetSysColor(COLOR_GRAYTEXT) | 0xff000000;
43}
44
48
50{
51 return m_nTextMargin.toPixelSize(m_scale);
52}
53
55{
56 return m_nIconMargin.toPixelSize(m_scale);
57}
58
60{
61 return CSize(m_szIcon[0].toPixelSize(m_scale), m_szIcon[1].toPixelSize(m_scale));
62}
63
65{
66 return m_nItemHei.toPixelSize(m_scale);
67}
68
70{
71 if (m_nMaxWidth.isValid())
72 return m_nMaxWidth.toPixelSize(m_scale);
73 return -1;
74}
75
77{
78 if (!m_nItemHei.isValid())
79 {
80 if (m_pItemSkin)
81 m_nItemHei.setSize((float)m_pItemSkin->GetSkinSize().cy, SLayoutSize::dp);
82 else
83 m_nItemHei.setSize(30, SLayoutSize::dp);
84 }
85}
86
88{
89 SAutoRefPtr<IFontS> font = m_dpiFont.GetFontPtr();
90 if (font)
91 return font;
92 return GETUIDEF->GetFont(FF_DEFAULTFONT, m_scale);
93}
94
95void SMenuAttr::SetScale(int scale)
96{
97 if (m_scale == scale)
98 return;
99 m_scale = scale;
100 m_dpiFont.UpdateFont(m_scale);
101 if (m_pIconSkin)
102 m_pIconSkin = GETSKIN(m_pIconSkin->GetName(), m_scale);
103 if (m_pItemSkin)
104 m_pItemSkin = GETSKIN(m_pItemSkin->GetName(), m_scale);
105 if (m_pSepSkin)
106 m_pSepSkin = GETSKIN(m_pSepSkin->GetName(), m_scale);
107 if (m_pCheckSkin)
108 m_pCheckSkin = GETSKIN(m_pCheckSkin->GetName(), m_scale);
109}
110
111//////////////////////////////////////////////////////////////////////////
112
113SMenuODWnd::SMenuODWnd(HWND hMenuOwner, SMenuAttr *pMenuAttr)
114 : m_hMenuOwner(hMenuOwner)
115 , m_attr(pMenuAttr)
116{
117}
118
122
124{
125 ::SendMessage(m_hMenuOwner, WM_INITMENU, (WPARAM)menu, 0);
126}
127
128void SMenuODWnd::OnInitMenuPopup(HMENU menuPopup, UINT nIndex, BOOL bSysMenu)
129{
130 ::SendMessage(m_hMenuOwner, WM_INITMENUPOPUP, (WPARAM)menuPopup, MAKELPARAM(nIndex, bSysMenu));
131}
132
133void SMenuODWnd::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
134{
135 CRect rcItem = lpDrawItemStruct->rcItem;
136 rcItem.MoveToXY(0, 0);
137 SMenuItemData *pdmmi = (SMenuItemData *)lpDrawItemStruct->itemData;
138
139 HDC dc(lpDrawItemStruct->hDC);
141 GETRENDERFACTORY->CreateRenderTarget(&pRT, rcItem.Width(), rcItem.Height());
142 pRT->BeginDraw();
143 if (pdmmi)
144 {
145 MENUITEMINFO mii = { sizeof(MENUITEMINFO), MIIM_FTYPE, 0 };
146 GetMenuItemInfo((HMENU)lpDrawItemStruct->hwndItem, lpDrawItemStruct->itemID, FALSE, &mii);
147
148 BOOL bDisabled = lpDrawItemStruct->itemState & ODS_GRAYED;
149 BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED;
150 BOOL bChecked = lpDrawItemStruct->itemState & ODS_CHECKED;
151 BOOL bRadio = mii.fType & MFT_RADIOCHECK;
152 m_attr->m_pItemSkin->DrawByIndex(pRT, rcItem, bSelected ? 1 : 0); // draw background
153
154 // draw icon
155 CRect rcIcon;
156 int iconOffset = m_attr->GetIconMargin();
157
158 rcIcon.left = rcItem.left + iconOffset;
159 CSize szIcon = m_attr->GetIconSize();
160 rcIcon.right = rcIcon.left + szIcon.cx;
161 rcIcon.top = rcItem.top + (rcItem.Height() - szIcon.cy) / 2;
162 rcIcon.bottom = rcIcon.top + szIcon.cy;
163 if (bChecked)
164 {
165 if (m_attr->m_pCheckSkin)
166 {
167 m_attr->m_pCheckSkin->DrawByIndex(pRT, rcIcon, bRadio ? 1 : 0);
168 }
169 }
170 else if (pdmmi->hIcon)
171 {
172 pRT->DrawIconEx(rcIcon.left, rcIcon.top, pdmmi->hIcon, rcIcon.Width(), rcIcon.Height(), DI_NORMAL);
173 }
174 else if (pdmmi->iIcon != -1 && m_attr->m_pIconSkin)
175 {
176 m_attr->m_pIconSkin->DrawByIndex(pRT, rcIcon, pdmmi->iIcon);
177 }
178 rcItem.left = rcIcon.right + iconOffset;
179
180 // draw text
181 CRect rcTxt = rcItem;
182 rcTxt.DeflateRect(m_attr->GetTextMargin(), 0);
183
184 COLORREF crOld = pRT->SetTextColor(bDisabled ? m_attr->m_crTxtGray : (bSelected ? m_attr->m_crTxtSel : m_attr->m_crTxtNormal));
185
186 SAutoRefPtr<IFontS> oldFont;
187 pRT->SelectObject(m_attr->GetFontPtr(), (IRenderObj **)&oldFont);
188 SStringT strLeft, strRight;
189 int pos = pdmmi->strText.ReverseFind('\t');
190 if (pos != -1)
191 {
192 const int kArrowSize = 14; // arrow width.
193 rcTxt.right -= kArrowSize * m_attr->GetScale() / 100;
194 strLeft = pdmmi->strText.Left(pos);
195 strRight = pdmmi->strText.Mid(pos + 1);
196 pRT->DrawText(strLeft, strLeft.GetLength(), &rcTxt, DT_SINGLELINE | DT_VCENTER | DT_LEFT | DT_END_ELLIPSIS);
197 pRT->DrawText(strRight, strRight.GetLength(), &rcTxt, DT_SINGLELINE | DT_VCENTER | DT_RIGHT | DT_END_ELLIPSIS);
198 }
199 else
200 {
201 pRT->DrawText(pdmmi->strText, pdmmi->strText.GetLength(), &rcTxt, DT_SINGLELINE | DT_VCENTER | DT_LEFT | DT_END_ELLIPSIS);
202 }
203 pRT->SelectObject(oldFont, NULL);
204
205 pRT->SetTextColor(crOld);
206
207 if (bSelected && m_attr->m_pItemSkin->GetStates() > 2)
208 {
209 // draw select mask
210 CRect rcItem = lpDrawItemStruct->rcItem;
211 rcItem.MoveToXY(0, 0);
212 m_attr->m_pItemSkin->DrawByIndex(pRT, rcItem, 2);
213 }
214 }
215 else // if(strcmp("sep",pXmlItem->Value())==0)
216 {
217 if (m_attr->m_pSepSkin)
218 m_attr->m_pSepSkin->DrawByIndex(pRT, rcItem, 0); // draw seperator
219 }
220 rcItem = lpDrawItemStruct->rcItem;
221
222 pRT->EndDraw();
223 HDC hmemdc = pRT->GetDC(0);
224 BitBlt(dc, rcItem.left, rcItem.top, rcItem.Width(), rcItem.Height(), hmemdc, 0, 0, SRCCOPY);
225 pRT->ReleaseDC(hmemdc, &rcItem);
226}
227
228void SMenuODWnd::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
229{
230 if (lpMeasureItemStruct->CtlType != ODT_MENU)
231 return;
232
233 SMenuItemData *pdmmi = (SMenuItemData *)lpMeasureItemStruct->itemData;
234 if (pdmmi)
235 {
236 // menu item
237 lpMeasureItemStruct->itemHeight = m_attr->GetItemHeight();
238 lpMeasureItemStruct->itemWidth = m_attr->GetIconSize().cx + m_attr->GetIconMargin() * 2;
239
241 GETRENDERFACTORY->CreateRenderTarget(&pRT, 0, 0);
242 SAutoRefPtr<IFontS> oldFont;
243 pRT->SelectObject(m_attr->GetFontPtr(), (IRenderObj **)&oldFont);
244 SIZE szTxt;
245 pRT->MeasureText(pdmmi->strText, pdmmi->strText.GetLength(), &szTxt);
246 lpMeasureItemStruct->itemWidth += szTxt.cx + m_attr->GetTextMargin() * 2;
247 int itemMaxWidth = m_attr->GetMaxWidth();
248 if (itemMaxWidth != -1 && (int)lpMeasureItemStruct->itemWidth > itemMaxWidth)
249 lpMeasureItemStruct->itemWidth = itemMaxWidth;
250 pRT->SelectObject(oldFont, NULL);
251 }
252 else
253 {
254 // separator
255 lpMeasureItemStruct->itemHeight = m_attr->m_pSepSkin ? m_attr->m_pSepSkin->GetSkinSize().cy : 3;
256 lpMeasureItemStruct->itemWidth = 0;
257 }
258}
259
260void SMenuODWnd::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU menu)
261{
262 ::SendMessage(m_hMenuOwner, WM_MENUSELECT, MAKEWPARAM(nItemID, nFlags), (LPARAM)menu);
263}
264
265LRESULT SMenuODWnd::OnMenuChar(UINT nChar, UINT nFlags, HMENU hMenu)
266{
267 wchar_t cChar = tolower(nChar);
268
269 int nMenuItems = ::GetMenuItemCount(hMenu);
270 for (int i = 0; i < nMenuItems; i++)
271 {
272 MENUITEMINFO mi = { sizeof(mi), 0 };
273 mi.fMask = MIIM_DATA;
274 ::GetMenuItemInfo(hMenu, i, TRUE, &mi);
275 SMenuItemData *pItemData = (SMenuItemData *)mi.dwItemData;
276 if (pItemData && pItemData->vHotKey == cChar)
277 {
278 return MAKELONG(i, MNC_EXECUTE);
279 }
280 }
281 return MAKELONG(0, MNC_IGNORE);
282}
283
284//////////////////////////////////////////////////////////////////////////
285
287 : m_hMenu(0)
288 , m_bAttached(false)
289{
290 Attach(src.m_hMenu);
291}
292
293SMenu::SMenu(HMENU hMenu)
294 : m_hMenu(0)
295 , m_bAttached(false)
296{
297 if (hMenu)
298 {
299 Attach(hMenu);
300 }
301}
302
304{
305 if (!m_bAttached)
306 DestroyMenu();
307}
308
310{
311 if (!pXmlNode)
312 return FALSE;
313 SXmlNode xmlMenu(pXmlNode);
314 SAutoRefPtr<SMenuAttr> pMenuAttr(new SMenuAttr, TRUE);
315 pMenuAttr->InitFromXml(&xmlMenu);
316 if (!pMenuAttr->m_pItemSkin)
317 {
318 SSLOGE() << "menu root doesn't has itemSkin defined";
319 return FALSE;
320 }
321
322 SASSERT(m_hMenu == 0);
323 m_hMenu = CreatePopupMenu();
324 if (!m_hMenu)
325 {
326 return FALSE;
327 }
328 SetMenuContextHelpId(m_hMenu, xmlMenu.attribute(L"contextHelpId").as_uint(0));
329 SetMenuAttr(m_hMenu, pMenuAttr);
330
331 if (m_icons)
332 {
333 pMenuAttr->m_pIconSkin = m_icons;
334 }
335 BuildMenu(m_hMenu, xmlMenu);
336
337 return TRUE;
338}
339
340BOOL SMenu::LoadMenu(LPCTSTR resId)
341{
342 SASSERT(!::IsMenu(m_hMenu));
343
344 SXmlDoc xmlDoc;
345 if (!LOADXML(xmlDoc, resId))
346 return FALSE;
347
348 SXmlNode xmlMenu = xmlDoc.root().child(L"menu");
349 if (!xmlMenu)
350 return FALSE;
351
352 return LoadMenu2(&xmlMenu);
353}
354
355BOOL SMenu::LoadMenuU8(THIS_ LPCSTR resId)
356{
357 SStringT strResId = S_CA2T(resId, CP_UTF8);
358 return LoadMenu(strResId);
359}
360
361void SMenu::InitMenuItemData(SMenuItemData *itemInfo, const SStringW &strTextW)
362{
363 SMenuAttr *pMenuAttr = GetMenuAttr(m_hMenu);
364 itemInfo->strText = S_CW2T(TR(strTextW, pMenuAttr->m_strTrCtx));
365 //查找快捷键
366 int iHotKey = strTextW.Find(L"&");
367 if (iHotKey != -1 && iHotKey < strTextW.GetLength() - 1)
368 {
369 itemInfo->vHotKey = tolower(strTextW[iHotKey + 1]);
370 }
371 else
372 {
373 itemInfo->vHotKey = 0;
374 }
375}
376
377BOOL SMenu::InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem, LPCTSTR strText, int iIcon, HICON hIcon)
378{
379 nFlags |= MF_OWNERDRAW;
380 if (nFlags & MF_SEPARATOR)
381 {
382 return ::InsertMenu(m_hMenu, nPosition, nFlags, (UINT_PTR)0, (LPCTSTR)NULL);
383 }
384
385 SMenuItemData *pMenuData = new SMenuItemData;
386 pMenuData->iIcon = iIcon;
387 pMenuData->hIcon = hIcon;
388 InitMenuItemData(pMenuData, S_CT2W(strText));
389
390 if (!::InsertMenu(m_hMenu, nPosition, nFlags, nIDNewItem, (LPCTSTR)pMenuData))
391 {
392 delete pMenuData;
393 return FALSE;
394 }
395 if (nFlags & MF_POPUP)
396 {
397 HMENU hSubMenu = (HMENU)nIDNewItem;
398 SMenuAttr *pMenuAttr = GetMenuAttr(hSubMenu);
399 if (!pMenuAttr)
400 {
401 pMenuAttr = GetMenuAttr(m_hMenu);
402 SetMenuAttr(hSubMenu, pMenuAttr);
403 }
404 }
405 return TRUE;
406}
407
408void SMenu::UpdateScale(int nScale)
409{
410 SASSERT(IsMenu(m_hMenu));
411 SMenuAttr *pMenuAttr = GetMenuAttr(m_hMenu);
412 SASSERT(pMenuAttr);
413 pMenuAttr->SetScale(nScale);
414}
415
416UINT SMenu::TrackPopupMenu(UINT uFlags, int x, int y, HWND hWnd, LPCRECT prcRect, int nScale)
417{
418 SASSERT(IsMenu(m_hMenu));
419
420 UpdateScale(nScale);
421
422 SMenuODWnd menuOwner(hWnd, GetMenuAttr(m_hMenu));
423 menuOwner.CreateNative(NULL, WS_POPUP, WS_EX_NOACTIVATE, 0, 0, 0, 0, NULL, 0, NULL);
424 if (IsWindow(hWnd) && IsWindowEnabled(hWnd))
425 ::SetForegroundWindow(hWnd);
426 UINT uNewFlags = uFlags | TPM_RETURNCMD;
427 UINT uRet = ::TrackPopupMenu(m_hMenu, uNewFlags, x, y, 0, menuOwner.m_hWnd, prcRect);
428 menuOwner.DestroyWindow();
429 if (uRet && !(uFlags & TPM_RETURNCMD))
430 ::SendMessage(hWnd, WM_COMMAND, uRet, 0);
431 return uRet;
432}
433
434void SMenu::BuildMenu(HMENU menuPopup, SXmlNode xmlNode)
435{
436 SXmlNode xmlItem = xmlNode.first_child();
437
438 while (xmlItem)
439 {
440 if (wcsicmp(L"item", xmlItem.name()) == 0)
441 {
442 SMenuItemData *pdmmi = new SMenuItemData;
443 pdmmi->iIcon = xmlItem.attribute(L"icon").as_int(-1);
444 pdmmi->dwUserData = xmlItem.append_attribute(L"userData").as_uint();
445 SStringW strText = xmlItem.attribute(L"text").as_string();
446 if (strText.IsEmpty())
447 {
448 strText = SWindow::GetXmlText(xmlItem);
449 }
450 strText = TR(GETSTRING(strText), GetMenuAttr(menuPopup)->m_strTrCtx);
451 strText = STrText::EscapeString(strText);
452 InitMenuItemData(pdmmi, strText);
453
454 int nID = xmlItem.attribute(L"id").as_int(0);
455 BOOL bCheck = xmlItem.attribute(L"check").as_bool(false);
456 BOOL bRadio = xmlItem.attribute(L"radio").as_bool(false);
457 BOOL bDisable = xmlItem.attribute(L"disable").as_bool(false);
458
459 SStringW str;
460 xmlItem.ToString(&str);
461
462 SXmlNode xmlChild = xmlItem.first_child();
463 while (xmlChild && xmlChild.type() == node_pcdata)
464 xmlChild = xmlChild.next_sibling();
465
466 if (!xmlChild && !xmlItem.attribute(L"popup").as_bool(false))
467 {
468 UINT uFlag = MF_OWNERDRAW;
469 if (bCheck)
470 uFlag |= MF_CHECKED;
471 if (bDisable)
472 uFlag |= MF_GRAYED;
473 if (bRadio)
474 uFlag |= MFT_RADIOCHECK | MF_CHECKED;
475 ::AppendMenu(menuPopup, uFlag, (UINT_PTR)nID, (LPCTSTR)pdmmi);
476 }
477 else
478 {
479 HMENU hSubMenu = ::CreatePopupMenu();
480 SMenuAttr *pMenuAttr = GetMenuAttr(m_hMenu);
481 SetMenuAttr(hSubMenu, pMenuAttr);
482 SetMenuContextHelpId(hSubMenu, xmlItem.attribute(L"contextHelpId").as_uint(0));
483
484 UINT uFlag = MF_OWNERDRAW | MF_POPUP;
485 if (bDisable)
486 uFlag |= MF_GRAYED;
487 ::AppendMenu(menuPopup, uFlag, (UINT_PTR)hSubMenu, (LPCTSTR)pdmmi);
488 BuildMenu(hSubMenu, xmlItem); // build sub menu
489 }
490 }
491 else if (wcscmp(L"sep", xmlItem.name()) == 0)
492 {
493 ::AppendMenu(menuPopup, MF_SEPARATOR | MF_OWNERDRAW, (UINT_PTR)0, (LPCTSTR)NULL);
494 }
495 xmlItem = xmlItem.next_sibling();
496 }
497}
498
499void SMenu::FreeMenuItemData(HMENU hMemu)
500{
501 SMenuAttr *pMenuAttr = GetMenuAttr(hMemu);
502 pMenuAttr->Release();
503
504 int cItems = ::GetMenuItemCount(hMemu);
505 for (int i = 0; i < cItems; i++)
506 {
507 MENUITEMINFO mii = { sizeof(mii), MIIM_DATA | MIIM_SUBMENU, 0 };
508 GetMenuItemInfo(hMemu, i, TRUE, &mii);
509 if (mii.dwItemData)
510 {
511 SMenuItemData *pData = (SMenuItemData *)mii.dwItemData;
512 delete pData;
513 }
514 if (mii.hSubMenu)
515 {
516 FreeMenuItemData(mii.hSubMenu);
517 }
518 }
519}
520
522{
523 SASSERT(!m_bAttached);
524 if (::IsMenu(m_hMenu))
525 {
526 // free item data
527 FreeMenuItemData(m_hMenu);
528 ::DestroyMenu(m_hMenu);
529 }
530 m_hMenu = NULL;
531}
532
533BOOL SMenu::ModifyMenuString(UINT uPosition, UINT uFlags, LPCTSTR lpItemString)
534{
535 MENUITEMINFO mi = { sizeof(mi), 0 };
536 mi.fMask = MIIM_DATA;
537 if (!::GetMenuItemInfo(m_hMenu, uPosition, uFlags & MF_BYPOSITION, &mi))
538 return FALSE;
539 SMenuItemData *pItemData = (SMenuItemData *)mi.dwItemData;
540 pItemData->strText = lpItemString;
541 return TRUE;
542}
543
544BOOL SMenu::DeleteMenu(UINT uPosition, UINT uFlags)
545{
546 MENUITEMINFO mi = { sizeof(mi), MIIM_DATA, 0 };
547 if (!::GetMenuItemInfo(m_hMenu, uPosition, uFlags & MF_BYPOSITION, &mi))
548 return FALSE;
549 SMenuItemData *pItemData = (SMenuItemData *)mi.dwItemData;
550 if (::DeleteMenu(m_hMenu, uPosition, uFlags))
551 {
552 delete pItemData;
553 return TRUE;
554 }
555 return FALSE;
556}
557
558BOOL SMenu::AppendMenu(UINT uFlags, UINT_PTR uIDNewItem, LPCTSTR lpNewItem, int iIcon, HICON hIcon)
559{
560 return InsertMenu(-1, uFlags, uIDNewItem, lpNewItem, iIcon, hIcon);
561}
562
563BOOL SMenu::CheckMenuItem(UINT uIdCheckItem, UINT uCheck)
564{
565 return ::CheckMenuItem(m_hMenu, uIdCheckItem, uCheck);
566}
567
568BOOL SMenu::CheckMenuRadioItem(THIS_ UINT idFirst, UINT idLast, UINT idCheck, UINT uFlags)
569{
570 return ::CheckMenuRadioItem(m_hMenu, idFirst, idLast, idCheck, uFlags);
571}
572
573SMenuAttr *SMenu::GetMenuAttr(HMENU hMenu) const
574{
575 SASSERT(::IsMenu(hMenu));
576 MENUINFO mi = { sizeof(mi), MIM_MENUDATA, 0 };
577 GetMenuInfo(hMenu, &mi);
578 return (SMenuAttr *)mi.dwMenuData;
579}
580
581void SMenu::SetMenuAttr(HMENU hMenu, SMenuAttr *pMenuAttr) const
582{
583 MENUINFO mi = { sizeof(mi), MIM_MENUDATA, 0 };
584 mi.dwMenuData = (ULONG_PTR)pMenuAttr;
585 pMenuAttr->AddRef();
586 ::SetMenuInfo(hMenu, &mi);
587}
588
589BOOL SMenu::Attach(HMENU hMenu)
590{
591 SASSERT(m_hMenu == NULL);
592 SMenuAttr *pMenuAttr = GetMenuAttr(hMenu);
593 if (IsBadReadPtr(pMenuAttr, sizeof(SMenuAttr)))
594 return FALSE;
595 m_hMenu = hMenu;
596 m_bAttached = true;
597 return TRUE;
598}
599
601{
602 SASSERT(m_bAttached);
603 HMENU hRet = m_hMenu;
604 m_hMenu = NULL;
605 m_bAttached = false;
606 return hRet;
607}
608
609BOOL SMenu::SetMenuUserData(UINT uPosition, UINT uFlags, ULONG_PTR ulUserData)
610{
611 MENUITEMINFO mi = { sizeof(mi), MIIM_DATA, 0 };
612 if (!::GetMenuItemInfo(m_hMenu, uPosition, uFlags, &mi))
613 return FALSE;
614 SMenuItemData *pmid = (SMenuItemData *)mi.dwItemData;
615 pmid->dwUserData = ulUserData;
616 return TRUE;
617}
618
619ULONG_PTR SMenu::GetMenuUserData(UINT uPosition, UINT uFlags)
620{
621 MENUITEMINFO mi = { sizeof(mi), MIIM_DATA, 0 };
622 if (!::GetMenuItemInfo(m_hMenu, uPosition, uFlags, &mi))
623 return 0;
624 SMenuItemData *pmid = (SMenuItemData *)mi.dwItemData;
625 return pmid->dwUserData;
626}
627
629{
630 SASSERT(!m_hMenu);
631 m_icons = icons;
632}
633
634HMENU SMenu::GetHMenu() const
635{
636 return m_hMenu;
637}
638
640{
641 return ::GetMenuContextHelpId(m_hMenu);
642}
643
644void SMenu::SetContextHelpId(THIS_ DWORD dwId)
645{
646 ::SetMenuContextHelpId(m_hMenu, dwId);
647}
648
649HMENU SMenu::GetSubMenu(THIS_ int nPos)
650{
651 return ::GetSubMenu(m_hMenu, nPos);
652}
653
654BOOL SMenu::GetMenuString(THIS_ UINT uPosition, UINT uFlags, IStringT *lpItemString)
655{
656 MENUITEMINFO mi = { sizeof(mi), 0 };
657 mi.fMask = MIIM_DATA;
658 if (!::GetMenuItemInfo(m_hMenu, uPosition, uFlags & MF_BYPOSITION, &mi))
659 return FALSE;
660 SMenuItemData *pItemData = (SMenuItemData *)mi.dwItemData;
661 lpItemString->Copy(&pItemData->strText);
662 return TRUE;
663}
664
665SNSEND
Smart pointer class for managing COM-style reference-counted objects.
布局大小类
Definition SLayoutSize.h:10
菜单属性类
Definition SMenu.h:20
virtual void WINAPI OnInitFinished(SXmlNode xmlNode)
初始化完成后的回调函数
Definition SMenu.cpp:76
int GetItemHeight()
获取菜单项高度
Definition SMenu.cpp:64
SMenuAttr()
构造函数
Definition SMenu.cpp:26
int GetTextMargin()
获取文本边缘空间
Definition SMenu.cpp:49
void SetScale(int scale)
设置缩放比例
Definition SMenu.cpp:95
CSize GetIconSize()
获取图标尺寸
Definition SMenu.cpp:59
int GetMaxWidth()
获取菜单项最大宽度
Definition SMenu.cpp:69
~SMenuAttr()
析构函数
Definition SMenu.cpp:45
int GetIconMargin()
获取图标边缘空间
Definition SMenu.cpp:54
SAutoRefPtr< IFontS > GetFontPtr()
获取字体指针
Definition SMenu.cpp:87
SMenuAttr * GetMenuAttr(HMENU hMenu) const
获取菜单属性对象指针
Definition SMenu.cpp:573
void DestroyMenu() OVERRIDE
销毁菜单
Definition SMenu.cpp:521
void InitMenuItemData(SMenuItemData *itemInfo, const SStringW &strText)
初始化菜单项数据
Definition SMenu.cpp:361
BOOL Attach(HMENU hMenu) OVERRIDE
附加菜单句柄
Definition SMenu.cpp:589
BOOL InsertMenu(UINT uPosition, UINT uFlags, UINT_PTR nIDNewItem, LPCTSTR strText, int iIcon=-1, HICON hIcon=0) OVERRIDE
插入菜单项
Definition SMenu.cpp:377
BOOL LoadMenu(LPCTSTR resId) OVERRIDE
加载菜单资源
Definition SMenu.cpp:340
BOOL AppendMenu(UINT uFlags, UINT_PTR uIDNewItem, LPCTSTR lpNewItem, int iIcon=-1, HICON hIcon=0) OVERRIDE
追加菜单项
Definition SMenu.cpp:558
BOOL ModifyMenuString(UINT uPosition, UINT uFlags, LPCTSTR lpItemString) OVERRIDE
修改菜单项字符串
Definition SMenu.cpp:533
BOOL CheckMenuRadioItem(UINT idFirst, UINT idLast, UINT idCheck, UINT uFlags) OVERRIDE
检查菜单项(单选按钮)
Definition SMenu.cpp:568
HMENU GetHMenu() SCONST OVERRIDE
获取菜单句柄
Definition SMenu.cpp:634
BOOL LoadMenuU8(LPCSTR resId) OVERRIDE
加载菜单资源(UTF-8)
Definition SMenu.cpp:355
DWORD GetContextHelpId() SCONST OVERRIDE
获取上下文帮助ID
Definition SMenu.cpp:639
BOOL GetMenuString(UINT uPosition, UINT uFlags, IStringT *lpItemString) OVERRIDE
获取菜单项字符串
Definition SMenu.cpp:654
BOOL DeleteMenu(UINT uPosition, UINT uFlags) OVERRIDE
删除菜单项
Definition SMenu.cpp:544
void SetIconSkin(ISkinObj *icons) OVERRIDE
设置菜单图标皮肤
Definition SMenu.cpp:628
void SetMenuAttr(HMENU hMenu, SMenuAttr *pMenuAttr) const
设置菜单属性对象指针
Definition SMenu.cpp:581
SMenu(const SMenu &src)
复制构造函数
Definition SMenu.cpp:286
ULONG_PTR GetMenuUserData(UINT uPosition, UINT uFlags) OVERRIDE
获取菜单项用户数据
Definition SMenu.cpp:619
BOOL CheckMenuItem(UINT uIdCheckItem, UINT uCheck) OVERRIDE
检查菜单项
Definition SMenu.cpp:563
void UpdateScale(int nScale)
更新缩放比例
Definition SMenu.cpp:408
BOOL LoadMenu2(IXmlNode *xmlMenu) OVERRIDE
加载菜单资源(XML)
Definition SMenu.cpp:309
void SetContextHelpId(DWORD dwId) OVERRIDE
设置上下文帮助ID
Definition SMenu.cpp:644
~SMenu(void)
析构函数
Definition SMenu.cpp:303
void FreeMenuItemData(HMENU hMemu)
释放菜单项数据
Definition SMenu.cpp:499
void BuildMenu(HMENU menuPopup, SXmlNode xmlNode)
构建菜单
Definition SMenu.cpp:434
UINT TrackPopupMenu(UINT uFlags, int x, int y, HWND hWnd, LPCRECT prcRect=NULL, int nScale=100) OVERRIDE
跟踪弹出菜单
Definition SMenu.cpp:416
HMENU GetSubMenu(int nPos) OVERRIDE
获取子菜单
Definition SMenu.cpp:649
HMENU Detach() OVERRIDE
分离菜单句柄
Definition SMenu.cpp:600
BOOL SetMenuUserData(UINT uPosition, UINT uFlags, ULONG_PTR ulUserData) OVERRIDE
设置菜单项用户数据
Definition SMenu.cpp:609
所有者绘制菜单窗口类
Definition SMenu.h:323
void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
绘制菜单项
Definition SMenu.cpp:133
SMenuODWnd(HWND hMenuOwner, SMenuAttr *pMenuAttr)
构造函数
Definition SMenu.cpp:113
~SMenuODWnd()
析构函数
Definition SMenu.cpp:119
void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU menu)
处理菜单选择消息
Definition SMenu.cpp:260
LRESULT OnMenuChar(UINT nChar, UINT nFlags, HMENU hMenu)
处理菜单字符消息
Definition SMenu.cpp:265
void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
测量菜单项
Definition SMenu.cpp:228
void OnInitMenu(HMENU menu)
初始化菜单
Definition SMenu.cpp:123
void OnInitMenuPopup(HMENU menuPopup, UINT nIndex, BOOL bSysMenu)
初始化弹出菜单
Definition SMenu.cpp:128
LRESULT SendMessage(UINT message, WPARAM wParam=0, LPARAM lParam=0) OVERRIDE
Sends a message to the window.
HWND m_hWnd
Handle to the window.
Definition SNativeWnd.h:744
HWND CreateNative(LPCTSTR lpWindowName, DWORD dwStyle, DWORD dwExStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, int nID=0, LPVOID lpParam=0) OVERRIDE
Creates a native window.
BOOL DestroyWindow() OVERRIDE
Destroys the window.
A class representing an ASCII string.
Definition sstringw.h:96
BOOL IsEmpty() SCONST
Checks if the string is empty.
int GetLength() SCONST
Retrieves the length of the string.
int Find(const wchar_t *pszSub, int nStart=0) SCONST
Finds the first occurrence of a substring in the string.
Definition sstringw.cpp:516
static SStringW EscapeString(const SStringW &str)
Escapes a string.
Definition Swnd.cpp:52
static SStringW GetXmlText(const SXmlNode &xmlNode)
Gets the XML text from a node.
Definition Swnd.cpp:2955
int as_int(int def=0) const
Converts the attribute value to an integer.
Definition SXml.cpp:100
const wchar_t * as_string(const wchar_t *def=L"") const
Gets the attribute value as a string.
Definition SXml.cpp:95
unsigned int as_uint(unsigned int def=0) const
Converts the attribute value to an unsigned integer.
Definition SXml.cpp:105
bool as_bool(bool def=false) const
Converts the attribute value to a boolean.
Definition SXml.cpp:120
Implementation of IXmlDoc.
Definition SXml.h:912
SXmlNode root() const
Retrieves the root node of the document.
Definition SXml.cpp:754
Class representing an XML node.
Definition SXml.h:352
SXmlNode next_sibling() const
Gets the next sibling node in the children list of the parent node.
Definition SXml.cpp:393
SXmlNode first_child() const
Gets the first child node of the node.
Definition SXml.cpp:383
void ToString(IStringW *out) SCONST OVERRIDE
Converts the node to a string representation.
Definition SXml.cpp:238
const wchar_t * name() const
Gets the name of the node.
Definition SXml.cpp:363
SXmlAttr attribute(const wchar_t *name, bool bCaseSensitive=false) const
Gets the attribute with the specified name.
Definition SXml.cpp:428
SXmlAttr append_attribute(const wchar_t *name)
Adds an attribute with the specified name.
Definition SXml.cpp:458
XmlNodeType type() const
Gets the type of the node.
Definition SXml.cpp:358
SXmlNode child(const wchar_t *name, bool bCaseSensitive=false) const
Gets the child node, attribute, or next/previous sibling with the specified name.
Definition SXml.cpp:423
long AddRef() override
Increments the reference count.
long Release() override
Decrements the reference count and deletes the object if the count reaches zero.
Base class for all renderable objects.
Definition SRender-i.h:145
Interface for Skin Objects.
Definition SSkinobj-i.h:29
Interface for XML nodes.
Definition sxml-i.h:128
菜单项数据结构
Definition SMenu.h:134
~SMenuItemData()
析构函数
Definition SMenu.cpp:18
SMenuItemData()
构造函数
Definition SMenu.cpp:10