]> git.saurik.com Git - wxWidgets.git/blame - 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
2bda0e17
KB
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
a23fd0e1 9// Licence: wxWindows licence
2bda0e17
KB
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
2432b92d 24#include "wx/event.h"
2bda0e17
KB
25#include "wx/app.h"
26#include "wx/dcclient.h"
27#endif
28
2432b92d
JS
29#include "wx/control.h"
30
2bda0e17
KB
31#include "wx/msw/private.h"
32
65fd5cb0 33#if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__) || defined(wxUSE_NORLANDER_HEADERS)
2bda0e17
KB
34#include <commctrl.h>
35#endif
36
2bda0e17
KB
37IMPLEMENT_ABSTRACT_CLASS(wxControl, wxWindow)
38
39BEGIN_EVENT_TABLE(wxControl, wxWindow)
a23fd0e1 40 EVT_ERASE_BACKGROUND(wxControl::OnEraseBackground)
2bda0e17 41END_EVENT_TABLE()
2bda0e17
KB
42
43// Item members
42e69d6b 44wxControl::wxControl()
2bda0e17 45{
3f2711d5
VZ
46 m_backgroundColour = *wxWHITE;
47 m_foregroundColour = *wxBLACK;
42e69d6b
VZ
48
49#if WXWIN_COMPATIBILITY
3f2711d5 50 m_callback = 0;
42e69d6b 51#endif // WXWIN_COMPATIBILITY
2bda0e17
KB
52}
53
42e69d6b 54wxControl::~wxControl()
2bda0e17 55{
42e69d6b 56 m_isBeingDeleted = TRUE;
2bda0e17
KB
57}
58
222594ea
VZ
59bool wxControl::MSWCreateControl(const wxChar *classname,
60 WXDWORD style,
61 const wxPoint& pos,
62 const wxSize& size,
63 const wxString& label,
64 WXDWORD exstyle)
8d99be5f 65{
3f2711d5
VZ
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
222594ea
VZ
70 // if no extended style given, determine it ourselves
71 if ( exstyle == (WXDWORD)-1 )
72 {
73 exstyle = GetExStyle(style, &want3D);
74 }
75
3f2711d5
VZ
76 // all controls have these childs (wxWindows creates all controls visible
77 // by default)
78 style |= WS_CHILD | WS_VISIBLE;
79
8d99be5f
VZ
80 m_hWnd = (WXHWND)::CreateWindowEx
81 (
222594ea 82 exstyle, // extended style
8d99be5f 83 classname, // the kind of control to create
222594ea 84 label, // the window name
8d99be5f 85 style, // the window style
222594ea
VZ
86 pos.x, pos.y, // the window position
87 size.x, size.y, // and size
8d99be5f
VZ
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__
223d09f6 97 wxLogError(wxT("Failed to create a control of class '%s'"), classname);
8d99be5f
VZ
98#endif // DEBUG
99
100 return FALSE;
101 }
102
3f2711d5
VZ
103#if wxUSE_CTL3D
104 if ( want3D )
105 {
106 Ctl3dSubclassCtl(GetHwnd());
107 m_useCtl3D = TRUE;
108 }
109#endif // wxUSE_CTL3D
110
8d99be5f
VZ
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
f68586e5 120wxSize wxControl::DoGetBestSize() const
4438caf4
VZ
121{
122 return wxSize(DEFAULT_ITEM_WIDTH, DEFAULT_ITEM_HEIGHT);
123}
124
42e69d6b 125bool wxControl::ProcessCommand(wxCommandEvent& event)
2bda0e17 126{
42e69d6b
VZ
127#if WXWIN_COMPATIBILITY
128 if ( m_callback )
129 {
130 (void)(*m_callback)(this, event);
2bda0e17 131
42e69d6b
VZ
132 return TRUE;
133 }
134 else
135#endif // WXWIN_COMPATIBILITY
2bda0e17 136
42e69d6b 137 return GetEventHandler()->ProcessEvent(event);
2bda0e17
KB
138}
139
a23fd0e1
VZ
140#ifdef __WIN95__
141bool wxControl::MSWOnNotify(int idCtrl,
142 WXLPARAM lParam,
143 WXLPARAM* result)
2bda0e17 144{
a23fd0e1
VZ
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;
2bda0e17 153
a23fd0e1
VZ
154 case NM_DBLCLK:
155 eventType = wxEVT_COMMAND_LEFT_DCLICK;
156 break;
2bda0e17 157
a23fd0e1
VZ
158 case NM_RCLICK:
159 eventType = wxEVT_COMMAND_RIGHT_CLICK;
160 break;
2bda0e17 161
a23fd0e1
VZ
162 case NM_RDBLCLK:
163 eventType = wxEVT_COMMAND_RIGHT_DCLICK;
164 break;
2bda0e17 165
a23fd0e1
VZ
166 case NM_SETFOCUS:
167 eventType = wxEVT_COMMAND_SET_FOCUS;
168 break;
debe6624 169
a23fd0e1
VZ
170 case NM_KILLFOCUS:
171 eventType = wxEVT_COMMAND_KILL_FOCUS;
172 break;
2bda0e17 173
a23fd0e1
VZ
174 case NM_RETURN:
175 eventType = wxEVT_COMMAND_ENTER;
176 break;
177
178 default:
179 return wxWindow::MSWOnNotify(idCtrl, lParam, result);
180 }
fd3f686c 181
2bda0e17 182 event.SetEventType(eventType);
a23fd0e1 183 event.SetEventObject(this);
2bda0e17 184
a23fd0e1 185 return GetEventHandler()->ProcessEvent(event);
2bda0e17 186}
a23fd0e1 187#endif // Win95
2bda0e17 188
2bda0e17
KB
189void wxControl::OnEraseBackground(wxEraseEvent& event)
190{
42e69d6b
VZ
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;
3f2711d5 197 ::GetClientRect(GetHwnd(), &rect);
42e69d6b 198
3f2711d5 199 HBRUSH hBrush = ::CreateSolidBrush(wxColourToRGB(GetBackgroundColour()));
42e69d6b 200
3f2711d5
VZ
201 HDC hdc = GetHdcOf((*event.GetDC()));
202 int mode = ::SetMapMode(hdc, MM_TEXT);
203
204 ::FillRect(hdc, &rect, hBrush);
42e69d6b 205 ::DeleteObject(hBrush);
3f2711d5 206 ::SetMapMode(hdc, mode);
2bda0e17
KB
207}
208
f048e32f
VZ
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
3f2711d5 237WXDWORD wxControl::GetExStyle(WXDWORD& style, bool *want3D) const
8d99be5f 238{
3f2711d5 239 WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, want3D);
8d99be5f 240
3f2711d5
VZ
241 // Even with extended styles, need to combine with WS_BORDER for them to
242 // look right.
243 if ( *want3D || wxStyleHasBorder(m_windowStyle) )
8d99be5f
VZ
244 style |= WS_BORDER;
245
246 return exStyle;
247}
248
42e69d6b
VZ
249// ---------------------------------------------------------------------------
250// global functions
251// ---------------------------------------------------------------------------
2bda0e17 252
42e69d6b
VZ
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)
2bda0e17 259{
42e69d6b
VZ
260 int left = rect->left;
261 int right = rect->right;
262 int top = rect->top;
263 int bottom = rect->bottom;
2bda0e17 264
42e69d6b 265 GetWindowRect((HWND) wnd, rect);
2bda0e17 266
42e69d6b
VZ
267 if (left < 0)
268 return;
2bda0e17 269
42e69d6b
VZ
270 if (left < rect->left)
271 rect->left = left;
2bda0e17 272
42e69d6b
VZ
273 if (right > rect->right)
274 rect->right = right;
2bda0e17 275
42e69d6b
VZ
276 if (top < rect->top)
277 rect->top = top;
2bda0e17 278
42e69d6b
VZ
279 if (bottom > rect->bottom)
280 rect->bottom = bottom;
2bda0e17
KB
281}
282