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 // choose the position for the control
110 int x
= pos
.x
== -1 ? 0 : pos
.x
,
111 y
= pos
.y
== -1 ? 0 : pos
.y
,
112 w
= size
.x
== -1 ? 0 : size
.x
,
113 h
= size
.y
== -1 ? 0 : size
.y
;
115 // ... and adjust it to account for ap ossible parent frames toolbar
116 AdjustForParentClientOrigin(x
, y
);
118 m_hWnd
= (WXHWND
)::CreateWindowEx
120 exstyle
, // extended style
121 classname
, // the kind of control to create
122 label
, // the window name
123 style
, // the window style
124 x
, y
, w
, h
, // the window position and size
125 GetHwndOf(GetParent()), // parent
126 (HMENU
)GetId(), // child id
127 wxGetInstance(), // app instance
128 NULL
// creation parameters
133 wxLogDebug(wxT("Failed to create a control of class '%s'"), classname
);
134 wxFAIL_MSG(_T("something is very wrong"));
142 Ctl3dSubclassCtl(GetHwnd());
145 #endif // wxUSE_CTL3D
147 // install wxWindows window proc for this window
150 // controls use the same font and colours as their parent dialog by default
153 // set the size now if no initial size specified
154 if ( w
<= 0 || h
<= 0 )
162 wxBorder
wxControl::GetDefaultBorder() const
164 // we want to automatically give controls a sunken style (confusingly,
165 // it may not really mean sunken at all as we map it to WS_EX_CLIENTEDGE
166 // which is not sunken at all under Windows XP -- rather, just the default)
167 return wxBORDER_SUNKEN
;
170 wxSize
wxControl::DoGetBestSize() const
172 return wxSize(DEFAULT_ITEM_WIDTH
, DEFAULT_ITEM_HEIGHT
);
175 bool wxControl::ProcessCommand(wxCommandEvent
& event
)
177 return GetEventHandler()->ProcessEvent(event
);
181 bool wxControl::MSWOnNotify(int idCtrl
,
185 wxEventType eventType
= wxEVT_NULL
;
187 NMHDR
*hdr
= (NMHDR
*) lParam
;
191 eventType
= wxEVT_COMMAND_LEFT_CLICK
;
195 eventType
= wxEVT_COMMAND_LEFT_DCLICK
;
199 eventType
= wxEVT_COMMAND_RIGHT_CLICK
;
203 eventType
= wxEVT_COMMAND_RIGHT_DCLICK
;
207 eventType
= wxEVT_COMMAND_SET_FOCUS
;
211 eventType
= wxEVT_COMMAND_KILL_FOCUS
;
215 eventType
= wxEVT_COMMAND_ENTER
;
219 return wxWindow::MSWOnNotify(idCtrl
, lParam
, result
);
222 wxCommandEvent
event(wxEVT_NULL
, m_windowId
);
223 event
.SetEventType(eventType
);
224 event
.SetEventObject(this);
226 return GetEventHandler()->ProcessEvent(event
);
230 void wxControl::OnEraseBackground(wxEraseEvent
& event
)
232 // notice that this 'dumb' implementation may cause flicker for some of the
233 // controls in which case they should intercept wxEraseEvent and process it
234 // themselves somehow
237 ::GetClientRect(GetHwnd(), &rect
);
239 HBRUSH hBrush
= ::CreateSolidBrush(wxColourToRGB(GetBackgroundColour()));
241 HDC hdc
= GetHdcOf((*event
.GetDC()));
244 int mode
= ::SetMapMode(hdc
, MM_TEXT
);
247 ::FillRect(hdc
, &rect
, hBrush
);
248 ::DeleteObject(hBrush
);
251 ::SetMapMode(hdc
, mode
);
255 WXHBRUSH
wxControl::OnCtlColor(WXHDC pDC
, WXHWND
WXUNUSED(pWnd
), WXUINT
WXUNUSED(nCtlColor
),
261 WXUINT
WXUNUSED(message
),
262 WXWPARAM
WXUNUSED(wParam
),
263 WXLPARAM
WXUNUSED(lParam
)
270 HBRUSH hbrush
= Ctl3dCtlColorEx(message
, wParam
, lParam
);
271 return (WXHBRUSH
) hbrush
;
273 #endif // wxUSE_CTL3D
276 wxColour colBack
= GetBackgroundColour();
278 ::SetBkColor(hdc
, wxColourToRGB(colBack
));
279 ::SetTextColor(hdc
, wxColourToRGB(GetForegroundColour()));
281 wxBrush
*brush
= wxTheBrushList
->FindOrCreateBrush(colBack
, wxSOLID
);
283 return (WXHBRUSH
)brush
->GetResourceHandle();
286 WXDWORD
wxControl::MSWGetStyle(long style
, WXDWORD
*exstyle
) const
288 long msStyle
= wxWindow::MSWGetStyle(style
, exstyle
);
290 if ( AcceptsFocus() )
292 msStyle
|= WS_TABSTOP
;
298 // ---------------------------------------------------------------------------
300 // ---------------------------------------------------------------------------
302 // Call this repeatedly for several wnds to find the overall size
304 // Call it initially with -1 for all values in rect.
305 // Keep calling for other widgets, and rect will be modified
306 // to calculate largest bounding rectangle.
307 void wxFindMaxSize(WXHWND wnd
, RECT
*rect
)
309 int left
= rect
->left
;
310 int right
= rect
->right
;
312 int bottom
= rect
->bottom
;
314 GetWindowRect((HWND
) wnd
, rect
);
319 if (left
< rect
->left
)
322 if (right
> rect
->right
)
328 if (bottom
> rect
->bottom
)
329 rect
->bottom
= bottom
;
332 #endif // wxUSE_CONTROLS