]> git.saurik.com Git - wxWidgets.git/blame - src/msw/control.cpp
no changes; just code cleanup in OnEraseBackground()
[wxWidgets.git] / src / msw / control.cpp
CommitLineData
2bda0e17 1/////////////////////////////////////////////////////////////////////////////
a71d815b 2// Name: src/msw/control.cpp
2bda0e17
KB
3// Purpose: wxControl class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
6c9a19aa 8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
34040e31
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
2bda0e17
KB
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
1e6feb95 24 #pragma hdrstop
2bda0e17
KB
25#endif
26
1e6feb95
VZ
27#if wxUSE_CONTROLS
28
2bda0e17 29#ifndef WX_PRECOMP
1e6feb95
VZ
30 #include "wx/event.h"
31 #include "wx/app.h"
32 #include "wx/dcclient.h"
33 #include "wx/log.h"
34040e31 34 #include "wx/settings.h"
2bda0e17
KB
35#endif
36
2432b92d
JS
37#include "wx/control.h"
38
01c500af
VZ
39#if wxUSE_NOTEBOOK
40 #include "wx/notebook.h"
41#endif // wxUSE_NOTEBOOK
42
2bda0e17 43#include "wx/msw/private.h"
01c500af 44#include "wx/msw/uxtheme.h"
2bda0e17 45
a71d815b
WS
46// include <commctrl.h> "properly"
47#include "wx/msw/wrapcctl.h"
2bda0e17 48
34040e31
VZ
49// ----------------------------------------------------------------------------
50// wxWin macros
51// ----------------------------------------------------------------------------
52
2bda0e17
KB
53IMPLEMENT_ABSTRACT_CLASS(wxControl, wxWindow)
54
34040e31
VZ
55// ============================================================================
56// wxControl implementation
57// ============================================================================
58
59// ----------------------------------------------------------------------------
60// wxControl ctor/dtor
61// ----------------------------------------------------------------------------
2bda0e17 62
42e69d6b 63wxControl::~wxControl()
2bda0e17 64{
d95de154 65 m_isBeingDeleted = true;
2bda0e17
KB
66}
67
34040e31
VZ
68// ----------------------------------------------------------------------------
69// control window creation
70// ----------------------------------------------------------------------------
8d772832 71
5b2f31eb
VZ
72bool wxControl::Create(wxWindow *parent,
73 wxWindowID id,
8d772832 74 const wxPoint& pos,
5b2f31eb
VZ
75 const wxSize& size,
76 long style,
ac8d0c11 77 const wxValidator& wxVALIDATOR_PARAM(validator),
8d772832
RD
78 const wxString& name)
79{
5b2f31eb 80 if ( !wxWindow::Create(parent, id, pos, size, style, name) )
d95de154 81 return false;
5b2f31eb 82
8d772832 83#if wxUSE_VALIDATORS
5b2f31eb 84 SetValidator(validator);
8d772832 85#endif
5b2f31eb 86
d95de154 87 return true;
5b2f31eb
VZ
88}
89
90bool wxControl::MSWCreateControl(const wxChar *classname,
91 const wxString& label,
92 const wxPoint& pos,
6dd16e4f 93 const wxSize& size)
5b2f31eb
VZ
94{
95 WXDWORD exstyle;
6dd16e4f 96 WXDWORD msStyle = MSWGetStyle(GetWindowStyle(), &exstyle);
5b2f31eb 97
2eb4c3aa 98 return MSWCreateControl(classname, msStyle, pos, size, label, exstyle);
8d772832
RD
99}
100
222594ea
VZ
101bool wxControl::MSWCreateControl(const wxChar *classname,
102 WXDWORD style,
103 const wxPoint& pos,
104 const wxSize& size,
105 const wxString& label,
2eb4c3aa 106 WXDWORD exstyle)
8d99be5f 107{
222594ea
VZ
108 // if no extended style given, determine it ourselves
109 if ( exstyle == (WXDWORD)-1 )
110 {
fe3d9123 111 exstyle = 0;
65bc172c 112 (void) MSWGetStyle(GetWindowStyle(), &exstyle);
222594ea
VZ
113 }
114
bdf5c30d
VZ
115 // all controls should have this style
116 style |= WS_CHILD;
117
77ffb593 118 // create the control visible if it's currently shown for wxWidgets
bdf5c30d
VZ
119 if ( m_isShown )
120 {
121 style |= WS_VISIBLE;
122 }
3f2711d5 123
7fe985ee
VZ
124 // choose the position for the control: we have a problem with default size
125 // here as we can't calculate the best size before the control exists
126 // (DoGetBestSize() may need to use m_hWnd), so just choose the minimal
127 // possible but non 0 size because 0 window width/height result in problems
128 // elsewhere
d95de154
WS
129 int x = pos.x == wxDefaultCoord ? 0 : pos.x,
130 y = pos.y == wxDefaultCoord ? 0 : pos.y,
7fe985ee
VZ
131 w = size.x == wxDefaultCoord ? 1 : size.x,
132 h = size.y == wxDefaultCoord ? 1 : size.y;
a63cbfa3 133
7c0a023d 134 // ... and adjust it to account for a possible parent frames toolbar
4e9d23cd
VZ
135 AdjustForParentClientOrigin(x, y);
136
8d99be5f
VZ
137 m_hWnd = (WXHWND)::CreateWindowEx
138 (
222594ea 139 exstyle, // extended style
8d99be5f 140 classname, // the kind of control to create
7862127b 141 label, // the window name
8d99be5f 142 style, // the window style
a63cbfa3 143 x, y, w, h, // the window position and size
8d99be5f
VZ
144 GetHwndOf(GetParent()), // parent
145 (HMENU)GetId(), // child id
146 wxGetInstance(), // app instance
147 NULL // creation parameters
148 );
149
150 if ( !m_hWnd )
151 {
658252ef
VZ
152#ifdef __WXDEBUG__
153 wxFAIL_MSG(wxString::Format
154 (
155 _T("CreateWindowEx(\"%s\", flags=%08x, ex=%08x) failed"),
f62ff2f1 156 classname, (unsigned int)style, (unsigned int)exstyle
658252ef
VZ
157 ));
158#endif // __WXDEBUG__
8d99be5f 159
d95de154 160 return false;
8d99be5f
VZ
161 }
162
77ffb593 163 // install wxWidgets window proc for this window
8d99be5f
VZ
164 SubclassWin(m_hWnd);
165
34040e31 166 // set up fonts and colours
8d99be5f 167 InheritAttributes();
e0176dd9
VZ
168 if (!m_hasFont)
169 SetFont(GetDefaultAttributes().font);
8d99be5f 170
a63cbfa3 171 // set the size now if no initial size specified
085dd1e9 172 SetInitialBestSize(size);
a63cbfa3 173
d95de154 174 return true;
8d99be5f
VZ
175}
176
34040e31
VZ
177// ----------------------------------------------------------------------------
178// various accessors
179// ----------------------------------------------------------------------------
180
65bc172c
VZ
181wxBorder wxControl::GetDefaultBorder() const
182{
183 // we want to automatically give controls a sunken style (confusingly,
184 // it may not really mean sunken at all as we map it to WS_EX_CLIENTEDGE
185 // which is not sunken at all under Windows XP -- rather, just the default)
edea6281
JS
186#if defined(__POCKETPC__) || defined(__SMARTPHONE__)
187 return wxBORDER_SIMPLE;
188#else
65bc172c 189 return wxBORDER_SUNKEN;
edea6281 190#endif
65bc172c
VZ
191}
192
34040e31
VZ
193WXDWORD wxControl::MSWGetStyle(long style, WXDWORD *exstyle) const
194{
195 long msStyle = wxWindow::MSWGetStyle(style, exstyle);
196
197 if ( AcceptsFocus() )
198 {
199 msStyle |= WS_TABSTOP;
200 }
201
202 return msStyle;
203}
204
f68586e5 205wxSize wxControl::DoGetBestSize() const
4438caf4
VZ
206{
207 return wxSize(DEFAULT_ITEM_WIDTH, DEFAULT_ITEM_HEIGHT);
208}
209
4bf45c9e
WS
210// This is a helper for all wxControls made with UPDOWN native control.
211// In wxMSW it was only wxSpinCtrl derived from wxSpinButton but in
212// WinCE of Smartphones this happens also for native wxTextCtrl,
213// wxChoice and others.
5aaabb37 214wxSize wxControl::GetBestSpinnerSize(const bool is_vertical) const
4bf45c9e 215{
b081046a 216 // take size according to layout
1550d5f8 217 wxSize bestSize(
285f605a 218#if defined(__SMARTPHONE__) && defined(__WXWINCE__)
1550d5f8 219 0,GetCharHeight()
3180bc0e 220#else
46697f31
WS
221 ::GetSystemMetrics(is_vertical ? SM_CXVSCROLL : SM_CXHSCROLL),
222 ::GetSystemMetrics(is_vertical ? SM_CYVSCROLL : SM_CYHSCROLL)
3180bc0e 223#endif
1550d5f8 224 );
b081046a
WS
225
226 // correct size as for undocumented MSW variants cases (WinCE and perhaps others)
227 if (bestSize.x==0)
228 bestSize.x = bestSize.y;
229 if (bestSize.y==0)
230 bestSize.y = bestSize.x;
231
232 // double size according to layout
4bf45c9e 233 if (is_vertical)
b081046a 234 bestSize.y *= 2;
4bf45c9e 235 else
b081046a
WS
236 bestSize.x *= 2;
237
238 return bestSize;
4bf45c9e
WS
239}
240
34040e31
VZ
241/* static */ wxVisualAttributes
242wxControl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
243{
244 wxVisualAttributes attrs;
245
246 // old school (i.e. not "common") controls use the standard dialog font
247 // by default
248 attrs.font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
249
250 // most, or at least many, of the controls use the same colours as the
251 // buttons -- others will have to override this (and possibly simply call
252 // GetCompositeControlsDefaultAttributes() from their versions)
253 attrs.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT);
254 attrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
255
256 return attrs;
257}
258
259// another version for the "composite", i.e. non simple controls
260/* static */ wxVisualAttributes
fbfe58cb 261wxControl::GetCompositeControlsDefaultAttributes(wxWindowVariant WXUNUSED(variant))
34040e31
VZ
262{
263 wxVisualAttributes attrs;
264 attrs.font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
265 attrs.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
266 attrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
267
268 return attrs;
269}
270
271// ----------------------------------------------------------------------------
272// message handling
273// ----------------------------------------------------------------------------
274
42e69d6b 275bool wxControl::ProcessCommand(wxCommandEvent& event)
2bda0e17 276{
42e69d6b 277 return GetEventHandler()->ProcessEvent(event);
2bda0e17
KB
278}
279
a23fd0e1
VZ
280bool wxControl::MSWOnNotify(int idCtrl,
281 WXLPARAM lParam,
282 WXLPARAM* result)
2bda0e17 283{
5cb598ae 284 wxEventType eventType wxDUMMY_INITIALIZE(wxEVT_NULL);
b6e5eaa5
VZ
285
286 NMHDR *hdr = (NMHDR*) lParam;
287 switch ( hdr->code )
a23fd0e1
VZ
288 {
289 case NM_CLICK:
290 eventType = wxEVT_COMMAND_LEFT_CLICK;
291 break;
2bda0e17 292
a23fd0e1
VZ
293 case NM_DBLCLK:
294 eventType = wxEVT_COMMAND_LEFT_DCLICK;
295 break;
2bda0e17 296
a23fd0e1
VZ
297 case NM_RCLICK:
298 eventType = wxEVT_COMMAND_RIGHT_CLICK;
299 break;
2bda0e17 300
a23fd0e1
VZ
301 case NM_RDBLCLK:
302 eventType = wxEVT_COMMAND_RIGHT_DCLICK;
303 break;
2bda0e17 304
a23fd0e1
VZ
305 case NM_SETFOCUS:
306 eventType = wxEVT_COMMAND_SET_FOCUS;
307 break;
debe6624 308
a23fd0e1
VZ
309 case NM_KILLFOCUS:
310 eventType = wxEVT_COMMAND_KILL_FOCUS;
311 break;
2bda0e17 312
a23fd0e1
VZ
313 case NM_RETURN:
314 eventType = wxEVT_COMMAND_ENTER;
315 break;
316
317 default:
318 return wxWindow::MSWOnNotify(idCtrl, lParam, result);
319 }
fd3f686c 320
b6e5eaa5 321 wxCommandEvent event(wxEVT_NULL, m_windowId);
2bda0e17 322 event.SetEventType(eventType);
a23fd0e1 323 event.SetEventObject(this);
2bda0e17 324
a23fd0e1 325 return GetEventHandler()->ProcessEvent(event);
2bda0e17
KB
326}
327
2bae4332 328WXHBRUSH wxControl::DoMSWControlColor(WXHDC pDC, wxColour colBg, WXHWND hWnd)
f048e32f 329{
01c500af
VZ
330 HDC hdc = (HDC)pDC;
331 if ( m_hasFgCol )
6ed16512 332 {
01c500af 333 ::SetTextColor(hdc, wxColourToRGB(GetForegroundColour()));
6ed16512 334 }
01c500af 335
c3732409
VZ
336 WXHBRUSH hbr = 0;
337 if ( !colBg.Ok() )
338 {
2bae4332 339 hbr = MSWGetBgBrush(pDC, hWnd);
c3732409
VZ
340
341 // if the control doesn't have any bg colour, foreground colour will be
342 // ignored as the return value would be 0 -- so forcefully give it a
343 // non default background brush in this case
344 if ( !hbr && m_hasFgCol )
345 colBg = GetBackgroundColour();
346 }
347
d1a47dfe 348 // use the background colour override if a valid colour is given
5c836c46 349 if ( colBg.Ok() )
f048e32f 350 {
bcc4aa97
VZ
351 ::SetBkColor(hdc, wxColourToRGB(colBg));
352
d1a47dfe 353 // draw children with the same colour as the parent
5c836c46 354 wxBrush *brush = wxTheBrushList->FindOrCreateBrush(colBg, wxSOLID);
01c500af 355
d1a47dfe 356 hbr = (WXHBRUSH)brush->GetResourceHandle();
3d2f4457
VZ
357
358 // if we use custom background, we should set foreground ourselves too
359 if ( !m_hasFgCol )
360 {
361 ::SetTextColor(hdc, ::GetSysColor(COLOR_WINDOWTEXT));
362 }
363 //else: already set above
d1a47dfe 364 }
f048e32f 365
d1a47dfe 366 return hbr;
5c836c46
VZ
367}
368
2bae4332 369WXHBRUSH wxControl::MSWControlColor(WXHDC pDC, WXHWND hWnd)
5c836c46 370{
c3732409
VZ
371 wxColour colBg;
372
373 if ( HasTransparentBackground() )
374 ::SetBkMode((HDC)pDC, TRANSPARENT);
375 else // if the control is opaque it shouldn't use the parents background
376 colBg = GetBackgroundColour();
01c500af 377
2bae4332 378 return DoMSWControlColor(pDC, colBg, hWnd);
5c836c46
VZ
379}
380
381WXHBRUSH wxControl::MSWControlColorDisabled(WXHDC pDC)
382{
dd12ce22 383 return DoMSWControlColor(pDC,
2bae4332
VZ
384 wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE),
385 GetHWND());
f048e32f
VZ
386}
387
42e69d6b
VZ
388// ---------------------------------------------------------------------------
389// global functions
390// ---------------------------------------------------------------------------
2bda0e17 391
34040e31
VZ
392// this is used in radiobox.cpp and slider95.cpp and should be removed as soon
393// as it is not needed there any more!
394//
42e69d6b
VZ
395// Call this repeatedly for several wnds to find the overall size
396// of the widget.
d95de154 397// Call it initially with wxDefaultCoord for all values in rect.
42e69d6b
VZ
398// Keep calling for other widgets, and rect will be modified
399// to calculate largest bounding rectangle.
400void wxFindMaxSize(WXHWND wnd, RECT *rect)
2bda0e17 401{
42e69d6b
VZ
402 int left = rect->left;
403 int right = rect->right;
404 int top = rect->top;
405 int bottom = rect->bottom;
2bda0e17 406
42e69d6b 407 GetWindowRect((HWND) wnd, rect);
2bda0e17 408
42e69d6b
VZ
409 if (left < 0)
410 return;
2bda0e17 411
42e69d6b
VZ
412 if (left < rect->left)
413 rect->left = left;
2bda0e17 414
42e69d6b
VZ
415 if (right > rect->right)
416 rect->right = right;
2bda0e17 417
42e69d6b
VZ
418 if (top < rect->top)
419 rect->top = top;
2bda0e17 420
42e69d6b
VZ
421 if (bottom > rect->bottom)
422 rect->bottom = bottom;
2bda0e17
KB
423}
424
1e6feb95 425#endif // wxUSE_CONTROLS