1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxSliderMSW 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:       wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13 #pragma implementation "slidrmsw.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  29 #include "wx/msw/slidrmsw.h" 
  30 #include "wx/msw/private.h" 
  32 IMPLEMENT_DYNAMIC_CLASS(wxSliderMSW
, wxControl
) 
  35 wxSliderMSW::wxSliderMSW() 
  46 bool wxSliderMSW::Create(wxWindow 
*parent
, wxWindowID id
, 
  47            int value
, int minValue
, int maxValue
, 
  49            const wxSize
& size
, long style
, 
  50            const wxValidator
& validator
, 
  53     if ( (style 
& wxBORDER_MASK
) == wxBORDER_DEFAULT 
) 
  54         style 
|= wxBORDER_NONE
; 
  58   SetValidator(validator
); 
  59 #endif // wxUSE_VALIDATORS 
  61   if (parent
) parent
->AddChild(this); 
  62   SetBackgroundColour(parent
->GetBackgroundColour()) ; 
  63   SetForegroundColour(parent
->GetForegroundColour()) ; 
  70   m_windowStyle 
= style
; 
  73       m_windowId 
= (int)NewControlId(); 
  82   // non-Win95 implementation 
  84   long msStyle 
= SS_CENTER
; 
  87   msStyle 
|= MSWGetStyle(GetWindowStyle(), & exStyle
) ; 
  89   m_staticValue 
= (WXHWND
) CreateWindowEx(exStyle
, wxT("STATIC"), NULL
, 
  91                            0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)NewControlId(), 
  92                            wxGetInstance(), NULL
); 
  94   // Now create min static control 
  96   buf
.Printf(wxT("%d"), minValue
); 
  97   DWORD wstyle 
= STATIC_FLAGS
; 
  98   if ( m_windowStyle 
& wxCLIP_SIBLINGS 
) 
  99         wstyle 
|= WS_CLIPSIBLINGS
; 
 100   m_staticMin 
= (WXHWND
) CreateWindowEx(0, wxT("STATIC"), buf
, 
 102                          0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)NewControlId(), 
 103                          wxGetInstance(), NULL
); 
 106   if (m_windowStyle 
& wxSL_VERTICAL
) 
 107     msStyle 
= SBS_VERT 
| WS_CHILD 
| WS_VISIBLE 
| WS_TABSTOP 
; 
 109     msStyle 
= SBS_HORZ 
| WS_CHILD 
| WS_VISIBLE 
| WS_TABSTOP 
; 
 111   HWND scroll_bar 
= CreateWindowEx(exStyle
, wxT("SCROLLBAR"), wxEmptyString
, 
 113                          0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
, 
 114                          wxGetInstance(), NULL
); 
 116   m_pageSize 
= (int)((maxValue
-minValue
)/10); 
 117   m_rangeMax 
= maxValue
; 
 118   m_rangeMin 
= minValue
; 
 120   ::SetScrollRange(scroll_bar
, SB_CTL
, minValue
, maxValue
, FALSE
); 
 121   ::SetScrollPos(scroll_bar
, SB_CTL
, value
, FALSE
); 
 122   ShowWindow(scroll_bar
, SW_SHOW
); 
 124   m_hWnd 
= (WXHWND
)scroll_bar
; 
 126   // Subclass again for purposes of dialog editing mode 
 127   SubclassWin(GetHWND()); 
 129   // Finally, create max value static item 
 130   buf
.Printf(wxT("%d"), maxValue
); 
 131   wstyle 
= STATIC_FLAGS
; 
 132   if ( m_windowStyle 
& wxCLIP_SIBLINGS 
) 
 133         wstyle 
|= WS_CLIPSIBLINGS
; 
 134   m_staticMax 
