+
+
+ // get the theme engine or NULL if themes
+ // are not available or not supported on menu
+ static wxUxThemeEngine *GetUxThemeEngine()
+ {
+ #if wxUSE_UXTHEME
+ if ( MenuLayout() == FullTheme )
+ return wxUxThemeEngine::GetIfActive();
+ #endif // wxUSE_UXTHEME
+ return NULL;
+ }
+
+
+ enum MenuLayoutType
+ {
+ FullTheme, // full menu themes (Vista or new)
+ PseudoTheme, // pseudo menu themes (on XP)
+ Classic
+ };
+
+ static MenuLayoutType MenuLayout()
+ {
+ MenuLayoutType menu = Classic;
+ #if wxUSE_UXTHEME
+ if ( wxUxThemeEngine::GetIfActive() != NULL )
+ {
+ static wxWinVersion ver = wxGetWinVersion();
+ if ( ver >= wxWinVersion_Vista )
+ menu = FullTheme;
+ else if ( ver == wxWinVersion_XP )
+ menu = PseudoTheme;
+ }
+ #endif // wxUSE_UXTHEME
+ return menu;
+ }
+
+private:
+ void Init();
+
+ static MenuDrawData* ms_instance;
+};
+
+MenuDrawData* MenuDrawData::ms_instance = NULL;
+
+void MenuDrawData::Init()
+{
+#if wxUSE_UXTHEME
+ wxUxThemeEngine* theme = GetUxThemeEngine();
+ if ( theme )
+ {
+ wxWindow* window = static_cast<wxApp*>(wxApp::GetInstance())->GetTopWindow();
+ wxUxThemeHandle hTheme(window, L"MENU");
+
+ theme->GetThemeMargins(hTheme, NULL, MENU_POPUPITEM, 0,
+ TMT_CONTENTMARGINS, NULL,
+ &ItemMargin);
+
+ theme->GetThemeMargins(hTheme, NULL, MENU_POPUPCHECK, 0,
+ TMT_CONTENTMARGINS, NULL,
+ &CheckMargin);
+ theme->GetThemeMargins(hTheme, NULL, MENU_POPUPCHECKBACKGROUND, 0,
+ TMT_CONTENTMARGINS, NULL,
+ &CheckBgMargin);
+
+ theme->GetThemeMargins(hTheme, NULL, MENU_POPUPSUBMENU, 0,
+ TMT_CONTENTMARGINS, NULL,
+ &ArrowMargin);
+
+ theme->GetThemeMargins(hTheme, NULL, MENU_POPUPSEPARATOR, 0,
+ TMT_SIZINGMARGINS, NULL,
+ &SeparatorMargin);
+
+ theme->GetThemePartSize(hTheme, NULL, MENU_POPUPCHECK, 0,
+ NULL, TS_TRUE, &CheckSize);
+
+ theme->GetThemePartSize(hTheme, NULL, MENU_POPUPSUBMENU, 0,
+ NULL, TS_TRUE, &ArrowSize);
+
+ theme->GetThemePartSize(hTheme, NULL, MENU_POPUPSEPARATOR, 0,
+ NULL, TS_TRUE, &SeparatorSize);
+
+ theme->GetThemeInt(hTheme, MENU_POPUPBACKGROUND, 0, TMT_BORDERSIZE, &TextBorder);
+
+ AccelBorder = 34;
+ ArrowBorder = 0;
+
+ Offset = -14;
+
+ wxUxThemeFont themeFont;
+ theme->GetThemeSysFont(hTheme, TMT_MENUFONT, themeFont.GetPtr());
+ Font = wxFont(themeFont.GetLOGFONT());
+
+ Theme = true;
+
+ // native menu doesn't uses the vertical margins
+ ItemMargin.cyTopHeight =
+ ItemMargin.cyBottomHeight = 0;
+
+ // native menu uses small top margin for separator
+ if ( SeparatorMargin.cyTopHeight >= 2 )
+ SeparatorMargin.cyTopHeight -= 2;
+ }
+ else
+#endif // wxUSE_UXTHEME
+ {
+ const NONCLIENTMETRICS& metrics = wxMSWImpl::GetNonClientMetrics();
+
+ CheckMargin.cxLeftWidth =
+ CheckMargin.cxRightWidth = ::GetSystemMetrics(SM_CXEDGE);
+ CheckMargin.cyTopHeight =
+ CheckMargin.cyBottomHeight = ::GetSystemMetrics(SM_CYEDGE);
+
+ CheckSize.cx = ::GetSystemMetrics(SM_CXMENUCHECK);
+ CheckSize.cy = ::GetSystemMetrics(SM_CYMENUCHECK);
+
+ ArrowSize = CheckSize;
+
+ // separator height with margins
+ int sepFullSize = metrics.iMenuHeight / 2;
+
+ SeparatorMargin.cxLeftWidth =
+ SeparatorMargin.cxRightWidth = 1;
+ SeparatorMargin.cyTopHeight =
+ SeparatorMargin.cyBottomHeight = sepFullSize / 2 - 1;
+
+ SeparatorSize.cx = 1;
+ SeparatorSize.cy = sepFullSize - SeparatorMargin.GetTotalY();
+
+ TextBorder = 0;
+ AccelBorder = 8;
+ ArrowBorder = 6;
+
+ Offset = -12;
+
+ Font = wxFont(wxNativeFontInfo(metrics.lfMenuFont));
+
+ Theme = false;
+ }
+
+ int value;
+ if ( ::SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &value, 0) == 0 )
+ {
+ // if it's not supported, we must be on an old Windows version
+ // which always shows them
+ value = 1;
+ }
+
+ AlwaysShowCues = value == 1;
+