1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxSliderMSW 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:       wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  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 #if !USE_SHARED_LIBRARY 
  33 IMPLEMENT_DYNAMIC_CLASS(wxSliderMSW
, wxControl
) 
  37 wxSliderMSW::wxSliderMSW() 
  49 bool wxSliderMSW::Create(wxWindow 
*parent
, wxWindowID id
, 
  50            int value
, int minValue
, int maxValue
, 
  52            const wxSize
& size
, long style
, 
  53            const wxValidator
& validator
, 
  57   SetValidator(validator
); 
  59   if (parent
) parent
->AddChild(this); 
  60   SetBackgroundColour(parent
->GetBackgroundColour()) ; 
  61   SetForegroundColour(parent
->GetForegroundColour()) ; 
  68   m_windowStyle 
= style
; 
  72       m_windowId 
= (int)NewControlId(); 
  81   // non-Win95 implementation 
  83   long msStyle 
= WS_CHILD 
| WS_VISIBLE 
| WS_BORDER 
| SS_CENTER
; 
  86   WXDWORD exStyle 
= Determine3DEffects(WS_EX_CLIENTEDGE
, &want3D
) ; 
  88   m_staticValue 
= (WXHWND
) CreateWindowEx(exStyle
, _T("STATIC"), NULL
, 
  90                            0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)NewControlId(), 
  91                            wxGetInstance(), NULL
); 
  93   // Now create min static control 
  94   wxSprintf(wxBuffer
, _T("%d"), minValue
); 
  95   m_staticMin 
= (WXHWND
) CreateWindowEx(0, _T("STATIC"), wxBuffer
, 
  97                          0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)NewControlId(), 
  98                          wxGetInstance(), NULL
); 
 101   m_windowId 
= (int)NewControlId(); 
 104   if (m_windowStyle 
& wxSL_VERTICAL
) 
 105     msStyle 
= SBS_VERT 
| WS_CHILD 
| WS_VISIBLE 
| WS_TABSTOP 
; 
 107     msStyle 
= SBS_HORZ 
| WS_CHILD 
| WS_VISIBLE 
| WS_TABSTOP 
; 
 109   HWND scroll_bar 
= CreateWindowEx(MakeExtendedStyle(m_windowStyle
), _T("SCROLLBAR"), wxBuffer
, 
 111                          0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)m_windowId
, 
 112                          wxGetInstance(), NULL
); 
 114   m_pageSize 
= (int)((maxValue
-minValue
)/10); 
 115   m_rangeMax 
= maxValue
; 
 116   m_rangeMin 
= minValue
; 
 118   ::SetScrollRange(scroll_bar
, SB_CTL
, minValue
, maxValue
, FALSE
); 
 119   ::SetScrollPos(scroll_bar
, SB_CTL
, value
, FALSE
); 
 120   ShowWindow(scroll_bar
, SW_SHOW
); 
 122   m_hWnd 
= (WXHWND
)scroll_bar
; 
 124   // Subclass again for purposes of dialog editing mode 
 125   SubclassWin(GetHWND()); 
 127   // Finally, create max value static item 
 128   wxSprintf(wxBuffer
, _T("%d"), maxValue
); 
 129   m_staticMax 
= (WXHWND
) CreateWindowEx(0, _T("STATIC"), wxBuffer
, 
 131                          0, 0, 0, 0, (HWND
) parent
->GetHWND(), (HMENU
)NewControlId(), 
 132                          wxGetInstance(), NULL
); 
 134   SetFont(parent
->GetFont()); 
 138 //    GetFont()->RealizeResource(); 
 139     if (GetFont().GetResourceHandle()) 
 142               SendMessage((HWND
)m_staticMin
,WM_SETFONT
, 
 143                       (WPARAM
)GetFont().GetResourceHandle(),0L); 
 145               SendMessage((HWND
)m_staticMax
,WM_SETFONT
, 
 146                   (WPARAM
)GetFont().GetResourceHandle(),0L); 
 148             SendMessage((HWND
)m_staticValue
,WM_SETFONT
, 
 149                     (WPARAM
)GetFont().GetResourceHandle(),0L); 
 153   SetSize(x
, y
, width
, height
); 
 159 bool wxSliderMSW::MSWOnScroll(int WXUNUSED(orientation
), WXWORD wParam
, 
 160                               WXWORD pos
, WXHWND control
) 
 162     int position 
