removed USE_SHARED_LIBRARY(IES)
[wxWidgets.git] / src / msw / control.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: control.cpp
3 // Purpose: wxControl class
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 01/02/97
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "control.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/event.h"
25 #include "wx/app.h"
26 #include "wx/dcclient.h"
27 #endif
28
29 #include "wx/control.h"
30
31 #include "wx/msw/private.h"
32
33 #if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__) || defined(wxUSE_NORLANDER_HEADERS)
34 #include <commctrl.h>
35 #endif
36
37 IMPLEMENT_ABSTRACT_CLASS(wxControl, wxWindow)
38
39 BEGIN_EVENT_TABLE(wxControl, wxWindow)
40 EVT_ERASE_BACKGROUND(wxControl::OnEraseBackground)
41 END_EVENT_TABLE()
42
43 // Item members
44 wxControl::wxControl()
45 {
46 m_backgroundColour = *wxWHITE;
47 m_foregroundColour = *wxBLACK;
48
49 #if WXWIN_COMPATIBILITY
50 m_callback = 0;
51 #endif // WXWIN_COMPATIBILITY
52 }
53
54 wxControl::~wxControl()
55 {
56 m_isBeingDeleted = TRUE;
57 }
58
59 bool wxControl::MSWCreateControl(const wxChar *classname,
60 WXDWORD style,
61 const wxPoint& pos,
62 const wxSize& size,
63 const wxString& label,
64 WXDWORD exstyle)
65 {
66 // VZ: if someone could put a comment here explaining what exactly this is
67 // needed for, it would be nice...
68 bool want3D;
69
70 // if no extended style given, determine it ourselves
71 if ( exstyle == (WXDWORD)-1 )
72 {
73 exstyle = GetExStyle(style, &want3D);
74 }
75
76 // all controls have these childs (wxWindows creates all controls visible
77 // by default)
78 style |= WS_CHILD | WS_VISIBLE;
79
80 m_hWnd = (WXHWND)::CreateWindowEx
81 (
82 exstyle, // extended style
83 classname, // the kind of control to create
84 label, // the window name
85 style, // the window style
86 pos.x, pos.y, // the window position
87 size.x, size.y, // and size
88 GetHwndOf(GetParent()), // parent
89 (HMENU)GetId(), // child id
90 wxGetInstance(), // app instance
91 NULL // creation parameters
92 );
93
94 if ( !m_hWnd )
95 {
96 #ifdef __WXDEBUG__
97 wxLogError(wxT("Failed to create a control of class '%s'"), classname);
98 #endif // DEBUG
99
100 return FALSE;
101 }
102
103 #if wxUSE_CTL3D
104 if ( want3D )
105 {
106 Ctl3dSubclassCtl(GetHwnd());
107 m_useCtl3D = TRUE;
108 }
109 #endif // wxUSE_CTL3D
110
111 // subclass again for purposes of dialog editing mode
112 SubclassWin(m_hWnd);
113
114 // controls use the same font and colours as their parent dialog by default
115 InheritAttributes();
116
117 return TRUE;
118 }
119
120 wxSize wxControl::DoGetBestSize() const
121 {
122 return wxSize(DEFAULT_ITEM_WIDTH, DEFAULT_ITEM_HEIGHT);
123 }
124
125 bool wxControl::ProcessCommand(wxCommandEvent& event)
126 {
127 #if WXWIN_COMPATIBILITY
128 if ( m_callback )
129 {
130 (void)(*m_callback)(this, event);
131
132 return TRUE;
133 }
134 else
135 #endif // WXWIN_COMPATIBILITY
136
137 return GetEventHandler()->ProcessEvent(event);
138 }
139
140 #ifdef __WIN95__
141 bool wxControl::MSWOnNotify(int idCtrl,
142 WXLPARAM lParam,
143 WXLPARAM* result)
144 {
145 wxCommandEvent event(wxEVT_NULL, m_windowId);
146 wxEventType eventType = wxEVT_NULL;
147 NMHDR *hdr1 = (NMHDR*) lParam;
148 switch ( hdr1->code )
149 {
150 case NM_CLICK:
151 eventType = wxEVT_COMMAND_LEFT_CLICK;
152 break;
153
154 case NM_DBLCLK:
155 eventType = wxEVT_COMMAND_LEFT_DCLICK;
156 break;
157
158 case NM_RCLICK:
159 eventType = wxEVT_COMMAND_RIGHT_CLICK;
160 break;
161
162 case NM_RDBLCLK:
163 eventType = wxEVT_COMMAND_RIGHT_DCLICK;
164 break;
165
166 case NM_SETFOCUS:
167 eventType = wxEVT_COMMAND_SET_FOCUS;
168 break;
169
170 case NM_KILLFOCUS:
171 eventType = wxEVT_COMMAND_KILL_FOCUS;
172 break;
173
174 case NM_RETURN:
175 eventType = wxEVT_COMMAND_ENTER;
176 break;
177
178 default:
179 return wxWindow::MSWOnNotify(idCtrl, lParam, result);
180 }
181
182 event.SetEventType(eventType);
183 event.SetEventObject(this);
184
185 return GetEventHandler()->ProcessEvent(event);
186 }
187 #endif // Win95
188
189 void wxControl::OnEraseBackground(wxEraseEvent& event)
190 {
191 // In general, you don't want to erase the background of a control,
192 // or you'll get a flicker.
193 // TODO: move this 'null' function into each control that
194 // might flicker.
195
196 RECT rect;
197 ::GetClientRect(GetHwnd(), &rect);
198
199 HBRUSH hBrush = ::CreateSolidBrush(wxColourToRGB(GetBackgroundColour()));
200
201 HDC hdc = GetHdcOf((*event.GetDC()));
202 int mode = ::SetMapMode(hdc, MM_TEXT);
203
204 ::FillRect(hdc, &rect, hBrush);
205 ::DeleteObject(hBrush);
206 ::SetMapMode(hdc, mode);
207 }
208
209 WXHBRUSH wxControl::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
210 WXUINT message,
211 WXWPARAM wParam,
212 WXLPARAM lParam)
213 {
214 #if wxUSE_CTL3D
215 if ( m_useCtl3D )
216 {
217 HBRUSH hbrush = Ctl3dCtlColorEx(message, wParam, lParam);
218 return (WXHBRUSH) hbrush;
219 }
220 #endif // wxUSE_CTL3D
221
222 HDC hdc = (HDC)pDC;
223 if (GetParent()->GetTransparentBackground())
224 SetBkMode(hdc, TRANSPARENT);
225 else
226 SetBkMode(hdc, OPAQUE);
227
228 const wxColour& colBack = GetBackgroundColour();
229 ::SetBkColor(hdc, wxColourToRGB(colBack));
230 ::SetTextColor(hdc, wxColourToRGB(GetForegroundColour()));
231
232 wxBrush *brush = wxTheBrushList->FindOrCreateBrush(colBack, wxSOLID);
233
234 return (WXHBRUSH)brush->GetResourceHandle();
235 }
236
237 WXDWORD wxControl::GetExStyle(WXDWORD& style, bool *want3D) const
238 {
239 WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, want3D);
240
241 // Even with extended styles, need to combine with WS_BORDER for them to
242 // look right.
243 if ( *want3D || wxStyleHasBorder(m_windowStyle) )
244 style |= WS_BORDER;
245
246 return exStyle;
247 }
248
249 // ---------------------------------------------------------------------------
250 // global functions
251 // ---------------------------------------------------------------------------
252
253 // Call this repeatedly for several wnds to find the overall size
254 // of the widget.
255 // Call it initially with -1 for all values in rect.
256 // Keep calling for other widgets, and rect will be modified
257 // to calculate largest bounding rectangle.
258 void wxFindMaxSize(WXHWND wnd, RECT *rect)
259 {
260 int left = rect->left;
261 int right = rect->right;
262 int top = rect->top;
263 int bottom = rect->bottom;
264
265 GetWindowRect((HWND) wnd, rect);
266
267 if (left < 0)
268 return;
269
270 if (left < rect->left)
271 rect->left = left;
272
273 if (right > rect->right)
274 rect->right = right;
275
276 if (top < rect->top)
277 rect->top = top;
278
279 if (bottom > rect->bottom)
280 rect->bottom = bottom;
281 }
282