1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "spinbutt.h"
22 #pragma implementation "spinbutbase.h"
25 // For compilers that support precompilation, includes "wx.h".
26 #include "wx/wxprec.h"
38 #include "wx/spinbutt.h"
40 IMPLEMENT_DYNAMIC_CLASS(wxSpinEvent
, wxNotifyEvent
)
42 #if defined(__WIN95__)
44 #include "wx/msw/private.h"
46 #if defined(__WIN95__) && !(defined(__GNUWIN32_OLD__) && !defined(__CYGWIN10__))
50 // ============================================================================
52 // ============================================================================
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
59 #if wxUSE_EXTENDED_RTTI
60 WX_DEFINE_FLAGS( wxSpinButtonStyle
)
62 WX_BEGIN_FLAGS( wxSpinButtonStyle
)
63 // new style border flags, we put them first to
64 // use them for streaming out
65 WX_FLAGS_MEMBER(wxBORDER_SIMPLE
)
66 WX_FLAGS_MEMBER(wxBORDER_SUNKEN
)
67 WX_FLAGS_MEMBER(wxBORDER_DOUBLE
)
68 WX_FLAGS_MEMBER(wxBORDER_RAISED
)
69 WX_FLAGS_MEMBER(wxBORDER_STATIC
)
70 WX_FLAGS_MEMBER(wxBORDER_NONE
)
72 // old style border flags
73 WX_FLAGS_MEMBER(wxSIMPLE_BORDER
)
74 WX_FLAGS_MEMBER(wxSUNKEN_BORDER
)
75 WX_FLAGS_MEMBER(wxDOUBLE_BORDER
)
76 WX_FLAGS_MEMBER(wxRAISED_BORDER
)
77 WX_FLAGS_MEMBER(wxSTATIC_BORDER
)
78 WX_FLAGS_MEMBER(wxNO_BORDER
)
80 // standard window styles
81 WX_FLAGS_MEMBER(wxTAB_TRAVERSAL
)
82 WX_FLAGS_MEMBER(wxCLIP_CHILDREN
)
83 WX_FLAGS_MEMBER(wxTRANSPARENT_WINDOW
)
84 WX_FLAGS_MEMBER(wxWANTS_CHARS
)
85 WX_FLAGS_MEMBER(wxNO_FULL_REPAINT_ON_RESIZE
)
86 WX_FLAGS_MEMBER(wxALWAYS_SHOW_SB
)
87 WX_FLAGS_MEMBER(wxVSCROLL
)
88 WX_FLAGS_MEMBER(wxHSCROLL
)
90 WX_FLAGS_MEMBER(wxSP_HORIZONTAL
)
91 WX_FLAGS_MEMBER(wxSP_VERTICAL
)
92 WX_FLAGS_MEMBER(wxSP_ARROW_KEYS
)
93 WX_FLAGS_MEMBER(wxSP_WRAP
)
95 WX_END_FLAGS( wxSpinButtonStyle
)
97 IMPLEMENT_DYNAMIC_CLASS_XTI(wxSpinButton
, wxControl
,"wx/spinbut.h")
99 WX_BEGIN_PROPERTIES_TABLE(wxSpinButton
)
100 WX_PROPERTY( Value
, int , SetValue
, GetValue
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
101 WX_PROPERTY( Min
, int , SetMin
, GetMin
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
102 WX_PROPERTY( Max
, int , SetMax
, GetMax
, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
103 WX_PROPERTY_FLAGS( WindowStyle
, wxSpinButtonStyle
, long , SetWindowStyleFlag
, GetWindowStyleFlag
, , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
106 style wxSP_VERTICAL | wxSP_ARROW_KEYS
108 WX_END_PROPERTIES_TABLE()
110 WX_BEGIN_HANDLERS_TABLE(wxSpinButton
)
111 WX_END_HANDLERS_TABLE()
113 WX_CONSTRUCTOR_5( wxSpinButton
, wxWindow
* , Parent
, wxWindowID
, Id
, wxPoint
, Position
, wxSize
, Size
, long , WindowStyle
)
115 IMPLEMENT_DYNAMIC_CLASS(wxSpinButton
, wxControl
)
120 // ----------------------------------------------------------------------------
122 // ----------------------------------------------------------------------------
124 bool wxSpinButton::Create(wxWindow
*parent
,
129 const wxString
& name
)
131 // basic initialization
134 m_windowId
= (id
== -1) ? NewControlId() : id
;
136 m_backgroundColour
= parent
->GetBackgroundColour() ;
137 m_foregroundColour
= parent
->GetForegroundColour() ;
146 m_windowStyle
= style
;
150 // get the right size for the control
151 if ( width
<= 0 || height
<= 0 )
153 wxSize size
= DoGetBestSize();
165 // translate the styles
166 DWORD wstyle
= WS_VISIBLE
| WS_CHILD
| WS_TABSTOP
| /* WS_CLIPSIBLINGS | */
167 UDS_NOTHOUSANDS
| // never useful, sometimes harmful
168 UDS_SETBUDDYINT
; // it doesn't harm if we don't have buddy
170 if ( m_windowStyle
& wxCLIP_SIBLINGS
)
171 wstyle
|= WS_CLIPSIBLINGS
;
172 if ( m_windowStyle
& wxSP_HORIZONTAL
)
174 if ( m_windowStyle
& wxSP_ARROW_KEYS
)
175 wstyle
|= UDS_ARROWKEYS
;
176 if ( m_windowStyle
& wxSP_WRAP
)
179 // create the UpDown control.
180 m_hWnd
= (WXHWND
)CreateUpDownControl
189 m_min
// initial position
194 wxLogLastError(wxT("CreateUpDownControl"));
201 parent
->AddChild(this);
209 wxSpinButton::~wxSpinButton()
213 // ----------------------------------------------------------------------------
215 // ----------------------------------------------------------------------------
217 wxSize
wxSpinButton::DoGetBestSize() const
219 if ( (GetWindowStyle() & wxSP_VERTICAL
) != 0 )
222 return wxSize(GetSystemMetrics(SM_CXVSCROLL
),
223 2*GetSystemMetrics(SM_CYVSCROLL
));
227 // horizontal control
228 return wxSize(2*GetSystemMetrics(SM_CXHSCROLL
),
229 GetSystemMetrics(SM_CYHSCROLL
));
233 // ----------------------------------------------------------------------------
235 // ----------------------------------------------------------------------------
237 int wxSpinButton::GetValue() const
240 if ( wxTheApp
->GetComCtl32Version() >= 580 )
242 // use the full 32 bit range if available
243 return ::SendMessage(GetHwnd(), UDM_GETPOS32
, 0, 0);
245 #endif // UDM_GETPOS32
247 // we're limited to 16 bit
248 return (short)LOWORD(::SendMessage(GetHwnd(), UDM_GETPOS
, 0, 0));
251 void wxSpinButton::SetValue(int val
)
253 // wxSpinButtonBase::SetValue(val); -- no, it is pure virtual
256 if ( wxTheApp
->GetComCtl32Version() >= 580 )
258 // use the full 32 bit range if available
259 ::SendMessage(GetHwnd(), UDM_SETPOS32
, 0, val
);
261 else // we're limited to 16 bit
262 #endif // UDM_SETPOS32
264 ::SendMessage(GetHwnd(), UDM_SETPOS
, 0, MAKELONG((short) val
, 0));
268 void wxSpinButton::SetRange(int minVal
, int maxVal
)
270 wxSpinButtonBase::SetRange(minVal
, maxVal
);
272 #ifdef UDM_SETRANGE32
273 if ( wxTheApp
->GetComCtl32Version() >= 471 )
275 // use the full 32 bit range if available
276 ::SendMessage(GetHwnd(), UDM_SETRANGE32
, minVal
, maxVal
);
278 else // we're limited to 16 bit
279 #endif // UDM_SETRANGE32
281 ::SendMessage(GetHwnd(), UDM_SETRANGE
, 0,
282 (LPARAM
) MAKELONG((short)maxVal
, (short)minVal
));
286 bool wxSpinButton::MSWOnScroll(int WXUNUSED(orientation
), WXWORD wParam
,
287 WXWORD pos
, WXHWND control
)
289 wxCHECK_MSG( control
, FALSE
, wxT("scrolling what?") )
291 if ( wParam
!= SB_THUMBPOSITION
)
293 // probable SB_ENDSCROLL - we don't react to it
297 wxSpinEvent
event(wxEVT_SCROLL_THUMBTRACK
, m_windowId
);
298 event
.SetPosition((short)pos
); // cast is important for negative values!
299 event
.SetEventObject(this);
301 return GetEventHandler()->ProcessEvent(event
);
304 bool wxSpinButton::MSWOnNotify(int WXUNUSED(idCtrl
), WXLPARAM lParam
, WXLPARAM
*result
)
306 NM_UPDOWN
*lpnmud
= (NM_UPDOWN
*)lParam
;
308 if (lpnmud
->hdr
.hwndFrom
!= GetHwnd()) // make sure it is the right control
311 wxSpinEvent
event(lpnmud
->iDelta
> 0 ? wxEVT_SCROLL_LINEUP
312 : wxEVT_SCROLL_LINEDOWN
,
314 event
.SetPosition(lpnmud
->iPos
+ lpnmud
->iDelta
);
315 event
.SetEventObject(this);
317 bool processed
= GetEventHandler()->ProcessEvent(event
);
319 *result
= event
.IsAllowed() ? 0 : 1;
324 bool wxSpinButton::MSWCommand(WXUINT
WXUNUSED(cmd
), WXWORD
WXUNUSED(id
))
326 // No command messages