1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/settings.cpp 
   3 // Purpose:     wxSystemSettingsNative implementation for MSW 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  27 #include "wx/settings.h" 
  31     #include "wx/gdicmn.h" 
  32     #include "wx/module.h" 
  35 #include "wx/msw/private.h" 
  36 #include "wx/msw/missing.h" // for SM_CXCURSOR, SM_CYCURSOR, SM_TABLETPC 
  38 #ifndef SPI_GETFLATMENU 
  39 #define SPI_GETFLATMENU                     0x1022 
  42 #include "wx/fontutil.h" 
  44 // ---------------------------------------------------------------------------- 
  46 // ---------------------------------------------------------------------------- 
  48 // the module which is used to clean up wxSystemSettingsNative data (this is a 
  49 // singleton class so it can't be done in the dtor) 
  50 class wxSystemSettingsModule 
: public wxModule
 
  53     virtual bool OnInit(); 
  54     virtual void OnExit(); 
  57     DECLARE_DYNAMIC_CLASS(wxSystemSettingsModule
) 
  60 // ---------------------------------------------------------------------------- 
  62 // ---------------------------------------------------------------------------- 
  64 // the font returned by GetFont(wxSYS_DEFAULT_GUI_FONT): it is created when 
  65 // GetFont() is called for the first time and deleted by wxSystemSettingsModule 
  66 static wxFont 
*gs_fontDefault 
= NULL
; 
  68 // ============================================================================ 
  70 // ============================================================================ 
  72 // TODO: see ::SystemParametersInfo for all sorts of Windows settings. 
  73 // Different args are required depending on the id. How does this differ 
  74 // from GetSystemMetric, and should it? Perhaps call it GetSystemParameter 
  75 // and pass an optional void* arg to get further info. 
  76 // Should also have SetSystemParameter. 
  77 // Also implement WM_WININICHANGE (NT) / WM_SETTINGCHANGE (Win95) 
  79 // ---------------------------------------------------------------------------- 
  80 // wxSystemSettingsModule 
  81 // ---------------------------------------------------------------------------- 
  83 IMPLEMENT_DYNAMIC_CLASS(wxSystemSettingsModule
, wxModule
) 
  85 bool wxSystemSettingsModule::OnInit() 
  90 void wxSystemSettingsModule::OnExit() 
  92     delete gs_fontDefault
; 
  93     gs_fontDefault 
= NULL
; 
  96 // ---------------------------------------------------------------------------- 
  97 // wxSystemSettingsNative 
  98 // ---------------------------------------------------------------------------- 
 100 // ---------------------------------------------------------------------------- 
 102 // ---------------------------------------------------------------------------- 
 104 wxColour 
wxSystemSettingsNative::GetColour(wxSystemColour index
) 
 106     // we use 0 as the default value just to avoid compiler warnings, as there 
 107     // is no invalid colour value we use hasCol as the real indicator of 
 108     // whether colSys was initialized or not 
 112     // the default colours for the entries after BTNHIGHLIGHT 
 113     static const COLORREF s_defaultSysColors
[] = 
 115         0x000000,   // 3DDKSHADOW 
 117         0x000000,   // INFOTEXT 
 120         0,          // filler - no std colour with this index 
 122         // TODO: please fill in the standard values of those, I don't have them 
 124         0,          // GRADIENTACTIVECAPTION 
 125         0,          // GRADIENTINACTIVECAPTION 
 127         0,          // MENUBAR (unused) 
 130     if ( index 
== wxSYS_COLOUR_LISTBOX 
) 
 132         // there is no standard colour with this index, map to another one 
 133         index 
= wxSYS_COLOUR_WINDOW
; 
 135     else if ( index 
> wxSYS_COLOUR_BTNHIGHLIGHT 
) 
 137         // the indices before BTNHIGHLIGHT are understood by GetSysColor() in 
 138         // all Windows version, for the other ones we have to check 
 142         wxGetOsVersion(&verMaj
, &verMin
); 
 148         else if ( verMaj 
== 4 ) 
 151             useDefault 
