1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        msw/control.cpp 
   3 // Purpose:     wxControl class 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "control.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  36     #include "wx/dcclient.h" 
  38     #include "wx/settings.h" 
  41 #include "wx/control.h" 
  44     #include "wx/notebook.h" 
  45 #endif // wxUSE_NOTEBOOK 
  47 #include "wx/msw/private.h" 
  48 #include "wx/msw/uxtheme.h" 
  50 #if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__)) 
  54 // ---------------------------------------------------------------------------- 
  56 // ---------------------------------------------------------------------------- 
  58 IMPLEMENT_ABSTRACT_CLASS(wxControl
, wxWindow
) 
  60 // ============================================================================ 
  61 // wxControl implementation 
  62 // ============================================================================ 
  64 // ---------------------------------------------------------------------------- 
  65 // wxControl ctor/dtor 
  66 // ---------------------------------------------------------------------------- 
  68 wxControl::~wxControl() 
  70     m_isBeingDeleted 
= true; 
  73 // ---------------------------------------------------------------------------- 
  74 // control window creation 
  75 // ---------------------------------------------------------------------------- 
  77 bool wxControl::Create(wxWindow 
*parent
, 
  82                        const wxValidator
& wxVALIDATOR_PARAM(validator
), 
  85     if ( !wxWindow::Create(parent
, id
, pos
, size
, style
, name
) ) 
  89     SetValidator(validator
); 
  95 bool wxControl::MSWCreateControl(const wxChar 
*classname
, 
  96                                  const wxString
& label
, 
 101     WXDWORD msStyle 
= MSWGetStyle(GetWindowStyle(), &exstyle
); 
 103     return MSWCreateControl(classname
, msStyle
, pos
, size
, label
, exstyle
); 
 106 bool wxControl::MSWCreateControl(const wxChar 
*classname
, 
 110                                  const wxString
& label
, 
 113     // if no extended style given, determine it ourselves 
 114     if ( exstyle 
== (WXDWORD
)-1 ) 
 117         (void) MSWGetStyle(GetWindowStyle(), &exstyle
); 
 120     // all controls should have this style 
 123     // create the control visible if it's currently shown for wxWidgets 
 129     // choose the position for the control: we have a problem with default size 
 130     // here as we can't calculate the best size before the control exists 
 131     // (DoGetBestSize() may need to use m_hWnd), so just choose the minimal 
 132     // possible but non 0 size because 0 window width/height result in problems 
 134     int x 
= pos
.x 
== wxDefaultCoord 
? 0 : pos
.x
, 
 135         y 
= pos
.y 
== wxDefaultCoord 
? 0 : pos
.y
, 
 136         w 
= size
.x 
== wxDefaultCoord 
? 1 : size
.x
, 
 137         h 
= size
.y 
== wxDefaultCoord 
? 1 : size
.y
; 
 139     // ... and adjust it to account for a possible parent frames toolbar 
 140     AdjustForParentClientOrigin(x
, y
); 
 142     m_hWnd 
= (WXHWND
)::CreateWindowEx
 
 144                         exstyle
,            // extended style 
 145                         classname
,          // the kind of control to create 
 146                         label
,              // the window name 
 147                         style
,              // the window style 
 148                         x
, y
, w
, h
,         // the window position and size 
 149                         GetHwndOf(GetParent()),  // parent 
 150                         (HMENU
)GetId(),     // child id 
 151                         wxGetInstance(),    // app instance 
 152                         NULL                
// creation parameters 
 157         wxLogDebug(wxT("Failed to create a control of class '%s'"), classname
); 
 158         wxFAIL_MSG(_T("something is very wrong, CreateWindowEx failed")); 
 166         Ctl3dSubclassCtl(GetHwnd()); 
 169 #endif // wxUSE_CTL3D 
 171     // install wxWidgets window proc for this window 
 174     // set up fonts and colours 
 177         SetFont(GetDefaultAttributes().font
); 
 179     // set the size now if no initial size specified 
 180     SetInitialBestSize(size
); 
 185 // ---------------------------------------------------------------------------- 
 187 // ---------------------------------------------------------------------------- 
 189 wxBorder 
wxControl::GetDefaultBorder() const 
 191     // we want to automatically give controls a sunken style (confusingly, 
 192     // it may not really mean sunken at all as we map it to WS_EX_CLIENTEDGE 
 193     // which is not sunken at all under Windows XP -- rather, just the default) 
 194     return wxBORDER_SUNKEN
; 
 197 WXDWORD 
wxControl::MSWGetStyle(long style
, WXDWORD 
*exstyle
) const 
 199     long msStyle 
= wxWindow::MSWGetStyle(style
, exstyle
); 
 201     if ( AcceptsFocus() ) 
 203         msStyle 
|= WS_TABSTOP
; 
 209 wxSize 
wxControl::DoGetBestSize() const 
 211     return wxSize(DEFAULT_ITEM_WIDTH
, DEFAULT_ITEM_HEIGHT
); 
 214 // This is a helper for all wxControls made with UPDOWN native control. 
 215 // In wxMSW it was only wxSpinCtrl derived from wxSpinButton but in 
 216 // WinCE of Smartphones this happens also for native wxTextCtrl, 
 217 // wxChoice and others. 
 218 wxSize 
wxControl::GetBestSpinerSize(const bool is_vertical
) const 
 220     // take size according to layout 
 222 #if defined(__SMARTPHONE__) && defined(__WXWINCE__) 
 225                     ::GetSystemMetrics(is_vertical 
? SM_CXVSCROLL 
: SM_CXHSCROLL
), 
 226                     ::GetSystemMetrics(is_vertical 
? SM_CYVSCROLL 
: SM_CYHSCROLL
) 
 230     // correct size as for undocumented MSW variants cases (WinCE and perhaps others) 
 232         bestSize
.x 
= bestSize
.y
; 
 234         bestSize
.y 
= bestSize
.x
; 
 236     // double size according to layout 
 245 /* static */ wxVisualAttributes
 
 246 wxControl::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
 248     wxVisualAttributes attrs
; 
 250     // old school (i.e. not "common") controls use the standard dialog font 
 252     attrs
.font 
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
); 
 254     // most, or at least many, of the controls use the same colours as the 
 255     // buttons -- others will have to override this (and possibly simply call 
 256     // GetCompositeControlsDefaultAttributes() from their versions) 
 257     attrs
.colFg 
= wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT
); 
 258     attrs
.colBg 
= wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE
); 
 263 // another version for the "composite", i.e. non simple controls 
 264 /* static */ wxVisualAttributes
 
 265 wxControl::GetCompositeControlsDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
 267     wxVisualAttributes attrs
