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" 
  43 #include "wx/msw/private.h" 
  45 #if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__)) 
  49 // ---------------------------------------------------------------------------- 
  51 // ---------------------------------------------------------------------------- 
  53 IMPLEMENT_ABSTRACT_CLASS(wxControl
, wxWindow
) 
  55 BEGIN_EVENT_TABLE(wxControl
, wxWindow
) 
  56     EVT_ERASE_BACKGROUND(wxControl::OnEraseBackground
) 
  59 // ============================================================================ 
  60 // wxControl implementation 
  61 // ============================================================================ 
  63 // ---------------------------------------------------------------------------- 
  64 // wxControl ctor/dtor 
  65 // ---------------------------------------------------------------------------- 
  67 wxControl::~wxControl() 
  69     m_isBeingDeleted 
= TRUE
; 
  72 // ---------------------------------------------------------------------------- 
  73 // control window creation 
  74 // ---------------------------------------------------------------------------- 
  76 bool wxControl::Create(wxWindow 
*parent
, 
  81                        const wxValidator
& wxVALIDATOR_PARAM(validator
), 
  84     if ( !wxWindow::Create(parent
, id
, pos
, size
, style
, name
) ) 
  88     SetValidator(validator
); 
  94 bool wxControl::MSWCreateControl(const wxChar 
*classname
, 
  95                                  const wxString
& label
, 
 100     WXDWORD msStyle 
= MSWGetStyle(GetWindowStyle(), &exstyle
); 
 102     return MSWCreateControl(classname
, msStyle
, pos
, size
, label
, exstyle
); 
 105 bool wxControl::MSWCreateControl(const wxChar 
*classname
, 
 109                                  const wxString
& label
, 
 112     // if no extended style given, determine it ourselves 
 113     if ( exstyle 
== (WXDWORD
)-1 ) 
 116         (void) MSWGetStyle(GetWindowStyle(), &exstyle
); 
 119     // all controls should have this style 
 122     // create the control visible if it's currently shown for wxWindows 
 128     // choose the position for the control 
 129     int x 
= pos
.x 
== -1 ? 0 : pos
.x
, 
 130         y 
= pos
.y 
== -1 ? 0 : pos
.y
, 
 131         w 
= size
.x 
== -1 ? 0 : size
.x
, 
 132         h 
= size
.y 
== -1 ? 0 : size
.y
; 
 134     // ... and adjust it to account for ap ossible parent frames toolbar 
 135     AdjustForParentClientOrigin(x
, y
); 
 137     m_hWnd 
= (WXHWND
)::CreateWindowEx
 
 139                         exstyle
,            // extended style 
 140                         classname
,          // the kind of control to create 
 141                         label
,              // the window name 
 142                         style
,              // the window style 
 143                         x
, y
, w
, h
,         // the window position and size 
 144                         GetHwndOf(GetParent()),  // parent 
 145                         (HMENU
)GetId(),     // child id 
 146                         wxGetInstance(),    // app instance 
 147                         NULL                
// creation parameters 
 152         wxLogDebug(wxT("Failed to create a control of class '%s'"), classname
); 
 153         wxFAIL_MSG(_T("something is very wrong")); 
 161         Ctl3dSubclassCtl(GetHwnd()); 
 164 #endif // wxUSE_CTL3D 
 166     // install wxWindows window proc for this window 
 169     // set up fonts and colours 
 171     SetFont(GetDefaultAttributes().font
); 
 173     // set the size now if no initial size specified 
 174     if ( w 
<= 0 || h 
<= 0 ) 
 182 // ---------------------------------------------------------------------------- 
 184 // ---------------------------------------------------------------------------- 
 186 wxBorder 
wxControl::GetDefaultBorder() const 
 188     // we want to automatically give controls a sunken style (confusingly, 
 189     // it may not really mean sunken at all as we map it to WS_EX_CLIENTEDGE 
 190     // which is not sunken at all under Windows XP -- rather, just the default) 
 191     return wxBORDER_SUNKEN
; 
 194 WXDWORD 
wxControl::MSWGetStyle(long style
, WXDWORD 
*exstyle
) const 
 196     long msStyle 
= wxWindow::MSWGetStyle(style
, exstyle
); 
 198     if ( AcceptsFocus() ) 
 200         msStyle 
|= WS_TABSTOP
; 
 206 wxSize 
wxControl::DoGetBestSize() const 
 208     return wxSize(DEFAULT_ITEM_WIDTH
, DEFAULT_ITEM_HEIGHT
); 
 211 /* static */ wxVisualAttributes
 
 212 wxControl::GetClassDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
 214     wxVisualAttributes attrs
; 
 216     // old school (i.e. not "common") controls use the standard dialog font 
 218     attrs
.font 
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
); 
 220     // most, or at least many, of the controls use the same colours as the 
 221     // buttons -- others will have to override this (and possibly simply call 
 222     // GetCompositeControlsDefaultAttributes() from their versions) 
 223     attrs
.colFg 
= wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT
); 
 224     attrs
.colBg 
= wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE
); 
 229 // another version for the "composite", i.e. non simple controls 
 230 /* static */ wxVisualAttributes
 
 231 wxControl::GetCompositeControlsDefaultAttributes(wxWindowVariant 
WXUNUSED(variant
)) 
 233     wxVisualAttributes attrs