= ::GetScrollPos((HWND
)control
, SB_CTL
); 
 165     wxEventType scrollEvent 
= wxEVT_NULL
; 
 169             nScrollInc 
= m_rangeMax 
- position
; 
 170             scrollEvent 
= wxEVT_SCROLL_TOP
; 
 174             nScrollInc 
= - position
; 
 175             scrollEvent 
= wxEVT_SCROLL_BOTTOM
; 
 179             nScrollInc 
= - GetLineSize(); 
 180             scrollEvent 
= wxEVT_SCROLL_LINEUP
; 
 184             nScrollInc 
= GetLineSize(); 
 185             scrollEvent 
= wxEVT_SCROLL_LINEDOWN
; 
 189             nScrollInc 
= -GetPageSize(); 
 190             scrollEvent 
= wxEVT_SCROLL_PAGEUP
; 
 194             nScrollInc 
= GetPageSize(); 
 195             scrollEvent 
= wxEVT_SCROLL_PAGEDOWN
; 
 199         case SB_THUMBPOSITION
: 
 201             nScrollInc 
= (signed short)pos 
- position
; 
 203             nScrollInc 
= pos 
- position
; 
 205             scrollEvent 
= wxEVT_SCROLL_THUMBTRACK
; 
 218     int newPos 
= position 
+ nScrollInc
; 
 220     if ( (newPos 
< GetMin()) || (newPos 
> GetMax()) ) 
 222         // out of range - but we did process it 
 228     wxScrollEvent 
event(scrollEvent
, m_windowId
); 
 229     event
.SetPosition(newPos
); 
 230     event
.SetEventObject( this ); 
 231     GetEventHandler()->ProcessEvent(event
); 
 233     wxCommandEvent 
cevent( wxEVT_COMMAND_SLIDER_UPDATED
, GetId() ); 
 234     cevent
.SetEventObject( this ); 
 236     return GetEventHandler()->ProcessEvent( cevent 
); 
 239 wxSliderMSW::~wxSliderMSW() 
 242       DestroyWindow((HWND
) m_staticMin
); 
 244       DestroyWindow((HWND
) m_staticMax
); 
 246       DestroyWindow((HWND
) m_staticValue
); 
 249 int wxSliderMSW::GetValue() const 
 251   return ::GetScrollPos(GetHwnd(), SB_CTL
); 
 254 void wxSliderMSW::SetValue(int value
) 
 256   ::SetScrollPos(GetHwnd(), SB_CTL
, value
, TRUE
); 
 259     wxSprintf(wxBuffer
, _T("%d"), value
); 
 260     SetWindowText((HWND
) m_staticValue
, wxBuffer
); 
 264 void wxSliderMSW::GetSize(int *width
, int *height
) const 
 267   rect
.left 
= -1; rect
.right 
= -1; rect
.top 
= -1; rect
.bottom 
= -1; 
 269   wxFindMaxSize(GetHWND(), &rect
); 
 272     wxFindMaxSize(m_staticMin
, &rect
); 
 274     wxFindMaxSize(m_staticMax
, &rect
); 
 276     wxFindMaxSize(m_staticValue
, &rect
); 
 278   *width 
= rect
.right 
- rect
.left
; 
 279   *height 
= rect
.bottom 
- rect
.top
; 
 282 void wxSliderMSW::GetPosition(int *x
, int *y
) const 
 284   wxWindow 
*parent 
= GetParent(); 
 286   rect
