]> git.saurik.com Git - wxWidgets.git/blob - src/os2/scrolbar.cpp
Fix memory leak if wxDC::DrawBitmap() fails in wxOS2.
[wxWidgets.git] / src / os2 / scrolbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/scrolbar.cpp
3 // Purpose: wxScrollBar
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/15/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #include "wx/scrolbar.h"
16
17 #ifndef WX_PRECOMP
18 #include "wx/utils.h"
19 #endif
20
21 #include "wx/os2/private.h"
22
23 IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
24
25 // Scrollbar
26 bool wxScrollBar::Create(wxWindow* pParent,
27 wxWindowID vId,
28 const wxPoint& rPos,
29 const wxSize& rSize,
30 long lStyle,
31 #if wxUSE_VALIDATORS
32 const wxValidator& rValidator,
33 #endif
34 const wxString& rsName
35 )
36 {
37 int nX = rPos.x;
38 int nY = rPos.y;
39 int nWidth = rSize.x;
40 int nHeight = rSize.y;
41
42 if (!pParent)
43 return false;
44
45 pParent->AddChild(this);
46 SetName(rsName);
47 #if wxUSE_VALIDATORS
48 SetValidator(rValidator);
49 #endif
50 SetBackgroundColour(pParent->GetBackgroundColour()) ;
51 SetForegroundColour(pParent->GetForegroundColour()) ;
52
53 if (vId == wxID_ANY)
54 m_windowId = (int)NewControlId();
55 else
56 m_windowId = vId;
57
58 if (nWidth == wxDefaultCoord)
59 {
60 if (lStyle & wxHORIZONTAL)
61 nWidth = 140;
62 else
63 nWidth = 14;
64 }
65 if (nHeight == wxDefaultCoord)
66 {
67 if (lStyle & wxVERTICAL)
68 nHeight = 140;
69 else
70 nHeight = 14;
71 }
72
73 DWORD dwStyle = WS_VISIBLE;
74
75 if (GetWindowStyleFlag() & wxCLIP_SIBLINGS)
76 dwStyle |= WS_CLIPSIBLINGS;
77
78 DWORD dwDirection = (lStyle & wxHORIZONTAL) ? SBS_HORZ: SBS_VERT;
79
80 HWND hScrollBar = ::WinCreateWindow( (HWND)GetHwndOf(pParent)
81 ,WC_SCROLLBAR
82 ,(PSZ)NULL
83 ,dwDirection | dwStyle
84 ,0, 0, 0, 0
85 ,(HWND)GetHwndOf(pParent)
86 ,HWND_TOP
87 ,(HMENU)m_windowId
88 ,NULL
89 ,NULL
90 );
91
92 m_nPageSize = 1;
93 m_nViewSize = 1;
94 m_nObjectSize = 1;
95 ::WinSendMsg( hScrollBar
96 ,SBM_SETSCROLLBAR
97 ,(MPARAM)0
98 ,MPFROM2SHORT(0,1)
99 );
100 ::WinShowWindow( hScrollBar, TRUE );
101 SetFont(*wxSMALL_FONT);
102
103 m_hWnd = hScrollBar;
104
105 //
106 // Subclass again for purposes of dialog editing mode
107 //
108 SubclassWin((WXHWND)hScrollBar);
109 SetSize( nX
110 ,nY
111 ,nWidth
112 ,nHeight
113 );
114 return true;
115 } // end of wxScrollBar::Create
116
117 wxScrollBar::~wxScrollBar()
118 {
119 }
120
121 bool wxScrollBar::OS2OnScroll ( int WXUNUSED(nOrientation),
122 WXWORD wParam,
123 WXWORD wPos,
124 WXHWND WXUNUSED(hControl) )
125 {
126 int nPosition;
127 int nMaxPos;
128 int nTrackPos = wPos;
129 int nMinPos;
130 int nScrollInc;
131 wxEventType vScrollEvent = wxEVT_NULL;
132
133 MRESULT vRange;
134
135 //
136 // When we're dragging the scrollbar we can't use pos parameter because it
137 // is limited to 16 bits
138 //
139 if (wParam == SB_SLIDERPOSITION || wParam == SB_SLIDERTRACK)
140 {
141 SBCDATA vScrollInfo;
142
143 vScrollInfo.sHilite = SB_SLIDERTRACK;
144
145 ::WinSendMsg((HWND)GetHwnd(), WM_QUERYWINDOWPARAMS, (PVOID)&vScrollInfo, NULL);
146
147 nTrackPos = vScrollInfo.posThumb;
148 nPosition = vScrollInfo.posFirst;
149 nMaxPos = vScrollInfo.posLast;
150 }
151 else
152 {
153 nPosition = (int)(MRESULT)::WinSendMsg((HWND)GetHwnd(), SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL);
154 vRange = ::WinSendMsg((HWND)GetHwnd(), SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL);
155 nMinPos = SHORT1FROMMR(vRange);
156 nMaxPos = SHORT2FROMMR(vRange);
157 }
158 //
159 // A page size greater than one has the effect of reducing the effective
160 // range, therefore the range has already been boosted artificially - so
161 // reduce it again.
162 //
163 if (m_nPageSize > 1)
164 nMaxPos -= (m_nPageSize - 1);
165 switch (wParam)
166 {
167 case SB_LINEUP:
168 nScrollInc = -1;
169 vScrollEvent = wxEVT_SCROLL_LINEUP;
170 break;
171
172 case SB_LINEDOWN:
173 nScrollInc = 1;
174 vScrollEvent = wxEVT_SCROLL_LINEDOWN;
175 break;
176
177 case SB_PAGEUP:
178 nScrollInc = -GetPageSize();
179 vScrollEvent = wxEVT_SCROLL_PAGEUP;
180 break;
181
182 case SB_PAGEDOWN:
183 nScrollInc = GetPageSize();
184 vScrollEvent = wxEVT_SCROLL_PAGEDOWN;
185 break;
186
187 case SB_SLIDERTRACK:
188 nScrollInc = nTrackPos - nPosition;
189 vScrollEvent = wxEVT_SCROLL_THUMBTRACK;
190 break;
191
192 case SB_ENDSCROLL:
193 nScrollInc = 0;
194 vScrollEvent = wxEVT_SCROLL_CHANGED;
195 break;
196
197 default:
198 nScrollInc = 0;
199 }
200 if (nScrollInc)
201 {
202 nPosition += nScrollInc;
203
204 if (nPosition < 0)
205 nPosition = 0;
206 if (nPosition > nMaxPos)
207 nPosition = nMaxPos;
208 SetThumbPosition(nPosition);
209 }
210 else if ( vScrollEvent != wxEVT_SCROLL_THUMBRELEASE &&
211 vScrollEvent != wxEVT_SCROLL_CHANGED
212 )
213 {
214 //
215 // Don't process the event if there is no displacement,
216 // unless this is a thumb release or end scroll event.
217 //
218 return false;
219 }
220
221 wxScrollEvent vEvent( vScrollEvent
222 ,m_windowId
223 );
224
225 vEvent.SetOrientation(IsVertical() ? wxVERTICAL : wxHORIZONTAL);
226 vEvent.SetPosition(nPosition);
227 vEvent.SetEventObject(this);
228 return HandleWindowEvent(vEvent);
229 } // end of wxScrollBar::OS2OnScroll
230
231 void wxScrollBar::SetThumbPosition ( int nViewStart )
232 {
233 SBCDATA vInfo;
234
235 memset(&vInfo, '\0', sizeof(SBCDATA));
236 vInfo.cb = sizeof(SBCDATA);
237 vInfo.posThumb = (SHORT)nViewStart;
238
239 ::WinSendMsg((HWND)GetHwnd(), WM_SETWINDOWPARAMS, (MPARAM)&vInfo, (MPARAM)NULL);
240 ::WinSendMsg((HWND)GetHwnd(), SBM_SETPOS, (MPARAM)nViewStart, (MPARAM)NULL);
241 } // end of wxScrollBar::SetThumbPosition
242
243 int wxScrollBar::GetThumbPosition() const
244 {
245 return((int)(MRESULT)::WinSendMsg((HWND)GetHwnd(), SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL));
246 } // end of wxScrollBar::GetThumbPosition
247
248 void wxScrollBar::SetScrollbar ( int nPosition,
249 int nThumbSize,
250 int nRange,
251 int nPageSize,
252 bool WXUNUSED(bRefresh) )
253 {
254 SBCDATA vInfo;
255 //
256 // The lRange (number of scroll steps) is the
257 // object length minus the page size.
258 //
259 int nRange1 = wxMax((m_nObjectSize - m_nPageSize), 0);
260
261 m_nViewSize = nPageSize;
262 m_nPageSize = nThumbSize;
263 m_nObjectSize = nRange;
264
265
266 //
267 // Try to adjust the lRange to cope with page size > 1
268 // (see comment for SetPageLength)
269 //
270 if (m_nPageSize > 1 )
271 {
272 nRange1 += (m_nPageSize - 1);
273 }
274 vInfo.cb = sizeof(SBCDATA);
275 vInfo.cVisible = (SHORT)m_nPageSize;
276 vInfo.posFirst = 0;
277 vInfo.posLast = (SHORT)nRange1;
278 vInfo.posThumb = (SHORT)nPosition;
279
280 ::WinSendMsg((HWND)GetHwnd(), WM_SETWINDOWPARAMS, (MPARAM)&vInfo, (MPARAM)NULL);
281 } // end of wxScrollBar::SetScrollbar
282
283 WXHBRUSH wxScrollBar::OnCtlColor ( WXHDC WXUNUSED(hDC),
284 WXHWND WXUNUSED(hWnd),
285 WXUINT WXUNUSED(uCtlColor),
286 WXUINT WXUNUSED(uMessage),
287 WXWPARAM WXUNUSED(wParam),
288 WXLPARAM WXUNUSED(lParam) )
289 {
290 //
291 // Does nothing under OS/2
292 //
293 return 0;
294 } // end of wxScrollBar::OnCtlColor
295
296 void wxScrollBar::Command ( wxCommandEvent& rEvent )
297 {
298 SetThumbPosition(rEvent.GetInt());
299 ProcessCommand(rEvent);
300 } // end of wxScrollBar::Command