= (WXHWND
) CreateWindowEx(0, wxT("STATIC"), buf
, 
 136                          0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)NewControlId(), 
 137                          wxGetInstance(), NULL
); 
 139   SetFont(parent
->GetFont()); 
 143 //    GetFont()->RealizeResource(); 
 144     if (GetFont().GetResourceHandle()) 
 147               SendMessage((HWND
)m_staticMin
,WM_SETFONT
, 
 148                       (WPARAM
)GetFont().GetResourceHandle(),0L); 
 150               SendMessage((HWND
)m_staticMax
,WM_SETFONT
, 
 151                   (WPARAM
)GetFont().GetResourceHandle(),0L); 
 153             SendMessage((HWND
)m_staticValue
,WM_SETFONT
, 
 154                     (WPARAM
)GetFont().GetResourceHandle(),0L); 
 158   SetSize(x
, y
, width
, height
); 
 164 bool wxSliderMSW::MSWOnScroll(int WXUNUSED(orientation
), WXWORD wParam
, 
 165                               WXWORD pos
, WXHWND control
) 
 167     int position 
= ::GetScrollPos((HWND
)control
, SB_CTL
); 
 170     wxEventType scrollEvent 
= wxEVT_NULL
; 
 174             nScrollInc 
= m_rangeMax 
- position
; 
 175             scrollEvent 
= wxEVT_SCROLL_TOP
; 
 179             nScrollInc 
= - position
; 
 180             scrollEvent 
= wxEVT_SCROLL_BOTTOM
; 
 184             nScrollInc 
= - GetLineSize(); 
 185             scrollEvent 
= wxEVT_SCROLL_LINEUP
; 
 189             nScrollInc 
= GetLineSize(); 
 190             scrollEvent 
= wxEVT_SCROLL_LINEDOWN
; 
 194             nScrollInc 
= -GetPageSize(); 
 195             scrollEvent 
= wxEVT_SCROLL_PAGEUP
; 
 199             nScrollInc 
= GetPageSize(); 
 200             scrollEvent 
= wxEVT_SCROLL_PAGEDOWN
; 
 204         case SB_THUMBPOSITION
: 
 206             nScrollInc 
= (signed short)pos 
- position
; 
 208             nScrollInc 
= pos 
- position
; 
 210             scrollEvent 
= wxEVT_SCROLL_THUMBTRACK
; 
 223     int newPos 
= position 
+ nScrollInc
; 
 225     if ( (newPos 
< GetMin()) || (newPos 
> GetMax()) ) 
 227         // out of range - but we did process it 
 233     wxScrollEvent 
event(scrollEvent
, m_windowId
); 
 234     event
.SetPosition(newPos
); 
 235     event
.SetEventObject( this ); 
 236     GetEventHandler()->ProcessEvent(event
); 
 238     wxCommandEvent 
cevent( wxEVT_COMMAND_SLIDER_UPDATED
, GetId() ); 
 239     cevent
.SetInt( newPos 
); 
 240     cevent
.SetEventObject( this ); 
 242     return GetEventHandler()->ProcessEvent( cevent 
); 
 245 wxSliderMSW::~wxSliderMSW() 
 248       DestroyWindow((HWND
) m_staticMin
); 
 250       DestroyWindow((HWND
) m_staticMax
); 
 252       DestroyWindow((HWND
) m_staticValue
); 
 255 int wxSliderMSW::GetValue() const 
 257   return ::GetScrollPos(GetHwnd(), SB_CTL
); 
 260 void wxSliderMSW::SetValue(int value
) 
 262   ::SetScrollPos(GetHwnd(), SB_CTL
, value
, TRUE
); 
 266     buf
.Printf(wxT("%d"), value
); 
 267     SetWindowText((HWND
) m_staticValue
, buf
); 
 271 void wxSliderMSW::GetSize(int *width
, int *height
) const 
 274   rect
.left 
= -1; rect
.right 
= -1; rect
.top 
= -1; rect
.bottom 
= -1; 
 276   wxFindMaxSize(GetHWND(), &rect
); 
 279     wxFindMaxSize(m_staticMin
, &rect
); 
 281     wxFindMaxSize(m_staticMax
, &rect
); 
 283     wxFindMaxSize(m_staticValue
, &rect
); 
 285   *width 