.left 
= -1; rect
.right 
= -1; rect
.top 
= -1; rect
.bottom 
= -1; 
 288   wxFindMaxSize(GetHWND(), &rect
); 
 291     wxFindMaxSize(m_staticMin
, &rect
); 
 293     wxFindMaxSize(m_staticMax
, &rect
); 
 295     wxFindMaxSize(m_staticValue
, &rect
); 
 297   // Since we now have the absolute screen coords, 
 298   // if there's a parent we must subtract its top left corner 
 303     ::ScreenToClient((HWND
) parent
->GetHWND(), &point
); 
 305   // We may be faking the client origin. 
 306   // So a window that's really at (0, 30) may appear 
 307   // (to wxWin apps) to be at (0, 0). 
 310     wxPoint 
pt(GetParent()->GetClientAreaOrigin()); 
 318 // TODO one day, make sense of all this horros and replace it with a readable 
 320 void wxSliderMSW::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
 327   int currentX
, currentY
; 
 328   GetPosition(¤tX
, ¤tY
); 
 329   if (x 
== -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 331   if (y 
== -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 334   AdjustForParentClientOrigin(x1
, y1
, sizeFlags
); 
 341   int cx
;     // slider,min,max sizes 
 345   wxGetCharSize(GetHWND(), &cx
, &cy
,& this->GetFont()); 
 347   if ((m_windowStyle 
& wxSL_VERTICAL
) != wxSL_VERTICAL
) 
 349     if ( m_windowStyle 
& wxSL_LABELS 
) 
 353     GetWindowText((HWND
) m_staticMin
, buf
, 300); 
 354     GetTextExtent(buf
, &min_len
, &cyf
,NULL
,NULL
, & this->GetFont()); 
 358     GetWindowText((HWND
) m_staticMax
, buf
, 300); 
 359     GetTextExtent(buf
, &max_len
, &cyf
,NULL
,NULL
, & this->GetFont()); 
 362       int new_width 
= (int)(wxMax(min_len
, max_len
)); 
 363       int valueHeight 
= (int)cyf
; 
 365       // For some reason, under Win95, the text edit control has 
 366       // a lot of space before the first character 
 369       MoveWindow((HWND
) m_staticValue
, x_offset
, y_offset
, new_width
, valueHeight
, TRUE
); 
 370       x_offset 
+= new_width 
+ cx
; 
 373     MoveWindow((HWND
) m_staticMin
, x_offset
, y_offset
, (int)min_len
, cy
, TRUE
); 
 374     x_offset 
+= (int)(min_len 
+ cx
); 
 376     int slider_length 
= (int)(w1 
- x_offset 
- max_len 
- cx
); 
 378     int slider_height 
= cy
; 
 380     // Slider must have a minimum/default length/height 
 381     if (slider_length 
< 100) 
 384     MoveWindow(GetHwnd(), x_offset
, y_offset
, slider_length
, slider_height
, TRUE
); 
 385     x_offset 
+= slider_length 
+ cx
; 
 387     MoveWindow((HWND
) m_staticMax
, x_offset
, y_offset
, (int)max_len
, cy
, TRUE
); 
 396         MoveWindow(GetHwnd(), x1
, y1
, w1
, h1
, TRUE
); 
 401     if ( m_windowStyle 
& wxSL_LABELS 
) 
 404     GetWindowText((HWND
) m_staticMin
, buf
, 300); 
 405     GetTextExtent(buf
, &min_len
, &cyf
,NULL
,NULL
,& this->GetFont()); 
 408     GetWindowText((HWND
) m_staticMax
, buf
, 300); 
 409     GetTextExtent(buf
, &max_len
, &cyf
,NULL
,NULL
, & this->GetFont()); 
 413       int new_width 
= (int)(wxMax(min_len
, max_len
)); 
 414       int valueHeight 
= (int)cyf
; 
 415 /*** Suggested change by George Tasker - remove this block... 
 417       // For some reason, under Win95, the text edit control has 
 418       // a lot of space before the first character 
 421  ... and replace with following line: */ 
 424       MoveWindow((HWND
) m_staticValue
, x_offset
, y_offset
, new_width
, valueHeight
, TRUE
); 
 425       y_offset 
+= valueHeight
; 
 428     MoveWindow((HWND
) m_staticMin
, x_offset
, y_offset
, (int)min_len
, cy
, TRUE
); 
 431     int slider_length 
= (int)(h1 
- y_offset 
- cy 
- cy
); 
 433     // Use character height as an estimate of slider width (yes, width) 
 434     int slider_width 
= cy
; 
 436     // Slider must have a minimum/default length 
 437     if (slider_length 
< 100) 
 440     MoveWindow(GetHwnd(), x_offset
, y_offset
, slider_width
, slider_length
, TRUE
); 
 441     y_offset 
+= slider_length
; 
 443     MoveWindow((HWND
) m_staticMax
, x_offset
, y_offset
, (int)max_len
, cy
, TRUE
); 
 452         MoveWindow(GetHwnd(), x1
, y1
, w1
, h1
, TRUE
); 
 457 void wxSliderMSW::SetRange(int minValue
, int maxValue
) 
 459   m_rangeMin 
= minValue
; 
 460   m_rangeMax 
= maxValue
; 
 462   ::SetScrollRange(GetHwnd(), SB_CTL
, m_rangeMin
, m_rangeMax
, TRUE
); 
 466       wxSprintf(buf
, _T("%d"), m_rangeMin
); 
 467       SetWindowText((HWND
) m_staticMin
, buf
); 
 472     wxSprintf(buf
, _T("%d"), m_rangeMax
); 
 473     SetWindowText((HWND
) m_staticMax
, buf
); 
 477 WXHBRUSH 
wxSliderMSW::OnCtlColor(WXHDC pDC
, WXHWND pWnd
, WXUINT nCtlColor
, 
 478             WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
) 
 480   if ( nCtlColor 
== CTLCOLOR_SCROLLBAR 
) 
 483   // Otherwise, it's a static 
 484   if (GetParent()->GetTransparentBackground()) 
 485     SetBkMode((HDC
) pDC
, TRANSPARENT
); 
 487     SetBkMode((HDC
) pDC
, OPAQUE
); 
 489   ::SetBkColor((HDC
) pDC
, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue())); 
 490   ::SetTextColor((HDC
) pDC
, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue())); 
 492   wxBrush 
