+namespace
+{
+
+// helper class to keep information about metrics and other stuff
+// needed for measuring and drawing menu item
+class MenuDrawData
+{
+public:
+
+ struct Margins
+ {
+ int left;
+ int right;
+ int top;
+ int bottom;
+
+ Margins()
+ : left(0),
+ right(0),
+ top(0),
+ bottom(0)
+ {}
+ };
+
+ Margins ItemMargin; // popup item margins
+
+ Margins CheckMargin; // popup check margins
+ Margins CheckBgMargin; // popup check background margins
+
+ Margins SeparatorMargin; // popup separator margins
+
+ SIZE CheckSize; // popup check size metric
+ SIZE SeparatorSize; // popup separator size metric
+
+ int AccelBorder; // popup border space between
+ // item text and accelerator
+ int TextBorder; // popup border space between
+ // item text and gutter
+
+ wxFont Font; // default menu font
+
+ bool AlwaysShowCues; // must keyboard cues always be shown?
+
+ bool Theme; // is data initialized for FullTheme?
+
+ static const MenuDrawData* Get()
+ {
+ #if wxUSE_UXTHEME
+ bool theme = MenuLayout() == FullTheme;
+ if ( ms_instance->Theme != theme )
+ ms_instance->Init();
+ #endif // wxUSE_UXTHEME
+ return ms_instance;
+ }
+
+ MenuDrawData()
+ {
+ ms_instance = this;
+ Init();
+ }
+
+
+ // 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;
+
+MenuDrawData s_menuData;
+
+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,
+ reinterpret_cast<MARGINS*>(&ItemMargin));
+
+ theme->GetThemeMargins(hTheme, NULL, MENU_POPUPCHECK, 0,
+ TMT_CONTENTMARGINS, NULL,
+ reinterpret_cast<MARGINS*>(&CheckMargin));
+ theme->GetThemeMargins(hTheme, NULL, MENU_POPUPCHECKBACKGROUND, 0,
+ TMT_CONTENTMARGINS, NULL,
+ reinterpret_cast<MARGINS*>(&CheckBgMargin));
+
+ theme->GetThemeMargins(hTheme, NULL, MENU_POPUPSEPARATOR, 0,
+ TMT_SIZINGMARGINS, NULL,
+ reinterpret_cast<MARGINS*>(&SeparatorMargin));
+
+ theme->GetThemePartSize(hTheme, NULL, MENU_POPUPCHECK, 0,
+ NULL, TS_TRUE, &CheckSize);
+
+ theme->GetThemePartSize(hTheme, NULL, MENU_POPUPSEPARATOR, 0,
+ NULL, TS_TRUE, &SeparatorSize);
+
+ theme->GetThemeInt(hTheme, MENU_POPUPBORDERS, 0, TMT_BORDERSIZE, &AccelBorder);
+ theme->GetThemeInt(hTheme, MENU_POPUPBACKGROUND, 0, TMT_BORDERSIZE, &TextBorder);
+
+ wxNativeFontInfo fontInfo;
+ theme->GetThemeSysFont(hTheme, TMT_MENUFONT, &fontInfo.lf);
+ Font = wxFont(fontInfo);
+
+ Theme = true;
+
+ // native menu doesn't uses the vertical margins
+ ItemMargin.top = ItemMargin.bottom = 0;
+
+ // native menu uses small top margin for separator
+ if ( SeparatorMargin.top >= 2 )
+ SeparatorMargin.top -= 2;
+ }
+ else
+#endif // wxUSE_UXTHEME
+ {
+ const NONCLIENTMETRICS& metrics = wxMSWImpl::GetNonClientMetrics();
+
+ ItemMargin = Margins();
+
+ CheckMargin.left =
+ CheckMargin.right = ::GetSystemMetrics(SM_CXEDGE);
+ CheckMargin.top =
+ CheckMargin.bottom = ::GetSystemMetrics(SM_CYEDGE);
+
+ CheckBgMargin = Margins();
+
+ CheckSize.cx = ::GetSystemMetrics(SM_CXMENUCHECK);
+ CheckSize.cy = ::GetSystemMetrics(SM_CYMENUCHECK);
+
+ // separator height with margins
+ int sepFullSize = metrics.iMenuHeight / 2;
+
+ SeparatorMargin.left =
+ SeparatorMargin.right = 1;
+ SeparatorMargin.top =
+ SeparatorMargin.bottom = sepFullSize / 2 - 1;
+
+ SeparatorSize.cx = 1;
+ SeparatorSize.cy = sepFullSize - SeparatorMargin.top - SeparatorMargin.bottom;
+
+ TextBorder = 0;
+ AccelBorder = 8;
+
+ 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;
+
+}
+
+} // anonymous namespace