= index 
> wxSYS_COLOUR_INFOBK
; 
 153         else if ( verMaj 
== 5 && verMin 
== 0 ) 
 156             useDefault 
= index 
> wxSYS_COLOUR_GRADIENTINACTIVECAPTION
; 
 162             // Determine if we are using flat menus, only then allow wxSYS_COLOUR_MENUBAR 
 163             if ( index 
== wxSYS_COLOUR_MENUBAR 
) 
 166                 if ( SystemParametersInfo( SPI_GETFLATMENU 
, 0 ,&isFlat
, 0 ) ) 
 169                         index 
= wxSYS_COLOUR_MENU 
; 
 176             // special handling for MENUBAR colour: we use this in wxToolBar 
 177             // and wxStatusBar to have correct bg colour under Windows XP 
 178             // (which uses COLOR_MENUBAR for them) but they should still look 
 179             // correctly under previous Windows versions as well 
 180             if ( index 
== wxSYS_COLOUR_MENUBAR 
) 
 182                 index 
= wxSYS_COLOUR_3DFACE
; 
 184             else // replace with default colour 
 186                 unsigned int n 
= index 
- wxSYS_COLOUR_BTNHIGHLIGHT
; 
 188                 wxASSERT_MSG( n 
< WXSIZEOF(s_defaultSysColors
), 
 189                               _T("forgot tp update the default colours array") ); 
 191                 colSys 
= s_defaultSysColors
[n
]; 
 200         colSys 
= ::GetSysColor(index
|SYS_COLOR_INDEX_FLAG
); 
 202         colSys 
= ::GetSysColor(index
); 
 206     return wxRGBToColour(colSys
); 
 209 // ---------------------------------------------------------------------------- 
 211 // ---------------------------------------------------------------------------- 
 213 wxFont 
wxCreateFontFromStockObject(int index
) 
 217     HFONT hFont 
= (HFONT
) ::GetStockObject(index
); 
 221         if ( ::GetObject(hFont
, sizeof(LOGFONT
), &lf
) != 0 ) 
 223             wxNativeFontInfo info
; 
 226             // We want Windows 2000 or later to have new fonts even MS Shell Dlg 
 227             // is returned as default GUI font for compatibility 
 229             if(index 
== DEFAULT_GUI_FONT 
&& wxGetOsVersion(&verMaj
) == wxOS_WINDOWS_NT 
&& verMaj 
>= 5) 
 230                 wxStrcpy(info
.lf
.lfFaceName
, wxT("MS Shell Dlg 2")); 
 232             // Under MicroWindows we pass the HFONT as well 
 233             // because it's hard to convert HFONT -> LOGFONT -> HFONT 
 234             // It's OK to delete stock objects, the delete will be ignored. 
 235 #ifdef __WXMICROWIN__ 
 236             font
.Create(info
, (WXHFONT
) hFont
); 
 243             wxFAIL_MSG( _T("failed to get LOGFONT") ); 
 246     else // GetStockObject() failed 
 248         wxFAIL_MSG( _T("stock font not found") ); 
 254 wxFont 
wxSystemSettingsNative::GetFont(wxSystemFont index
) 
 257     // under CE only a single SYSTEM_FONT exists 
 260     if ( !gs_fontDefault 
) 
 262         gs_fontDefault 
= new wxFont(wxCreateFontFromStockObject(SYSTEM_FONT
)); 
 265     return *gs_fontDefault
; 
 266 #else // !__WXWINCE__ 
 267     // wxWindow ctor calls GetFont(wxSYS_DEFAULT_GUI_FONT) so we're 
 268     // called fairly often -- this is why we cache this particular font 
 269     const bool isDefaultRequested 
= index 
== wxSYS_DEFAULT_GUI_FONT
; 
 270     if ( isDefaultRequested 
) 
 272         if ( gs_fontDefault 
) 
 273             return *gs_fontDefault
; 
 276     wxFont font 
= wxCreateFontFromStockObject(index
); 
 278     if ( isDefaultRequested 
) 
 280         // if we got here it means we hadn't cached it yet - do now 
 281         gs_fontDefault 
