added support for right aligned labels (wxALIGN_RIGT maps to BS_LEFTTEXT)
[wxWidgets.git] / src / msw / checkbox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: checkbox.cpp
3 // Purpose: wxCheckBox
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "checkbox.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/checkbox.h"
25 #endif
26
27 #include "wx/msw/private.h"
28
29 #if !USE_SHARED_LIBRARY
30 IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl)
31 IMPLEMENT_DYNAMIC_CLASS(wxBitmapCheckBox, wxCheckBox)
32 #endif
33
34 bool wxCheckBox::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
35 {
36 wxCommandEvent event(wxEVENT_TYPE_CHECKBOX_COMMAND, m_windowId);
37 event.SetInt(GetValue());
38 event.SetEventObject(this);
39 ProcessCommand(event);
40 return TRUE;
41 }
42
43 // Single check box item
44 bool wxCheckBox::Create(wxWindow *parent, wxWindowID id, const wxString& label,
45 const wxPoint& pos,
46 const wxSize& size, long style,
47 const wxValidator& validator,
48 const wxString& name)
49 {
50 SetName(name);
51 SetValidator(validator);
52 if (parent) parent->AddChild(this);
53
54 SetBackgroundColour(parent->GetDefaultBackgroundColour()) ;
55 SetForegroundColour(parent->GetDefaultForegroundColour()) ;
56
57 m_windowStyle = style;
58
59 wxString Label = label;
60 if (Label == "")
61 Label = " "; // Apparently needed or checkbox won't show
62
63 if ( id == -1 )
64 m_windowId = NewControlId();
65 else
66 m_windowId = id;
67
68 int x = pos.x;
69 int y = pos.y;
70 int width = size.x;
71 int height = size.y;
72
73 long msStyle = BS_AUTOCHECKBOX | WS_TABSTOP | WS_CHILD | WS_VISIBLE;
74 if ( style & wxALIGN_RIGHT )
75 msStyle |= BS_LEFTTEXT;
76
77 // We perhaps have different concepts of 3D here - a 3D border,
78 // versus a 3D button.
79 // So we only wish to give a border if this is specified
80 // in the style.
81 bool want3D;
82 WXDWORD exStyle = Determine3DEffects(0, &want3D) ;
83
84 // Even with extended styles, need to combine with WS_BORDER
85 // for them to look right.
86 if (want3D && ((m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
87 (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER)))
88 msStyle |= WS_BORDER;
89
90 m_hWnd = (WXHWND)CreateWindowEx(exStyle, "BUTTON", Label,
91 msStyle,
92 0, 0, 0, 0,
93 (HWND)parent->GetHWND(), (HMENU)m_windowId,
94 wxGetInstance(), NULL);
95
96 #if CTL3D
97 if (want3D)
98 {
99 Ctl3dSubclassCtl((HWND)m_hWnd);
100 m_useCtl3D = TRUE;
101 }
102 #endif
103
104 // Subclass again for purposes of dialog editing mode
105 SubclassWin(m_hWnd);
106
107 SetFont(*parent->GetFont());
108
109 SetSize(x, y, width, height);
110
111 return TRUE;
112 }
113
114 void wxCheckBox::SetLabel(const wxString& label)
115 {
116 SetWindowText((HWND)GetHWND(), label);
117 }
118
119 void wxCheckBox::SetSize(int x, int y, int width, int height, int sizeFlags)
120 {
121 int currentX, currentY;
122 GetPosition(&currentX, &currentY);
123 int x1 = x;
124 int y1 = y;
125 int w1 = width;
126 int h1 = height;
127
128 if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
129 x1 = currentX;
130 if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
131 y1 = currentY;
132
133 AdjustForParentClientOrigin(x1, y1, sizeFlags);
134
135 int current_width, cyf;
136 HWND button = (HWND) GetHWND();
137
138 int nLen = GetWindowTextLength(button);
139 wxString str;
140 GetWindowText(button, str.GetWriteBuf(nLen), nLen);
141 str.UngetWriteBuf();
142
143 if ( !str.IsEmpty() )
144 {
145 GetTextExtent(str, &current_width, &cyf, NULL, NULL, GetFont());
146 if (w1 < 0)
147 w1 = (int)(current_width + RADIO_SIZE);
148 if (h1 < 0)
149 {
150 h1 = (int)(cyf);
151 if (h1 < RADIO_SIZE)
152 h1 = RADIO_SIZE;
153 }
154 }
155 else
156 {
157 if (w1 < 0)
158 w1 = RADIO_SIZE;
159 if (h1 < 0)
160 h1 = RADIO_SIZE;
161 }
162
163 MoveWindow(button, x1, y1, w1, h1, TRUE);
164 }
165
166 void wxCheckBox::SetValue(bool val)
167 {
168 SendMessage((HWND) GetHWND(), BM_SETCHECK, val, 0);
169 }
170
171 bool wxCheckBox::GetValue(void) const
172 {
173 #ifdef __WIN32__
174 return (SendMessage((HWND) GetHWND(), BM_GETCHECK, 0, 0) == BST_CHECKED);
175 #else
176 return ((0x003 & SendMessage((HWND) GetHWND(), BM_GETCHECK, 0, 0)) == 0x003);
177 #endif
178 }
179
180 WXHBRUSH wxCheckBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
181 WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
182 {
183 #if CTL3D
184 if ( m_useCtl3D )
185 {
186 HBRUSH hbrush = Ctl3dCtlColorEx(message, wParam, lParam);
187
188 return (WXHBRUSH) hbrush;
189 }
190 #endif
191
192 if (GetParent()->GetTransparentBackground())
193 SetBkMode((HDC) pDC, TRANSPARENT);
194 else
195 SetBkMode((HDC) pDC, OPAQUE);
196
197 ::SetBkColor((HDC) pDC, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
198 ::SetTextColor((HDC) pDC, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue()));
199
200 wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
201
202 // Note that this will be cleaned up in wxApp::OnIdle, if backgroundBrush
203 // has a zero usage count.
204 // backgroundBrush->RealizeResource();
205 return (WXHBRUSH) backgroundBrush->GetResourceHandle();
206 }
207
208 void wxCheckBox::Command (wxCommandEvent & event)
209 {
210 SetValue ((event.GetInt() != 0));
211 ProcessCommand (event);
212 }
213
214 bool wxBitmapCheckBox::Create(wxWindow *parent, wxWindowID id, const wxBitmap *label,
215 const wxPoint& pos,
216 const wxSize& size, long style,
217 const wxValidator& validator,
218 const wxString& name)
219 {
220 SetName(name);
221 SetValidator(validator);
222 if (parent) parent->AddChild(this);
223
224 SetBackgroundColour(parent->GetDefaultBackgroundColour()) ;
225 SetForegroundColour(parent->GetDefaultForegroundColour()) ;
226 m_windowStyle = style;
227
228 if ( id == -1 )
229 m_windowId = NewControlId();
230 else
231 m_windowId = id;
232
233 int x = pos.x;
234 int y = pos.y;
235 int width = size.x;
236 int height = size.y;
237
238 checkWidth = -1 ;
239 checkHeight = -1 ;
240 long msStyle = CHECK_FLAGS;
241
242 HWND wx_button = CreateWindowEx(MakeExtendedStyle(m_windowStyle), CHECK_CLASS, "toggle",
243 msStyle,
244 0, 0, 0, 0, (HWND) parent->GetHWND(), (HMENU)m_windowId,
245 wxGetInstance(), NULL);
246
247 #if CTL3D
248 if (!(GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS))
249 {
250 Ctl3dSubclassCtl(wx_button);
251 m_useCtl3D = TRUE;
252 }
253 #endif
254
255 m_hWnd = (WXHWND)wx_button;
256
257 // Subclass again for purposes of dialog editing mode
258 SubclassWin((WXHWND)wx_button);
259
260 // SetFont(parent->GetFont());
261
262 SetSize(x, y, width, height);
263
264 ShowWindow(wx_button, SW_SHOW);
265 return TRUE;
266 }
267
268 void wxBitmapCheckBox::SetLabel(const wxBitmap *bitmap)
269 {
270 }
271
272 void wxBitmapCheckBox::SetSize(int x, int y, int width, int height, int sizeFlags)
273 {
274 int currentX, currentY;
275 GetPosition(&currentX, &currentY);
276
277 int x1 = x;
278 int y1 = y;
279 int w1 = width;
280 int h1 = height;
281
282 if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
283 x1 = currentX;
284 if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
285 y1 = currentY;
286
287 AdjustForParentClientOrigin(x1, y1, sizeFlags);
288
289 HWND button = (HWND) GetHWND();
290 /*
291 if (w1<0)
292 w1 = checkWidth + FB_MARGIN ;
293 if (h1<0)
294 h1 = checkHeight + FB_MARGIN ;
295 */
296 MoveWindow(button, x1, y1, w1, h1, TRUE);
297 }
298
299 void wxBitmapCheckBox::SetValue(bool val)
300 {
301 SendMessage((HWND) GetHWND(), BM_SETCHECK, val, 0);
302 }
303
304 bool wxBitmapCheckBox::GetValue(void) const
305 {
306 return ((0x003 & SendMessage((HWND) GetHWND(), BM_GETCHECK, 0, 0)) == 0x003);
307 }
308
309