]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/spinbutt.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/spinbutt.cpp
3 // Purpose: wxSpinButton
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
28 #include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly"
34 #include "wx/spinbutt.h"
36 IMPLEMENT_DYNAMIC_CLASS(wxSpinEvent
, wxNotifyEvent
)
38 #include "wx/msw/private.h"
40 #ifndef UDM_SETRANGE32
41 #define UDM_SETRANGE32 (WM_USER+111)
45 #define UDM_SETPOS32 (WM_USER+113)
46 #define UDM_GETPOS32 (WM_USER+114)
49 // ============================================================================
51 // ============================================================================
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
58 #if wxUSE_EXTENDED_RTTI
59 WX_DEFINE_FLAGS( wxSpinButtonStyle
)
61 wxBEGIN_FLAGS( wxSpinButtonStyle
)
62 // new style border flags, we put them first to
63 // use them for streaming out
64 wxFLAGS_MEMBER(wxBORDER_SIMPLE
)
65 wxFLAGS_MEMBER(wxBORDER_SUNKEN
)
66 wxFLAGS_MEMBER(wxBORDER_DOUBLE
)
67 wxFLAGS_MEMBER(wxBORDER_RAISED
)
68 wxFLAGS_MEMBER(wxBORDER_STATIC
)
69 wxFLAGS_MEMBER(wxBORDER_NONE
)
71 // old style border flags
72 wxFLAGS_MEMBER(wxSIMPLE_BORDER
)
73 wxFLAGS_MEMBER(wxSUNKEN_BORDER
)
74 wxFLAGS_MEMBER(wxDOUBLE_BORDER
)
75 wxFLAGS_MEMBER(wxRAISED_BORDER
)
76 wxFLAGS_MEMBER(wxSTATIC_BORDER
)
77 wxFLAGS_MEMBER(wxBORDER
)
79 // standard window styles
80 wxFLAGS_MEMBER(wxTAB_TRAVERSAL
)
81 wxFLAGS_MEMBER(wxCLIP_CHILDREN
)
82 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW
)
83 wxFLAGS_MEMBER(wxWANTS_CHARS
)
84 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE
)
85 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB
)
86 wxFLAGS_MEMBER(wxVSCROLL
)
87 wxFLAGS_MEMBER(wxHSCROLL
)
89 wxFLAGS_MEMBER(wxSP_HORIZONTAL
)
90 wxFLAGS_MEMBER(wxSP_VERTICAL
)
91 wxFLAGS_MEMBER(wxSP_ARROW_KEYS
)
92 wxFLAGS_MEMBER(wxSP_WRAP
)
94 wxEND_FLAGS( wxSpinButtonStyle
)
96 IMPLEMENT_DYNAMIC_CLASS_XTI(wxSpinButton
, wxControl
,"wx/spinbut.h")
98 wxBEGIN_PROPERTIES_TABLE(wxSpinButton
)
99 wxEVENT_RANGE_PROPERTY( Spin
, wxEVT_SCROLL_TOP
, wxEVT_SCROLL_CHANGED
, wxSpinEvent
)
101 wxPROPERTY( Value
, int , SetValue
, GetValue
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
102 wxPROPERTY( Min
, int , SetMin
, GetMin
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
103 wxPROPERTY( Max
, int , SetMax
, GetMax
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
104 wxPROPERTY_FLAGS( WindowStyle
, wxSpinButtonStyle
, long , SetWindowStyleFlag
, GetWindowStyleFlag
, EMPTY_MACROVALUE
, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
105 wxEND_PROPERTIES_TABLE()
107 wxBEGIN_HANDLERS_TABLE(wxSpinButton
)
108 wxEND_HANDLERS_TABLE()
110 wxCONSTRUCTOR_5( wxSpinButton
, wxWindow
* , Parent
, wxWindowID
, Id
, wxPoint
, Position
, wxSize
, Size
, long , WindowStyle
)
112 IMPLEMENT_DYNAMIC_CLASS(wxSpinButton
, wxControl
)
117 // ----------------------------------------------------------------------------
119 // ----------------------------------------------------------------------------
121 bool wxSpinButton::Create(wxWindow
*parent
,
126 const wxString
& name
)
128 // basic initialization
129 m_windowId
= (id
== wxID_ANY
) ? NewControlId() : id
;
138 m_windowStyle
= style
;
142 // get the right size for the control
143 if ( width
<= 0 || height
<= 0 )
145 wxSize size
= DoGetBestSize();
157 // translate the styles
158 DWORD wstyle
= WS_VISIBLE
| WS_CHILD
| WS_TABSTOP
| /* WS_CLIPSIBLINGS | */
159 UDS_NOTHOUSANDS
| // never useful, sometimes harmful
160 UDS_SETBUDDYINT
; // it doesn't harm if we don't have buddy
162 if ( m_windowStyle
& wxCLIP_SIBLINGS
)
163 wstyle
|= WS_CLIPSIBLINGS
;
164 if ( m_windowStyle
& wxSP_HORIZONTAL
)
166 if ( m_windowStyle
& wxSP_ARROW_KEYS
)
167 wstyle
|= UDS_ARROWKEYS
;
168 if ( m_windowStyle
& wxSP_WRAP
)
171 // create the UpDown control.
172 m_hWnd
= (WXHWND
)CreateUpDownControl
181 m_min
// initial position
186 wxLogLastError(wxT("CreateUpDownControl"));
193 parent
->AddChild(this);
198 SetInitialSize(size
);
203 wxSpinButton::~wxSpinButton()
207 // ----------------------------------------------------------------------------
209 // ----------------------------------------------------------------------------
211 wxSize
wxSpinButton::DoGetBestSize() const
213 return GetBestSpinnerSize( (GetWindowStyle() & wxSP_VERTICAL
) != 0 );
216 // ----------------------------------------------------------------------------
218 // ----------------------------------------------------------------------------
220 int wxSpinButton::GetValue() const
224 if ( wxApp::GetComCtl32Version() >= 580 )
226 // use the full 32 bit range if available
227 n
= ::SendMessage(GetHwnd(), UDM_GETPOS32
, 0, 0);
230 #endif // UDM_GETPOS32
232 // we're limited to 16 bit
233 n
= (short)LOWORD(::SendMessage(GetHwnd(), UDM_GETPOS
, 0, 0));
236 if (n
< m_min
) n
= m_min
;
237 if (n
> m_max
) n
= m_max
;
242 void wxSpinButton::SetValue(int val
)
244 // wxSpinButtonBase::SetValue(val); -- no, it is pure virtual
247 if ( wxApp::GetComCtl32Version() >= 580 )
249 // use the full 32 bit range if available
250 ::SendMessage(GetHwnd(), UDM_SETPOS32
, 0, val
);
252 else // we're limited to 16 bit
253 #endif // UDM_SETPOS32
255 ::SendMessage(GetHwnd(), UDM_SETPOS
, 0, MAKELONG((short) val
, 0));
259 void wxSpinButton::NormalizeValue()
261 SetValue( GetValue() );
264 void wxSpinButton::SetRange(int minVal
, int maxVal
)
266 const bool hadRange
= m_min
< m_max
;
268 wxSpinButtonBase::SetRange(minVal
, maxVal
);
270 #ifdef UDM_SETRANGE32
271 if ( wxApp::GetComCtl32Version() >= 471 )
273 // use the full 32 bit range if available
274 ::SendMessage(GetHwnd(), UDM_SETRANGE32
, minVal
, maxVal
);
276 else // we're limited to 16 bit
277 #endif // UDM_SETRANGE32
279 ::SendMessage(GetHwnd(), UDM_SETRANGE
, 0,
280 (LPARAM
) MAKELONG((short)maxVal
, (short)minVal
));
283 // the current value might be out of the new range, force it to be in it
286 // if range was valid but becomes degenerated (min == max) now or vice
287 // versa then the spin buttons are automatically disabled/enabled back
288 // but don't update themselves for some reason, so do it manually
289 if ( hadRange
!= (m_min
< m_max
) )
291 // update the visual state of the button
296 bool wxSpinButton::MSWOnScroll(int WXUNUSED(orientation
), WXWORD wParam
,
297 WXWORD pos
, WXHWND control
)
299 wxCHECK_MSG( control
, false, wxT("scrolling what?") );
301 if ( wParam
!= SB_THUMBPOSITION
)
303 // probable SB_ENDSCROLL - we don't react to it
307 wxSpinEvent
event(wxEVT_SCROLL_THUMBTRACK
, m_windowId
);
308 event
.SetPosition((short)pos
); // cast is important for negative values!
309 event
.SetEventObject(this);
311 return HandleWindowEvent(event
);
314 bool wxSpinButton::MSWOnNotify(int WXUNUSED(idCtrl
), WXLPARAM lParam
, WXLPARAM
*result
)
316 NM_UPDOWN
*lpnmud
= (NM_UPDOWN
*)lParam
;
318 if (lpnmud
->hdr
.hwndFrom
!= GetHwnd()) // make sure it is the right control
321 wxSpinEvent
event(lpnmud
->iDelta
> 0 ? wxEVT_SCROLL_LINEUP
322 : wxEVT_SCROLL_LINEDOWN
,
324 event
.SetPosition(lpnmud
->iPos
+ lpnmud
->iDelta
);
325 event
.SetEventObject(this);
327 bool processed
= HandleWindowEvent(event
);
329 *result
= event
.IsAllowed() ? 0 : 1;
334 bool wxSpinButton::MSWCommand(WXUINT
WXUNUSED(cmd
), WXWORD
WXUNUSED(id
))
336 // No command messages
340 #endif // wxUSE_SPINBTN