; 
 234     attrs
.font 
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
); 
 235     attrs
.colFg 
= wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT
); 
 236     attrs
.colBg 
= wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
); 
 241 // ---------------------------------------------------------------------------- 
 243 // ---------------------------------------------------------------------------- 
 245 bool wxControl::ProcessCommand(wxCommandEvent
& event
) 
 247     return GetEventHandler()->ProcessEvent(event
); 
 251 bool wxControl::MSWOnNotify(int idCtrl
, 
 255     wxEventType eventType 
= wxEVT_NULL
; 
 257     NMHDR 
*hdr 
= (NMHDR
*) lParam
; 
 261             eventType 
= wxEVT_COMMAND_LEFT_CLICK
; 
 265             eventType 
= wxEVT_COMMAND_LEFT_DCLICK
; 
 269             eventType 
= wxEVT_COMMAND_RIGHT_CLICK
; 
 273             eventType 
= wxEVT_COMMAND_RIGHT_DCLICK
; 
 277             eventType 
= wxEVT_COMMAND_SET_FOCUS
; 
 281             eventType 
= wxEVT_COMMAND_KILL_FOCUS
; 
 285             eventType 
= wxEVT_COMMAND_ENTER
; 
 289             return wxWindow::MSWOnNotify(idCtrl
, lParam
, result
); 
 292     wxCommandEvent 
event(wxEVT_NULL
, m_windowId
); 
 293     event
.SetEventType(eventType
); 
 294     event
.SetEventObject(this); 
 296     return GetEventHandler()->ProcessEvent(event
); 
 300 void wxControl::OnEraseBackground(wxEraseEvent
& event
) 
 302     // notice that this 'dumb' implementation may cause flicker for some of the 
 303     // controls in which case they should intercept wxEraseEvent and process it 
 304     // themselves somehow 
 307     ::GetClientRect(GetHwnd(), &rect
); 
 309     HBRUSH hBrush 
= ::CreateSolidBrush(wxColourToRGB(GetBackgroundColour())); 
 311     HDC hdc 
= GetHdcOf((*event
.GetDC())); 
 314     int mode 
= ::SetMapMode(hdc
, MM_TEXT
); 
 317     ::FillRect(hdc
, &rect
, hBrush
); 
 318     ::DeleteObject(hBrush
); 
 321     ::SetMapMode(hdc
, mode
); 
 325 WXHBRUSH 
wxControl::OnCtlColor(WXHDC pDC
, WXHWND 
WXUNUSED(pWnd
), WXUINT 
WXUNUSED(nCtlColor
), 
 331                                WXUINT 
WXUNUSED(message
), 
 332                                WXWPARAM 
WXUNUSED(wParam
), 
 333                                WXLPARAM 
WXUNUSED(lParam
) 
 340         HBRUSH hbrush 
= Ctl3dCtlColorEx(message
, wParam
, lParam
); 
 341         return (WXHBRUSH
) hbrush
; 
 343 #endif // wxUSE_CTL3D 
 346     wxColour colBack 
= GetBackgroundColour(); 
 348     ::SetBkColor(hdc
, wxColourToRGB(colBack
)); 
 349     ::SetTextColor(hdc
, wxColourToRGB(GetForegroundColour())); 
 351     wxBrush 
*brush 
= wxTheBrushList
->FindOrCreateBrush(colBack
, wxSOLID
); 
 353     return (WXHBRUSH
)brush
->GetResourceHandle(); 
 356 // --------------------------------------------------------------------------- 
 358 // --------------------------------------------------------------------------- 
 360 // this is used in radiobox.cpp and slider95.cpp and should be removed as soon 
 361 // as it is not needed there any more! 
 363 // Call this repeatedly for several wnds to find the overall size 
 365 // Call it initially with -1 for all values in rect. 
 366 // Keep calling for other widgets, and rect will be modified 
 367 // to calculate largest bounding rectangle. 
 368 void wxFindMaxSize(WXHWND wnd
, RECT 
*rect
) 
 370     int left 
= rect
->left
; 
 371     int right 
= rect
->right
; 
 373     int bottom 
= rect
->bottom
; 
 375     GetWindowRect((HWND
) wnd
, rect
); 
 380     if (left 
< rect
->left
) 
 383     if (right 
> rect
->right
) 
 389     if (bottom 
> rect
->bottom
) 
 390         rect
->bottom 
= bottom
; 
 393 #endif // wxUSE_CONTROLS