]> git.saurik.com Git - wxWidgets.git/blob - src/msw/button.cpp
if'd out CheckForKeyDown call that doesn't seem to be necessary now (but we still...
[wxWidgets.git] / src / msw / button.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: button.cpp
3 // Purpose: wxButton
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 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19 #ifdef __GNUG__
20 #pragma implementation "button.h"
21 #endif
22
23 // For compilers that support precompilation, includes "wx.h".
24 #include "wx/wxprec.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 #ifndef WX_PRECOMP
31 #include "wx/button.h"
32 #include "wx/brush.h"
33 #include "wx/panel.h"
34 #include "wx/bmpbuttn.h"
35 #include "wx/settings.h"
36 #include "wx/dcscreen.h"
37 #endif
38
39 #include "wx/msw/private.h"
40
41 // ----------------------------------------------------------------------------
42 // macros
43 // ----------------------------------------------------------------------------
44
45 #if !USE_SHARED_LIBRARY
46 IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl)
47 #endif
48
49 // this macro tries to adjust the default button height to a reasonable value
50 // using the char height as the base
51 #define BUTTON_HEIGHT_FROM_CHAR_HEIGHT(cy) (11*EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)/10)
52
53 // ============================================================================
54 // implementation
55 // ============================================================================
56
57 // ----------------------------------------------------------------------------
58 // creation/destruction
59 // ----------------------------------------------------------------------------
60
61 bool wxButton::Create(wxWindow *parent,
62 wxWindowID id,
63 const wxString& label,
64 const wxPoint& pos,
65 const wxSize& size,
66 long style,
67 const wxValidator& validator,
68 const wxString& name)
69 {
70 if ( !CreateBase(parent, id, pos, size, style, validator, name) )
71 return FALSE;
72
73 SetValidator(validator);
74
75 parent->AddChild((wxButton *)this);
76
77 m_backgroundColour = parent->GetBackgroundColour() ;
78 m_foregroundColour = parent->GetForegroundColour() ;
79
80 m_hWnd = (WXHWND)CreateWindowEx
81 (
82 MakeExtendedStyle(m_windowStyle),
83 _T("BUTTON"),
84 label,
85 WS_VISIBLE | WS_TABSTOP | WS_CHILD,
86 0, 0, 0, 0,
87 GetWinHwnd(parent),
88 (HMENU)m_windowId,
89 wxGetInstance(),
90 NULL
91 );
92
93 // Subclass again for purposes of dialog editing mode
94 SubclassWin(m_hWnd);
95
96 SetFont(parent->GetFont());
97
98 SetSize(pos.x, pos.y, size.x, size.y);
99
100 return TRUE;
101 }
102
103 wxButton::~wxButton()
104 {
105 wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
106 if ( panel )
107 {
108 if ( panel->GetDefaultItem() == this )
109 {
110 // don't leave the panel with invalid default item
111 panel->SetDefaultItem(NULL);
112 }
113 }
114 }
115
116 // ----------------------------------------------------------------------------
117 // size management including autosizing
118 // ----------------------------------------------------------------------------
119
120 wxSize wxButton::DoGetBestSize()
121 {
122 wxString label = wxGetWindowText(GetHWND());
123 int wBtn;
124 GetTextExtent(label, &wBtn, NULL);
125
126 int wChar, hChar;
127 wxGetCharSize(GetHWND(), &wChar, &hChar, &GetFont());
128
129 // add a margin - the button is wider than just its label
130 wBtn += 3*wChar;
131
132 // the button height is proportional to the height of the font used
133 int hBtn = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(hChar);
134
135 return wxSize(wBtn, hBtn);
136 }
137
138 /* static */
139 wxSize wxButton::GetDefaultSize()
140 {
141 static wxSize s_sizeBtn;
142
143 if ( s_sizeBtn.x == 0 )
144 {
145 wxScreenDC dc;
146 dc.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
147
148 // the size of a standard button in the dialog units is 50x14,
149 // translate this to pixels
150 // NB1: the multipliers come from the Windows convention
151 // NB2: the extra +1/+2 were needed to get the size be the same as the
152 // size of the buttons in the standard dialog - I don't know how
153 // this happens, but on my system this size is 75x23 in pixels and
154 // 23*8 isn't even divisible by 14... Would be nice to understand
155 // why these constants are needed though!
156 s_sizeBtn.x = (50 * (dc.GetCharWidth() + 1))/4;
157 s_sizeBtn.y = ((14 * dc.GetCharHeight()) + 2)/8;
158 }
159
160 return s_sizeBtn;
161 }
162
163 // ----------------------------------------------------------------------------
164 // set this button as the default one in its panel
165 // ----------------------------------------------------------------------------
166
167 void wxButton::SetDefault()
168 {
169 wxWindow *parent = GetParent();
170 wxButton *btnOldDefault = NULL;
171 wxPanel *panel = wxDynamicCast(parent, wxPanel);
172 if ( panel )
173 {
174 btnOldDefault = panel->GetDefaultItem();
175 panel->SetDefaultItem(this);
176 }
177
178 if ( parent )
179 {
180 SendMessage(GetWinHwnd(parent), DM_SETDEFID, m_windowId, 0L);
181 }
182
183 // this doesn't work with bitmap buttons because it also removes the
184 // "ownerdrawn" style...
185 if ( btnOldDefault && !wxDynamicCast(btnOldDefault, wxBitmapButton) )
186 {
187 // remove the BS_DEFPUSHBUTTON style from the other button
188 long style = GetWindowLong(GetHwndOf(btnOldDefault), GWL_STYLE);
189 style &= ~BS_DEFPUSHBUTTON;
190 SendMessage(GetHwndOf(btnOldDefault), BM_SETSTYLE, style, 1L);
191 }
192
193 // set this button as the default
194 long style = GetWindowLong(GetHwnd(), GWL_STYLE);
195 style |= BS_DEFPUSHBUTTON;
196 SendMessage(GetHwnd(), BM_SETSTYLE, style, 1L);
197 }
198
199 // ----------------------------------------------------------------------------
200 // helpers
201 // ----------------------------------------------------------------------------
202
203 bool wxButton::SendClickEvent()
204 {
205 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
206 event.SetEventObject(this);
207
208 return ProcessCommand(event);
209 }
210
211 void wxButton::Command(wxCommandEvent & event)
212 {
213 ProcessCommand(event);
214 }
215
216 // ----------------------------------------------------------------------------
217 // event/message handlers
218 // ----------------------------------------------------------------------------
219
220 bool wxButton::MSWCommand(WXUINT param, WXWORD id)
221 {
222 bool processed = FALSE;
223 switch ( param )
224 {
225 case 1: // 1 for accelerator
226 case BN_CLICKED:
227 processed = SendClickEvent();
228 break;
229 }
230
231 return processed;
232 }
233
234 WXHBRUSH wxButton::OnCtlColor(WXHDC pDC,
235 WXHWND pWnd,
236 WXUINT nCtlColor,
237 WXUINT message,
238 WXWPARAM wParam,
239 WXLPARAM lParam)
240 {
241 wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
242
243 return (WXHBRUSH) backgroundBrush->GetResourceHandle();
244 }
245