]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/control.cpp
Fix for mingw32 compilation (replaced #ifdef NM_CUSTOMDRAW with a test for _WIN32_IE
[wxWidgets.git] / src / msw / control.cpp
... / ...
CommitLineData
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
37IMPLEMENT_ABSTRACT_CLASS(wxControl, wxWindow)
38
39BEGIN_EVENT_TABLE(wxControl, wxWindow)
40 EVT_ERASE_BACKGROUND(wxControl::OnEraseBackground)
41END_EVENT_TABLE()
42
43// Item members
44wxControl::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
54wxControl::~wxControl()
55{
56 m_isBeingDeleted = TRUE;
57}
58
59bool 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
120wxSize wxControl::DoGetBestSize() const
121{
122 return wxSize(DEFAULT_ITEM_WIDTH, DEFAULT_ITEM_HEIGHT);
123}
124
125bool 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__
141bool 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
189void 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
209WXHBRUSH 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
237WXDWORD 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.
258void 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