*backgroundBrush 
= wxTheBrushList
->FindOrCreateBrush(GetBackgroundColour(), wxSOLID
); 
 494   return (WXHBRUSH
) backgroundBrush
->GetResourceHandle(); 
 497 // For trackbars only 
 498 void wxSliderMSW::SetTickFreq(int n
, int pos
) 
 502 void wxSliderMSW::SetPageSize(int pageSize
) 
 504   m_pageSize 
= pageSize
; 
 507 int wxSliderMSW::GetPageSize() const 
 512 void wxSliderMSW::ClearSel() 
 516 void wxSliderMSW::ClearTicks() 
 520 void wxSliderMSW::SetLineSize(int lineSize
) 
 522   m_lineSize 
= lineSize
; 
 525 int wxSliderMSW::GetLineSize() const 
 530 int wxSliderMSW::GetSelEnd() const 
 535 int wxSliderMSW::GetSelStart() const 
 540 void wxSliderMSW::SetSelection(int minPos
, int maxPos
) 
 544 void wxSliderMSW::SetThumbLength(int len
) 
 548 int wxSliderMSW::GetThumbLength() const 
 553 void wxSliderMSW::SetTick(int tickPos
) 
 557 bool wxSliderMSW::ContainsHWND(WXHWND hWnd
) const 
 559     return ( hWnd 
== GetStaticMin() || hWnd 
== GetStaticMax() || hWnd 
== GetEditValue() ); 
 562 void wxSliderMSW::Command (wxCommandEvent 
& event
) 
 564   SetValue (event
.GetInt()); 
 565   ProcessCommand (event
); 
 568 bool wxSliderMSW::Show(bool show
) 
 570     wxWindow::Show(show
); 
 579         ShowWindow((HWND
) m_staticValue
, (BOOL
)cshow
); 
 581         ShowWindow((HWND
) m_staticMin
, (BOOL
)cshow
); 
 583         ShowWindow((HWND
) m_staticMax
, (BOOL
)cshow
);