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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "control.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
28 #include "wx/dcclient.h"
32 #include "wx/control.h"
34 #include "wx/msw/private.h"
36 #if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__))
40 IMPLEMENT_ABSTRACT_CLASS(wxControl
, wxWindow
)
42 BEGIN_EVENT_TABLE(wxControl
, wxWindow
)
43 EVT_ERASE_BACKGROUND(wxControl::OnEraseBackground
)
47 wxControl::wxControl()
51 wxControl::~wxControl()
53 m_isBeingDeleted
= TRUE
;
57 bool wxControl::Create(wxWindow
*parent
,
62 const wxValidator
& wxVALIDATOR_PARAM(validator
),
65 if ( !wxWindow::Create(parent
, id
, pos
, size
, style
, name
) )
69 SetValidator(validator
);
75 bool wxControl::MSWCreateControl(const wxChar
*classname
,
76 const wxString
& label
,
81 WXDWORD msStyle
= MSWGetStyle(GetWindowStyle(), &exstyle
);
83 return MSWCreateControl(classname
, msStyle
, pos
, size
, label
, exstyle
);
86 bool wxControl::MSWCreateControl(const wxChar
*classname
,
90 const wxString
& label
,
93 // if no extended style given, determine it ourselves
94 if ( exstyle
== (WXDWORD
)-1 )
97 (void) MSWGetStyle(GetWindowStyle(), &exstyle
);
100 // all controls should have this style
103 // create the control visible if it's currently shown for wxWindows
109 int x
= pos
.x
== -1 ? 0 : pos
.x
,
110 y
= pos
.y
== -1 ? 0 : pos
.y
,
111 w
= size
.x
== -1 ? 0 : size
.x
,
112 h
= size
.y
== -1 ? 0 : size
.y
;
114 m_hWnd
= (WXHWND
)::CreateWindowEx
116 exstyle
, // extended style
117 classname
, // the kind of control to create
118 label
, // the window name
119 style
, // the window style
120 x
, y
, w
, h
, // the window position and size
121 GetHwndOf(GetParent()), // parent
122 (HMENU
)GetId(), // child id
123 wxGetInstance(), // app instance
124 NULL
// creation parameters
129 wxLogDebug(wxT("Failed to create a control of class '%s'"), classname
);
130 wxFAIL_MSG(_T("something is very wrong"));
138 Ctl3dSubclassCtl(GetHwnd());
141 #endif // wxUSE_CTL3D
143 // install wxWindows window proc for this window
146 // controls use the same font and colours as their parent dialog by default
149 // set the size now if no initial size specified
150 if ( w
<= 0 || h
<= 0 )
158 wxBorder
wxControl::GetDefaultBorder() const
160 // we want to automatically give controls a sunken style (confusingly,
161 // it may not really mean sunken at all as we map it to WS_EX_CLIENTEDGE
162 // which is not sunken at all under Windows XP -- rather, just the default)
163 return wxBORDER_SUNKEN
;
166 wxSize
wxControl::DoGetBestSize() const
168 return wxSize(DEFAULT_ITEM_WIDTH
, DEFAULT_ITEM_HEIGHT
);
171 bool wxControl::ProcessCommand(wxCommandEvent
& event
)
173 return GetEventHandler()->ProcessEvent(event
);
177 bool wxControl::MSWOnNotify(int idCtrl
,
181 wxEventType eventType
= wxEVT_NULL
;
183 NMHDR
*hdr
= (NMHDR
*) lParam
;
187 eventType
= wxEVT_COMMAND_LEFT_CLICK
;
191 eventType
= wxEVT_COMMAND_LEFT_DCLICK
;
195 eventType
= wxEVT_COMMAND_RIGHT_CLICK
;
199 eventType
= wxEVT_COMMAND_RIGHT_DCLICK
;
203 eventType
= wxEVT_COMMAND_SET_FOCUS
;
207 eventType
= wxEVT_COMMAND_KILL_FOCUS
;
211 eventType
= wxEVT_COMMAND_ENTER
;
215 return wxWindow::MSWOnNotify(idCtrl
, lParam
, result
);
218 wxCommandEvent
event(wxEVT_NULL
, m_windowId
);
219 event
.SetEventType(eventType
);
220 event
.SetEventObject(this);
222 return GetEventHandler()->ProcessEvent(event
);
226 void wxControl::OnEraseBackground(wxEraseEvent
& event
)
228 // notice that this 'dumb' implementation may cause flicker for some of the
229 // controls in which case they should intercept wxEraseEvent and process it
230 // themselves somehow
233 ::GetClientRect(GetHwnd(), &rect
);
235 HBRUSH hBrush
= ::CreateSolidBrush(wxColourToRGB(GetBackgroundColour()));
237 HDC hdc
= GetHdcOf((*event
.GetDC()));
240 int mode
= ::SetMapMode(hdc
, MM_TEXT
);
243 ::FillRect(hdc
, &rect
, hBrush
);
244 ::DeleteObject(hBrush
);
247 ::SetMapMode(hdc
, mode
);
251 WXHBRUSH
wxControl::OnCtlColor(WXHDC pDC
, WXHWND
WXUNUSED(pWnd
), WXUINT
WXUNUSED(nCtlColor
),
257 WXUINT
WXUNUSED(message
),
258 WXWPARAM
WXUNUSED(wParam
),
259 WXLPARAM
WXUNUSED(lParam
)
266 HBRUSH hbrush
= Ctl3dCtlColorEx(message
, wParam
, lParam
);
267 return (WXHBRUSH
) hbrush
;
269 #endif // wxUSE_CTL3D
272 wxColour colBack
= GetBackgroundColour();
274 ::SetBkColor(hdc
, wxColourToRGB(colBack
));
275 ::SetTextColor(hdc
, wxColourToRGB(GetForegroundColour()));
277 wxBrush
*brush
= wxTheBrushList
->FindOrCreateBrush(colBack
, wxSOLID
);
279 return (WXHBRUSH
)brush
->GetResourceHandle();
282 WXDWORD
wxControl::MSWGetStyle(long style
, WXDWORD
*exstyle
) const
284 long msStyle
= wxWindow::MSWGetStyle(style
, exstyle
);
286 if ( AcceptsFocus() )
288 msStyle
|= WS_TABSTOP
;
294 // ---------------------------------------------------------------------------
296 // ---------------------------------------------------------------------------
298 // Call this repeatedly for several wnds to find the overall size
300 // Call it initially with -1 for all values in rect.
301 // Keep calling for other widgets, and rect will be modified
302 // to calculate largest bounding rectangle.
303 void wxFindMaxSize(WXHWND wnd
, RECT
*rect
)
305 int left
= rect
->left
;
306 int right
= rect
->right
;
308 int bottom
= rect
->bottom
;
310 GetWindowRect((HWND
) wnd
, rect
);
315 if (left
< rect
->left
)
318 if (right
> rect
->right
)
324 if (bottom
> rect
->bottom
)
325 rect
->bottom
= bottom
;
328 #endif // wxUSE_CONTROLS