= rect
.right 
- rect
.left
; 
 286   *height 
= rect
.bottom 
- rect
.top
; 
 289 void wxSliderMSW::GetPosition(int *x
, int *y
) const 
 291   wxWindow 
*parent 
= GetParent(); 
 293   rect
.left 
= -1; rect
.right 
= -1; rect
.top 
= -1; rect
.bottom 
= -1; 
 295   wxFindMaxSize(GetHWND(), &rect
); 
 298     wxFindMaxSize(m_staticMin
, &rect
); 
 300     wxFindMaxSize(m_staticMax
, &rect
); 
 302     wxFindMaxSize(m_staticValue
, &rect
); 
 304   // Since we now have the absolute screen coords, 
 305   // if there's a parent we must subtract its top left corner 
 310     ::ScreenToClient((HWND
) parent
->GetHWND(), &point
); 
 312   // We may be faking the client origin. 
 313   // So a window that's really at (0, 30) may appear 
 314   // (to wxWin apps) to be at (0, 0). 
 317     wxPoint 
pt(GetParent()->GetClientAreaOrigin()); 
 325 // TODO one day, make sense of all this horros and replace it with a readable 
 327 void wxSliderMSW::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
 334   int currentX
, currentY
; 
 335   GetPosition(¤tX
, ¤tY
); 
 336   if (x 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 338   if (y 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 341   AdjustForParentClientOrigin(x1
, y1
, sizeFlags
); 
 348   int cx
;     // slider,min,max sizes 
 352   wxGetCharSize(GetHWND(), &cx
, &cy
,& this->GetFont()); 
 354   if ((m_windowStyle 
& wxSL_VERTICAL
) != wxSL_VERTICAL
) 
 356     if ( m_windowStyle 
& wxSL_LABELS 
) 
 360     GetWindowText((HWND
) m_staticMin
, buf
, 300); 
 361     GetTextExtent(buf
, &min_len
, &cyf
,NULL
,NULL
, & this->GetFont()); 
 365     GetWindowText((HWND
) m_staticMax
, buf
, 300); 
 366     GetTextExtent(buf
, &max_len
, &cyf
,NULL
,NULL
, & this->GetFont()); 
 369       int new_width 
= (int)(wxMax(min_len
, max_len
)); 
 370       int valueHeight 
= (int)cyf
; 
 372       // For some reason, under Win95, the text edit control has 
 373       // a lot of space before the first character 
 376       MoveWindow((HWND
) m_staticValue
, x_offset
, y_offset
, new_width
, valueHeight
, TRUE
); 
 377       x_offset 
+= new_width 
+ cx
; 
 380     MoveWindow((HWND
) m_staticMin
, x_offset
, y_offset
, (int)min_len
, cy
, TRUE
); 
 381     x_offset 
+= (int)(min_len 
+ cx
); 
 383     int slider_length 
= (int)(w1 
- x_offset 
- max_len 
- cx
); 
 385     int slider_height 
= cy
; 
 387     // Slider must have a minimum/default length/height 
 388     if (slider_length 
< 100) 
 391     MoveWindow(GetHwnd(), x_offset
, y_offset
, slider_length
, slider_height
, TRUE
); 
 392     x_offset 
+= slider_length 
+ cx
; 
 394     MoveWindow((HWND
) m_staticMax
, x_offset
, y_offset
, (int)max_len
, cy
, TRUE
); 
 403         MoveWindow(GetHwnd(), x1
, y1
, w1
, h1
, TRUE
); 
 408     if ( m_windowStyle 
& wxSL_LABELS 
) 
 411     GetWindowText((HWND
) m_staticMin
, buf
, 300); 
 412     GetTextExtent(buf
, &min_len
, &cyf
,NULL
,NULL
,& this->GetFont()); 
 415     GetWindowText((HWND
) m_staticMax
, buf
, 300); 
 416     GetTextExtent(buf
, &max_len
, &cyf
,NULL
,NULL
, & this->GetFont()); 
 420       int new_width 
= (int)(wxMax(min_len
, max_len
)); 
 421       int valueHeight 
= (int)cyf
; 
 422 /*** Suggested change by George Tasker - remove this block... 
 424       // For some reason, under Win95, the text edit control has 
 425       // a lot of space before the first character 
 428  ... and replace with following line: */ 
 431       MoveWindow((HWND
) m_staticValue
, x_offset
, y_offset
, new_width
, valueHeight
, TRUE
); 
 432       y_offset 
+= valueHeight
; 
 435     MoveWindow((HWND
) m_staticMin
, x_offset
, y_offset
, (int)min_len
, cy
, TRUE
); 
 438     int slider_length 
= (int)(h1 
- y_offset 
- cy 
- cy
); 
 440     // Use character height as an estimate of slider width (yes, width) 
 441     int slider_width 
= cy
; 
 443     // Slider must have a minimum/default length 
 444     if (slider_length 
< 100) 
 447     MoveWindow(GetHwnd(), x_offset
, y_offset
, slider_width
, slider_length
, TRUE
); 
 448     y_offset 
+= slider_length
; 
 450     MoveWindow((HWND
) m_staticMax
, x_offset
, y_offset
, (int)max_len
, cy
, TRUE
); 
 459         MoveWindow(GetHwnd(), x1
, y1
, w1
, h1
, TRUE
); 
 464 void wxSliderMSW::SetRange(int minValue
, int maxValue
) 
 466   m_rangeMin 
= minValue
; 
 467   m_rangeMax 
= maxValue
; 
 469   ::SetScrollRange(GetHwnd(), SB_CTL
, m_rangeMin
, m_rangeMax
, TRUE
); 
 473       wxSprintf(buf
, wxT("%d"), m_rangeMin
); 
 474       SetWindowText((HWND
) m_staticMin
, buf
); 
 479     wxSprintf(buf
, wxT("%d"), m_rangeMax
); 
 480     SetWindowText((HWND
) m_staticMax
, buf
); 
 484 WXHBRUSH 
wxSliderMSW::OnCtlColor(WXHDC pDC
, WXHWND pWnd
, WXUINT nCtlColor
, 
 485             WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
) 
 487   if ( nCtlColor 
== CTLCOLOR_SCROLLBAR 
) 
 490   // Otherwise, it's a static 
 491   return wxControl::OnCtlColor(pDC
, pWnd
, nCtlColor
, message
, wParam
, lParam
); 
 494 void wxSliderMSW::SetPageSize(int pageSize
) 
 496   m_pageSize 
= pageSize
; 
 499 int wxSliderMSW::GetPageSize() const 
 504 void wxSliderMSW::SetLineSize(int lineSize
) 
 506   m_lineSize 
= lineSize
; 
 509 int wxSliderMSW::GetLineSize() const 
 514 // Not yet implemented 
 515 void wxSliderMSW::SetThumbLength(int WXUNUSED(lenPixels
)) 
 519 // Not yet implemented 
 520 int wxSliderMSW::GetThumbLength() const 
 525 bool wxSliderMSW::ContainsHWND(WXHWND hWnd
) const 
 527     return ( hWnd 
== GetStaticMin() || hWnd 
== GetStaticMax() || hWnd 
== GetEditValue() ); 
 530 void wxSliderMSW::Command (wxCommandEvent 
& event
) 
 532   SetValue (event
.GetInt()); 
 533   ProcessCommand (event
); 
 536 bool wxSliderMSW::Show(bool show
) 
 538     wxWindow::Show(show
); 
 547         ShowWindow((HWND
) m_staticValue
, (BOOL
)cshow
); 
 549         ShowWindow((HWND
) m_staticMin
, (BOOL
)cshow
); 
 551         ShowWindow((HWND
) m_staticMax
, (BOOL
)cshow
);