; 
 268     attrs
.font 
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
); 
 269     attrs
.colFg 
= wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT
); 
 270     attrs
.colBg 
= wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
); 
 275 // ---------------------------------------------------------------------------- 
 277 // ---------------------------------------------------------------------------- 
 279 bool wxControl::ProcessCommand(wxCommandEvent
& event
) 
 281     return GetEventHandler()->ProcessEvent(event
); 
 285 bool wxControl::MSWOnNotify(int idCtrl
, 
 289     wxEventType eventType 
wxDUMMY_INITIALIZE(wxEVT_NULL
); 
 291     NMHDR 
*hdr 
= (NMHDR
*) lParam
; 
 295             eventType 
= wxEVT_COMMAND_LEFT_CLICK
; 
 299             eventType 
= wxEVT_COMMAND_LEFT_DCLICK
; 
 303             eventType 
= wxEVT_COMMAND_RIGHT_CLICK
; 
 307             eventType 
= wxEVT_COMMAND_RIGHT_DCLICK
; 
 311             eventType 
= wxEVT_COMMAND_SET_FOCUS
; 
 315             eventType 
= wxEVT_COMMAND_KILL_FOCUS
; 
 319             eventType 
= wxEVT_COMMAND_ENTER
; 
 323             return wxWindow::MSWOnNotify(idCtrl
, lParam
, result
); 
 326     wxCommandEvent 
event(wxEVT_NULL
, m_windowId
); 
 327     event
.SetEventType(eventType
); 
 328     event
.SetEventObject(this); 
 330     return GetEventHandler()->ProcessEvent(event
); 
 334 WXHBRUSH 
wxControl::DoMSWControlColor(WXHDC pDC
, wxColour colBg
) 
 339         ::SetTextColor(hdc
, wxColourToRGB(GetForegroundColour())); 
 342     // use the background colour override if a valid colour is given 
 346         ::SetBkColor(hdc
, wxColourToRGB(colBg
)); 
 348         // draw children with the same colour as the parent 
 349         wxBrush 
*brush 
= wxTheBrushList
->FindOrCreateBrush(colBg
, wxSOLID
); 
 351         hbr 
= (WXHBRUSH
)brush
->GetResourceHandle(); 
 353     else // use our own background colour and recurse upwards if necessary 
 355         hbr 
= MSWGetBgBrush(pDC
); 
 361 WXHBRUSH 
wxControl::MSWControlColor(WXHDC pDC
) 
 363     // by default consider that the controls text shouldn't erase the 
 364     // background under it (this is true for all static controls, check boxes, 
 365     // radio buttons, ... 
 366     ::SetBkMode((HDC
)pDC
, TRANSPARENT
); 
 368     return DoMSWControlColor(pDC
, wxNullColour
); 
 371 WXHBRUSH 
wxControl::MSWControlColorDisabled(WXHDC pDC
) 
 373     return DoMSWControlColor(pDC
, 
 374                              wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE
)); 
 377 // --------------------------------------------------------------------------- 
 379 // --------------------------------------------------------------------------- 
 381 // this is used in radiobox.cpp and slider95.cpp and should be removed as soon 
 382 // as it is not needed there any more! 
 384 // Call this repeatedly for several wnds to find the overall size 
 386 // Call it initially with wxDefaultCoord for all values in rect. 
 387 // Keep calling for other widgets, and rect will be modified 
 388 // to calculate largest bounding rectangle. 
 389 void wxFindMaxSize(WXHWND wnd
, RECT 
*rect
) 
 391     int left 
= rect
->left
; 
 392     int right 
= rect
->right
; 
 394     int bottom 
= rect
->bottom
; 
 396     GetWindowRect((HWND
) wnd
, rect
); 
 401     if (left 
< rect
->left
) 
 404     if (right 
> rect
->right
) 
 410     if (bottom 
> rect
->bottom
) 
 411         rect
->bottom 
= bottom
; 
 414 #endif // wxUSE_CONTROLS