= new wxFont(font
); 
 285 #endif // __WXWINCE__/!__WXWINCE__ 
 288 // ---------------------------------------------------------------------------- 
 289 // system metrics/features 
 290 // ---------------------------------------------------------------------------- 
 292 // TODO: some of the "metrics" clearly should be features now that we have 
 295 // the conversion table from wxSystemMetric enum to GetSystemMetrics() param 
 297 // if the constant is not defined, put -1 in the table to indicate that it is 
 299 static const int gs_metricsMap
[] = 
 301     -1,  // wxSystemMetric enums start at 1, so give a dummy value for pos 0. 
 302 #if defined(__WIN32__) && !defined(__WXWINCE__) 
 318 #if defined(__WIN32__) && defined(SM_CXDRAG) 
 346 #if defined(__WIN32__) && defined(SM_CXSIZEFRAME) 
 365 #if defined(__WIN32__) && defined(SM_NETWORK) 
 375 #if defined(__WIN32__) && defined(SM_SHOWSOUNDS) 
 380     // SM_SWAPBUTTON is not available under CE and it doesn't make sense to ask 
 387     -1   // wxSYS_DCLICK_MSEC - not available as system metric 
 390 // Get a system metric, e.g. scrollbar size 
 391 int wxSystemSettingsNative::GetMetric(wxSystemMetric index
, wxWindow
* WXUNUSED(win
)) 
 393 #ifdef __WXMICROWIN__ 
 394     // TODO: probably use wxUniv themes functionality 
 396 #else // !__WXMICROWIN__ 
 397     wxCHECK_MSG( index 
> 0 && (size_t)index 
< WXSIZEOF(gs_metricsMap
), 0, 
 398                  _T("invalid metric") ); 
 400     if ( index 
== wxSYS_DCLICK_MSEC 
) 
 402         // This one is not a Win32 system metric 
 403         return ::GetDoubleClickTime(); 
 406     int indexMSW 
= gs_metricsMap
[index
]; 
 407     if ( indexMSW 
== -1 ) 
 409         // not supported under current system 
 413     int rc 
= ::GetSystemMetrics(indexMSW
); 
 414     if ( index 
== wxSYS_NETWORK_PRESENT 
) 
 416         // only the last bit is significant according to the MSDN 
 421 #endif // __WXMICROWIN__/!__WXMICROWIN__ 
 424 bool wxSystemSettingsNative::HasFeature(wxSystemFeature index
) 
 428         case wxSYS_CAN_ICONIZE_FRAME
: 
 429         case wxSYS_CAN_DRAW_FRAME_DECORATIONS
: 
 432         case wxSYS_TABLET_PRESENT
: 
 433             return ::GetSystemMetrics(SM_TABLETPC
) != 0; 
 436             wxFAIL_MSG( _T("unknown system feature") ); 
 442 // ---------------------------------------------------------------------------- 
 443 // function from wx/msw/wrapcctl.h: there is really no other place for it... 
 444 // ---------------------------------------------------------------------------- 
 446 #if wxUSE_LISTCTRL || wxUSE_TREECTRL 
 448 extern wxFont 
wxGetCCDefaultFont() 
 451     // under the systems enumerated below (anything released after Win98), the 
 452     // default font used for the common controls seems to be the desktop font 
 453     // which is also used for the icon titles and not the stock default GUI 
 457     switch ( wxGetOsVersion(&verMaj
, &verMin
) ) 
 459         case wxOS_WINDOWS_9X
: 
 461             useIconFont 
= verMaj 
== 4 && verMin 
>= 10; 
 464         case wxOS_WINDOWS_NT
: 
 466             useIconFont 
= verMaj 
>= 5; 
 476         if ( ::SystemParametersInfo
 
 478                     SPI_GETICONTITLELOGFONT
, 
 484             return wxFont(wxCreateFontFromLogFont(&lf
)); 
 488             wxLogLastError(_T("SystemParametersInfo(SPI_GETICONTITLELOGFONT")); 
 491 #endif // __WXWINCE__ 
 493     // fall back to the default font for the normal controls 
 494     return wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
); 
 497 #endif // wxUSE_LISTCTRL || wxUSE_TREECTRL