/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/msw/spinctrl.cpp
ViewVC logotype

Annotation of /branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/msw/spinctrl.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (hide annotations) (download)
Tue Sep 7 03:29:01 2010 UTC (10 years ago) by william
File size: 22307 byte(s)
branching from upstream revision (http://pcsx2.googlecode.com/svn/trunk
): r3113 to
https://svn.netsolutions.dnsalias.com/websvn/ps2/pcsx2/pcsx2_0.9.7/branch/r3113_0.9.7_beta
1 william 31 /////////////////////////////////////////////////////////////////////////////
2     // Name: src/msw/spinctrl.cpp
3     // Purpose: wxSpinCtrl class implementation for Win32
4     // Author: Vadim Zeitlin
5     // Modified by:
6     // Created: 22.07.99
7     // RCS-ID: $Id: spinctrl.cpp 55622 2008-09-14 19:56:14Z VZ $
8     // Copyright: (c) 1999-2005 Vadim Zeitlin
9     // Licence: wxWindows licence
10     /////////////////////////////////////////////////////////////////////////////
11    
12     // ============================================================================
13     // declarations
14     // ============================================================================
15    
16     // ----------------------------------------------------------------------------
17     // headers
18     // ----------------------------------------------------------------------------
19    
20     // for compilers that support precompilation, includes "wx.h".
21     #include "wx/wxprec.h"
22    
23     #ifdef __BORLANDC__
24     #pragma hdrstop
25     #endif
26    
27     #if wxUSE_SPINCTRL
28    
29     #include "wx/spinctrl.h"
30    
31     #ifndef WX_PRECOMP
32     #include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly"
33     #include "wx/event.h"
34     #include "wx/textctrl.h"
35     #endif
36    
37     #include "wx/msw/private.h"
38    
39     #if wxUSE_TOOLTIPS
40     #include "wx/tooltip.h"
41     #endif // wxUSE_TOOLTIPS
42    
43     #include <limits.h> // for INT_MIN
44    
45     // ----------------------------------------------------------------------------
46     // macros
47     // ----------------------------------------------------------------------------
48    
49     #if wxUSE_EXTENDED_RTTI
50     WX_DEFINE_FLAGS( wxSpinCtrlStyle )
51    
52     wxBEGIN_FLAGS( wxSpinCtrlStyle )
53     // new style border flags, we put them first to
54     // use them for streaming out
55     wxFLAGS_MEMBER(wxBORDER_SIMPLE)
56     wxFLAGS_MEMBER(wxBORDER_SUNKEN)
57     wxFLAGS_MEMBER(wxBORDER_DOUBLE)
58     wxFLAGS_MEMBER(wxBORDER_RAISED)
59     wxFLAGS_MEMBER(wxBORDER_STATIC)
60     wxFLAGS_MEMBER(wxBORDER_NONE)
61    
62     // old style border flags
63     wxFLAGS_MEMBER(wxSIMPLE_BORDER)
64     wxFLAGS_MEMBER(wxSUNKEN_BORDER)
65     wxFLAGS_MEMBER(wxDOUBLE_BORDER)
66     wxFLAGS_MEMBER(wxRAISED_BORDER)
67     wxFLAGS_MEMBER(wxSTATIC_BORDER)
68     wxFLAGS_MEMBER(wxBORDER)
69    
70     // standard window styles
71     wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
72     wxFLAGS_MEMBER(wxCLIP_CHILDREN)
73     wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
74     wxFLAGS_MEMBER(wxWANTS_CHARS)
75     wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
76     wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
77     wxFLAGS_MEMBER(wxVSCROLL)
78     wxFLAGS_MEMBER(wxHSCROLL)
79    
80     wxFLAGS_MEMBER(wxSP_HORIZONTAL)
81     wxFLAGS_MEMBER(wxSP_VERTICAL)
82     wxFLAGS_MEMBER(wxSP_ARROW_KEYS)
83     wxFLAGS_MEMBER(wxSP_WRAP)
84    
85     wxEND_FLAGS( wxSpinCtrlStyle )
86    
87     IMPLEMENT_DYNAMIC_CLASS_XTI(wxSpinCtrl, wxControl,"wx/spinbut.h")
88    
89     wxBEGIN_PROPERTIES_TABLE(wxSpinCtrl)
90     wxEVENT_RANGE_PROPERTY( Spin , wxEVT_SCROLL_TOP , wxEVT_SCROLL_CHANGED , wxSpinEvent )
91     wxEVENT_PROPERTY( Updated , wxEVT_COMMAND_SPINCTRL_UPDATED , wxCommandEvent )
92     wxEVENT_PROPERTY( TextUpdated , wxEVT_COMMAND_TEXT_UPDATED , wxCommandEvent )
93     wxEVENT_PROPERTY( TextEnter , wxEVT_COMMAND_TEXT_ENTER , wxCommandEvent )
94    
95     wxPROPERTY( ValueString , wxString , SetValue , GetValue , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) ;
96     wxPROPERTY( Value , int , SetValue, GetValue, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
97     wxPROPERTY( Min , int , SetMin, GetMin, 0, 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
98     wxPROPERTY( Max , int , SetMax, GetMax, 0 , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
99     wxPROPERTY_FLAGS( WindowStyle , wxSpinCtrlStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
100     /*
101     TODO PROPERTIES
102     style wxSP_ARROW_KEYS
103     */
104     wxEND_PROPERTIES_TABLE()
105    
106     wxBEGIN_HANDLERS_TABLE(wxSpinCtrl)
107     wxEND_HANDLERS_TABLE()
108    
109     wxCONSTRUCTOR_6( wxSpinCtrl , wxWindow* , Parent , wxWindowID , Id , wxString , ValueString , wxPoint , Position , wxSize , Size , long , WindowStyle )
110     #else
111     IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
112     #endif
113    
114     BEGIN_EVENT_TABLE(wxSpinCtrl, wxSpinButton)
115     EVT_CHAR(wxSpinCtrl::OnChar)
116    
117     EVT_SET_FOCUS(wxSpinCtrl::OnSetFocus)
118     EVT_KILL_FOCUS(wxSpinCtrl::OnKillFocus)
119     EVT_SPIN(wxID_ANY, wxSpinCtrl::OnSpinChange)
120     END_EVENT_TABLE()
121    
122     #define GetBuddyHwnd() (HWND)(m_hwndBuddy)
123    
124     // ----------------------------------------------------------------------------
125     // constants
126     // ----------------------------------------------------------------------------
127    
128     // the margin between the up-down control and its buddy (can be arbitrary,
129     // choose what you like - or may be decide during run-time depending on the
130     // font size?)
131     static const int MARGIN_BETWEEN = 1;
132    
133     // ============================================================================
134     // implementation
135     // ============================================================================
136    
137     wxArraySpins wxSpinCtrl::ms_allSpins;
138    
139     // ----------------------------------------------------------------------------
140     // wnd proc for the buddy text ctrl
141     // ----------------------------------------------------------------------------
142    
143     LRESULT APIENTRY _EXPORT wxBuddyTextWndProc(HWND hwnd,
144     UINT message,
145     WPARAM wParam,
146     LPARAM lParam)
147     {
148     wxSpinCtrl *spin = (wxSpinCtrl *)wxGetWindowUserData(hwnd);
149    
150     // forward some messages (mostly the key and focus ones) to the spin ctrl
151     switch ( message )
152     {
153     case WM_SETFOCUS:
154     // if the focus comes from the spin control itself, don't set it
155     // back to it -- we don't want to go into an infinite loop
156     if ( (WXHWND)wParam == spin->GetHWND() )
157     break;
158     //else: fall through
159    
160     case WM_KILLFOCUS:
161     case WM_CHAR:
162     case WM_DEADCHAR:
163     case WM_KEYUP:
164     case WM_KEYDOWN:
165     #ifdef WM_HELP
166     // we need to forward WM_HELP too to ensure that the context help
167     // associated with wxSpinCtrl is shown when the text control part of it
168     // is clicked with the "?" cursor
169     case WM_HELP:
170     #endif
171     spin->MSWWindowProc(message, wParam, lParam);
172    
173     // The control may have been deleted at this point, so check.
174     if ( !::IsWindow(hwnd) || wxGetWindowUserData(hwnd) != spin )
175     return 0;
176     break;
177    
178     case WM_GETDLGCODE:
179     if ( spin->HasFlag(wxTE_PROCESS_ENTER) )
180     {
181     long dlgCode = ::CallWindowProc
182     (
183     CASTWNDPROC spin->GetBuddyWndProc(),
184     hwnd,
185     message,
186     wParam,
187     lParam
188     );
189     dlgCode |= DLGC_WANTMESSAGE;
190     return dlgCode;
191     }
192     break;
193     }
194    
195     return ::CallWindowProc(CASTWNDPROC spin->GetBuddyWndProc(),
196     hwnd, message, wParam, lParam);
197     }
198    
199     /* static */
200     wxSpinCtrl *wxSpinCtrl::GetSpinForTextCtrl(WXHWND hwndBuddy)
201     {
202     wxSpinCtrl *spin = (wxSpinCtrl *)wxGetWindowUserData((HWND)hwndBuddy);
203    
204     int i = ms_allSpins.Index(spin);
205    
206     if ( i == wxNOT_FOUND )
207     return NULL;
208    
209     // sanity check
210     wxASSERT_MSG( spin->m_hwndBuddy == hwndBuddy,
211     _T("wxSpinCtrl has incorrect buddy HWND!") );
212    
213     return spin;
214     }
215    
216     // process a WM_COMMAND generated by the buddy text control
217     bool wxSpinCtrl::ProcessTextCommand(WXWORD cmd, WXWORD WXUNUSED(id))
218     {
219     if ( cmd == EN_CHANGE )
220     {
221     wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
222     event.SetEventObject(this);
223     wxString val = wxGetWindowText(m_hwndBuddy);
224     event.SetString(val);
225     event.SetInt(GetValue());
226     return GetEventHandler()->ProcessEvent(event);
227     }
228    
229     // not processed
230     return false;
231     }
232    
233     void wxSpinCtrl::OnChar(wxKeyEvent& event)
234     {
235     switch ( event.GetKeyCode() )
236     {
237     case WXK_RETURN:
238     {
239     wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
240     InitCommandEvent(event);
241     wxString val = wxGetWindowText(m_hwndBuddy);
242     event.SetString(val);
243     event.SetInt(GetValue());
244     if ( GetEventHandler()->ProcessEvent(event) )
245     return;
246     break;
247     }
248    
249     case WXK_TAB:
250     // always produce navigation event - even if we process TAB
251     // ourselves the fact that we got here means that the user code
252     // decided to skip processing of this TAB - probably to let it
253     // do its default job.
254     {
255     wxNavigationKeyEvent eventNav;
256     eventNav.SetDirection(!event.ShiftDown());
257     eventNav.SetWindowChange(event.ControlDown());
258     eventNav.SetEventObject(this);
259    
260     if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
261     return;
262     }
263     break;
264     }
265    
266     // no, we didn't process it
267     event.Skip();
268     }
269    
270     void wxSpinCtrl::OnKillFocus(wxFocusEvent& event)
271     {
272     // ensure that a correct value is shown by the control
273     NormalizeValue();
274     event.Skip();
275     }
276    
277     void wxSpinCtrl::OnSetFocus(wxFocusEvent& event)
278     {
279     // when we get focus, give it to our buddy window as it needs it more than
280     // we do
281     ::SetFocus((HWND)m_hwndBuddy);
282    
283     event.Skip();
284     }
285    
286     void wxSpinCtrl::NormalizeValue()
287     {
288     const int value = GetValue();
289     const bool changed = value != m_oldValue;
290    
291     // notice that we have to call SetValue() even if the value didn't change
292     // because otherwise we could be left with empty buddy control when value
293     // is 0, see comment in SetValue()
294     SetValue(value);
295    
296     if ( changed )
297     {
298     SendSpinUpdate(value);
299     }
300     }
301    
302     // ----------------------------------------------------------------------------
303     // construction
304     // ----------------------------------------------------------------------------
305    
306     bool wxSpinCtrl::Create(wxWindow *parent,
307     wxWindowID id,
308     const wxString& value,
309     const wxPoint& pos,
310     const wxSize& size,
311     long style,
312     int min, int max, int initial,
313     const wxString& name)
314     {
315     // this should be in ctor/init function but I don't want to add one to 2.8
316     // to avoid problems with default ctor which can be inlined in the user
317     // code and so might not get this fix without recompilation
318     m_oldValue = INT_MIN;
319    
320     // before using DoGetBestSize(), have to set style to let the base class
321     // know whether this is a horizontal or vertical control (we're always
322     // vertical)
323     style |= wxSP_VERTICAL;
324    
325     if ( (style & wxBORDER_MASK) == wxBORDER_DEFAULT )
326     #ifdef __WXWINCE__
327     style |= wxBORDER_SIMPLE;
328     #else
329     style |= wxBORDER_SUNKEN;
330     #endif
331    
332     SetWindowStyle(style);
333    
334     WXDWORD exStyle = 0;
335     WXDWORD msStyle = MSWGetStyle(GetWindowStyle(), & exStyle) ;
336    
337     // calculate the sizes: the size given is the toal size for both controls
338     // and we need to fit them both in the given width (height is the same)
339     wxSize sizeText(size), sizeBtn(size);
340     sizeBtn.x = wxSpinButton::DoGetBestSize().x;
341     if ( sizeText.x <= 0 )
342     {
343     // DEFAULT_ITEM_WIDTH is the default width for the text control
344     sizeText.x = DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN + sizeBtn.x;
345     }
346    
347     sizeText.x -= sizeBtn.x + MARGIN_BETWEEN;
348     if ( sizeText.x <= 0 )
349     {
350     wxLogDebug(_T("not enough space for wxSpinCtrl!"));
351     }
352    
353     wxPoint posBtn(pos);
354     posBtn.x += sizeText.x + MARGIN_BETWEEN;
355    
356     // we must create the text control before the spin button for the purpose
357     // of the dialog navigation: if there is a static text just before the spin
358     // control, activating it by Alt-letter should give focus to the text
359     // control, not the spin and the dialog navigation code will give focus to
360     // the next control (at Windows level), not the one after it
361    
362     // create the text window
363    
364     // PCSX2: Add right-handed alignment to the buddy text control, since any self-
365     // respecting integer deserves to be right-justified. I'd do this from the user
366     // lib instead of wxWidgets directly, but since the buddy textctrl isn't exposed
367     // as a wxWindow, I can't modify it's flags. >_< --air
368    
369     m_hwndBuddy = (WXHWND)::CreateWindowEx
370     (
371     exStyle, // sunken border
372     _T("EDIT"), // window class
373     NULL, // no window title
374     msStyle | ES_RIGHT, // style (will be shown later) [PCSX2, see above]
375     pos.x, pos.y, // position
376     0, 0, // size (will be set later)
377     GetHwndOf(parent), // parent
378     (HMENU)-1, // control id
379     wxGetInstance(), // app instance
380     NULL // unused client data
381     );
382    
383     if ( !m_hwndBuddy )
384     {
385     wxLogLastError(wxT("CreateWindow(buddy text window)"));
386    
387     return false;
388     }
389    
390    
391     // create the spin button
392     if ( !wxSpinButton::Create(parent, id, posBtn, sizeBtn, style, name) )
393     {
394     return false;
395     }
396    
397     wxSpinButtonBase::SetRange(min, max);
398    
399     // subclass the text ctrl to be able to intercept some events
400     wxSetWindowUserData(GetBuddyHwnd(), this);
401     m_wndProcBuddy = (WXFARPROC)wxSetWindowProc(GetBuddyHwnd(),
402     wxBuddyTextWndProc);
403    
404     // set up fonts and colours (This is nomally done in MSWCreateControl)
405     InheritAttributes();
406     if (!m_hasFont)
407     SetFont(GetDefaultAttributes().font);
408    
409     // set the size of the text window - can do it only now, because we
410     // couldn't call DoGetBestSize() before as font wasn't set
411     if ( sizeText.y <= 0 )
412     {
413     int cx, cy;
414     wxGetCharSize(GetHWND(), &cx, &cy, GetFont());
415    
416     sizeText.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
417     }
418    
419     SetInitialSize(size);
420    
421     (void)::ShowWindow(GetBuddyHwnd(), SW_SHOW);
422    
423     // associate the text window with the spin button
424     (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)m_hwndBuddy, 0);
425    
426     SetValue(initial);
427    
428     // Set the range in the native control
429     SetRange(min, max);
430    
431     if ( !value.empty() )
432     {
433     SetValue(value);
434     m_oldValue = (int) wxAtol(value);
435     }
436     else
437     {
438     SetValue(wxString::Format(wxT("%d"), initial));
439     m_oldValue = initial;
440     }
441    
442     // do it after finishing with m_hwndBuddy creation to avoid generating
443     // initial wxEVT_COMMAND_TEXT_UPDATED message
444     ms_allSpins.Add(this);
445    
446     return true;
447     }
448    
449     wxSpinCtrl::~wxSpinCtrl()
450     {
451     ms_allSpins.Remove(this);
452    
453     // This removes spurious memory leak reporting
454     if (ms_allSpins.GetCount() == 0)
455     ms_allSpins.Clear();
456    
457     // destroy the buddy window because this pointer which wxBuddyTextWndProc
458     // uses will not soon be valid any more
459     ::DestroyWindow(GetBuddyHwnd());
460     }
461    
462     // ----------------------------------------------------------------------------
463     // wxTextCtrl-like methods
464     // ----------------------------------------------------------------------------
465    
466     void wxSpinCtrl::SetValue(const wxString& text)
467     {
468     if ( !::SetWindowText(GetBuddyHwnd(), text.c_str()) )
469     {
470     wxLogLastError(wxT("SetWindowText(buddy)"));
471     }
472     }
473    
474     void wxSpinCtrl::SetValue(int val)
475     {
476     wxSpinButton::SetValue(val);
477    
478     // normally setting the value of the spin button is enough as it updates
479     // its buddy control automatically ...
480     if ( wxGetWindowText(m_hwndBuddy).empty() )
481     {
482     // ... but sometimes it doesn't, notably when the value is 0 and the
483     // text control is currently empty, the spin button seems to be happy
484     // to leave it like this, while we really want to always show the
485     // current value in the control, so do it manually
486     ::SetWindowText(GetBuddyHwnd(), wxString::Format(_T("%d"), val));
487     }
488    
489     m_oldValue = GetValue();
490     }
491    
492     int wxSpinCtrl::GetValue() const
493     {
494     wxString val = wxGetWindowText(m_hwndBuddy);
495    
496     long n;
497     if ( (wxSscanf(val, wxT("%ld"), &n) != 1) )
498     n = INT_MIN;
499    
500     if ( n < m_min )
501     n = m_min;
502     if ( n > m_max )
503     n = m_max;
504    
505     return n;
506     }
507    
508     void wxSpinCtrl::SetSelection(long from, long to)
509     {
510     // if from and to are both -1, it means (in wxWidgets) that all text should
511     // be selected - translate into Windows convention
512     if ( (from == -1) && (to == -1) )
513     {
514     from = 0;
515     }
516    
517     ::SendMessage(GetBuddyHwnd(), EM_SETSEL, (WPARAM)from, (LPARAM)to);
518     }
519    
520     // ----------------------------------------------------------------------------
521     // forward some methods to subcontrols
522     // ----------------------------------------------------------------------------
523    
524     bool wxSpinCtrl::SetFont(const wxFont& font)
525     {
526     if ( !wxWindowBase::SetFont(font) )
527     {
528     // nothing to do
529     return false;
530     }
531    
532     WXHANDLE hFont = GetFont().GetResourceHandle();
533     (void)::SendMessage(GetBuddyHwnd(), WM_SETFONT, (WPARAM)hFont, TRUE);
534    
535     return true;
536     }
537    
538     bool wxSpinCtrl::Show(bool show)
539     {
540     if ( !wxControl::Show(show) )
541     {
542     return false;
543     }
544    
545     ::ShowWindow(GetBuddyHwnd(), show ? SW_SHOW : SW_HIDE);
546    
547     return true;
548     }
549    
550     bool wxSpinCtrl::Reparent(wxWindowBase *newParent)
551     {
552     // Reparenting both the updown control and its buddy does not seem to work:
553     // they continue to be connected somehow, but visually there is no feedback
554     // on the buddy edit control. To avoid this problem, we reparent the buddy
555     // window normally, but we recreate the updown control and reassign its
556     // buddy.
557    
558     if ( !wxWindowBase::Reparent(newParent) )
559     return false;
560    
561     newParent->GetChildren().DeleteObject(this);
562    
563     // preserve the old values
564     const wxSize size = GetSize();
565     int value = GetValue();
566     const wxRect btnRect = wxRectFromRECT(wxGetWindowRect(GetHwnd()));
567    
568     // destroy the old spin button
569     UnsubclassWin();
570     if ( !::DestroyWindow(GetHwnd()) )
571     wxLogLastError(wxT("DestroyWindow"));
572    
573     // create and initialize the new one
574     if ( !wxSpinButton::Create(GetParent(), GetId(),
575     btnRect.GetPosition(), btnRect.GetSize(),
576     GetWindowStyle(), GetName()) )
577     return false;
578    
579     SetValue(value);
580     SetRange(m_min, m_max);
581     SetInitialSize(size);
582    
583     // associate it with the buddy control again
584     ::SetParent(GetBuddyHwnd(), GetHwndOf(GetParent()));
585     (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)GetBuddyHwnd(), 0);
586    
587     return true;
588     }
589    
590     bool wxSpinCtrl::Enable(bool enable)
591     {
592     if ( !wxControl::Enable(enable) )
593     {
594     return false;
595     }
596    
597     ::EnableWindow(GetBuddyHwnd(), enable);
598    
599     return true;
600     }
601    
602     void wxSpinCtrl::SetFocus()
603     {
604     ::SetFocus(GetBuddyHwnd());
605     }
606    
607     #if wxUSE_TOOLTIPS
608    
609     void wxSpinCtrl::DoSetToolTip(wxToolTip *tip)
610     {
611     wxSpinButton::DoSetToolTip(tip);
612    
613     if ( tip )
614     tip->Add(m_hwndBuddy);
615     }
616    
617     #endif // wxUSE_TOOLTIPS
618    
619     // ----------------------------------------------------------------------------
620     // events processing and generation
621     // ----------------------------------------------------------------------------
622    
623     void wxSpinCtrl::SendSpinUpdate(int value)
624     {
625     wxCommandEvent event(wxEVT_COMMAND_SPINCTRL_UPDATED, GetId());
626     event.SetEventObject(this);
627     event.SetInt(value);
628    
629     (void)GetEventHandler()->ProcessEvent(event);
630    
631     m_oldValue = value;
632     }
633    
634     void wxSpinCtrl::OnSpinChange(wxSpinEvent& eventSpin)
635     {
636     const int value = eventSpin.GetPosition();
637     if ( value != m_oldValue )
638     {
639     SendSpinUpdate(value);
640     }
641     }
642    
643     // ----------------------------------------------------------------------------
644     // size calculations
645     // ----------------------------------------------------------------------------
646    
647     wxSize wxSpinCtrl::DoGetBestSize() const
648     {
649     wxSize sizeBtn = wxSpinButton::DoGetBestSize();
650     sizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN;
651    
652     int y;
653     wxGetCharSize(GetHWND(), NULL, &y, GetFont());
654     y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(y);
655    
656     // JACS: we should always use the height calculated
657     // from above, because otherwise we'll get a spin control
658     // that's too big. So never use the height calculated
659     // from wxSpinButton::DoGetBestSize().
660    
661     // if ( sizeBtn.y < y )
662     {
663     // make the text tall enough
664     sizeBtn.y = y;
665     }
666    
667     return sizeBtn;
668     }
669    
670     void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
671     {
672     int widthBtn = wxSpinButton::DoGetBestSize().x;
673     int widthText = width - widthBtn - MARGIN_BETWEEN;
674     if ( widthText <= 0 )
675     {
676     wxLogDebug(_T("not enough space for wxSpinCtrl!"));
677     }
678    
679     // 1) The buddy window
680     DoMoveSibling(m_hwndBuddy, x, y, widthText, height);
681    
682     // 2) The button window
683     x += widthText + MARGIN_BETWEEN;
684     wxSpinButton::DoMoveWindow(x, y, widthBtn, height);
685     }
686    
687     // get total size of the control
688     void wxSpinCtrl::DoGetSize(int *x, int *y) const
689     {
690     RECT spinrect, textrect, ctrlrect;
691     GetWindowRect(GetHwnd(), &spinrect);
692     GetWindowRect(GetBuddyHwnd(), &textrect);
693     UnionRect(&ctrlrect,&textrect, &spinrect);
694    
695     if ( x )
696     *x = ctrlrect.right - ctrlrect.left;
697     if ( y )
698     *y = ctrlrect.bottom - ctrlrect.top;
699     }
700    
701     void wxSpinCtrl::DoGetClientSize(int *x, int *y) const
702     {
703     RECT spinrect = wxGetClientRect(GetHwnd());
704     RECT textrect = wxGetClientRect(GetBuddyHwnd());
705     RECT ctrlrect;
706     UnionRect(&ctrlrect,&textrect, &spinrect);
707    
708     if ( x )
709     *x = ctrlrect.right - ctrlrect.left;
710     if ( y )
711     *y = ctrlrect.bottom - ctrlrect.top;
712     }
713    
714     void wxSpinCtrl::DoGetPosition(int *x, int *y) const
715     {
716     // hack: pretend that our HWND is the text control just for a moment
717     WXHWND hWnd = GetHWND();
718     wxConstCast(this, wxSpinCtrl)->m_hWnd = m_hwndBuddy;
719    
720     wxSpinButton::DoGetPosition(x, y);
721    
722     wxConstCast(this, wxSpinCtrl)->m_hWnd = hWnd;
723     }
724    
725     #endif // wxUSE_SPINCTRL

  ViewVC Help
Powered by ViewVC 1.1.22