]> git.saurik.com Git - wxWidgets.git/blob - src/os2/combobox.cpp
Fixed a problem with borders being set wrong sometimes on wxMSW, XP, VC++ 7
[wxWidgets.git] / src / os2 / combobox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: combobox.cpp
3 // Purpose: wxComboBox class
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/13/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/combobox.h"
13
14 // For compilers that support precompilation, includes "wx.h".
15 #include "wx/wxprec.h"
16
17 #ifndef WX_PRECOMP
18 #include "wx/setup.h"
19 #include "wx/settings.h"
20 #endif
21
22 #if wxUSE_COMBOBOX
23
24 #include "wx/combobox.h"
25 #include "wx/clipbrd.h"
26 #include "wx/os2/private.h"
27
28 #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
29
30 MRESULT EXPENTRY wxComboEditWndProc( HWND hWnd
31 ,UINT uMessage
32 ,MPARAM wParam
33 ,MPARAM lParam
34 );
35 //
36 // The pointer to standard wnd proc
37 //
38 static WXFARPROC gfnWndprocEdit = (WXFARPROC)NULL;
39
40 IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)
41
42 bool wxComboBox::OS2Command(
43 WXUINT uParam
44 , WXWORD WXUNUSED(wId)
45 )
46 {
47 long lSel = -1L;
48 wxString sValue;
49
50 switch (uParam)
51 {
52 case CBN_LBSELECT:
53 if (GetSelection() > -1)
54 {
55 wxCommandEvent vEvent( wxEVT_COMMAND_COMBOBOX_SELECTED
56 ,GetId()
57 );
58
59 vEvent.SetInt(GetSelection());
60 vEvent.SetEventObject(this);
61 vEvent.SetString((char*)GetStringSelection().c_str());
62 ProcessCommand(vEvent);
63 }
64 break;
65
66 case CBN_EFCHANGE:
67 {
68 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED
69 ,GetId()
70 );
71
72 if (lSel == -1L)
73 sValue = GetValue();
74 else
75 SetValue(sValue);
76 vEvent.SetString((char*)GetValue().c_str());
77 vEvent.SetEventObject(this);
78 ProcessCommand(vEvent);
79 }
80 break;
81 }
82 //
83 // There is no return value for the CBN_ notifications, so always return
84 // FALSE from here to pass the message to DefWindowProc()
85 //
86 return FALSE;
87 } // end of wxComboBox::OS2Command
88
89 bool wxComboBox::Create(
90 wxWindow* pParent
91 , wxWindowID vId
92 , const wxString& rsValue
93 , const wxPoint& rPos
94 , const wxSize& rSize
95 , int n
96 , const wxString asChoices[]
97 , long lStyle
98 #if wxUSE_VALIDATORS
99 , const wxValidator& rValidator
100 #endif
101 , const wxString& rsName
102 )
103 {
104 m_isShown = FALSE;
105
106 if (!CreateControl( pParent
107 ,vId
108 ,rPos
109 ,rSize
110 ,lStyle
111 #if wxUSE_VALIDATORS
112 ,rValidator
113 #endif
114 ,rsName
115 ))
116 return FALSE;
117
118 //
119 // Get the right style
120 //
121 long lSstyle = 0L;
122
123 lSstyle = WS_TABSTOP |
124 WS_VISIBLE;
125
126 if (lStyle & wxCLIP_SIBLINGS )
127 lSstyle |= WS_CLIPSIBLINGS;
128 if (lStyle & wxCB_READONLY)
129 lSstyle |= CBS_DROPDOWNLIST;
130 else if (lStyle & wxCB_SIMPLE)
131 lSstyle |= CBS_SIMPLE; // A list (shown always) and edit control
132 else
133 lSstyle |= CBS_DROPDOWN;
134
135
136 if (!OS2CreateControl( "COMBOBOX"
137 ,lSstyle
138 ))
139 return FALSE;
140
141 //
142 // A choice/combobox normally has a white background (or other, depending
143 // on global settings) rather than inheriting the parent's background colour.
144 //
145 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
146
147 SetFont(*wxSMALL_FONT);
148
149 int i;
150 for (i = 0; i < n; i++)
151 {
152 Append(asChoices[i]);
153 }
154
155 SetSize( rPos.x
156 ,rPos.y
157 ,rSize.x
158 ,rSize.y
159 );
160 if (!rsValue.IsEmpty())
161 {
162 SetValue(rsValue);
163 }
164 gfnWndprocEdit = (WXFARPROC)::WinSubclassWindow( (HWND)GetHwnd()
165 ,(PFNWP)wxComboEditWndProc
166 );
167 ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
168 Show(TRUE);
169 return TRUE;
170 } // end of wxComboBox::Create
171
172 void wxComboBox::SetValue(
173 const wxString& rsValue
174 )
175 {
176 if ( HasFlag(wxCB_READONLY) )
177 SetStringSelection(rsValue);
178 else
179 ::WinSetWindowText(GetHwnd(), rsValue.c_str());
180 } // end of wxComboBox::SetValue
181
182 //
183 // Clipboard operations
184 //
185 void wxComboBox::Copy()
186 {
187 HWND hWnd = GetHwnd();
188
189 ::WinSendMsg(hWnd, EM_COPY, (MPARAM)0, (MPARAM)0);
190 } // end of wxComboBox::Copy
191
192 void wxComboBox::Cut()
193 {
194 HWND hWnd = GetHwnd();
195
196 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
197 } // end of wxComboBox::Cut
198
199 void wxComboBox::Paste()
200 {
201 HWND hWnd = GetHwnd();
202
203 ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0);
204 } // end of wxComboBox::Paste
205
206 void wxComboBox::SetEditable(
207 bool bEditable
208 )
209 {
210 HWND hWnd = GetHwnd();
211
212 ::WinSendMsg(hWnd, EM_SETREADONLY, (MPARAM)!bEditable, (MPARAM)0L);
213 } // end of wxComboBox::SetEditable
214
215 void wxComboBox::SetInsertionPoint(
216 long lPos
217 )
218 {
219 HWND hWnd = GetHwnd();
220
221 ::WinSendMsg(hWnd, EM_SETFIRSTCHAR, MPFROMLONG(lPos), (MPARAM)0);
222 } // end of wxComboBox::SetInsertionPoint
223
224 void wxComboBox::SetInsertionPointEnd()
225 {
226 long lPos = GetLastPosition();
227
228 SetInsertionPoint(lPos);
229 } // end of wxComboBox::SetInsertionPointEnd
230
231 long wxComboBox::GetInsertionPoint() const
232 {
233 long lPos = LONGFROMMR(::WinSendMsg( GetHwnd()
234 ,LM_QUERYSELECTION
235 ,(MPARAM)0
236 ,(MPARAM)0
237 ));
238 if (lPos == LIT_NONE)
239 return wxNOT_FOUND;
240 return lPos;
241 } // end of wxComboBox::GetInsertionPoint
242
243 long wxComboBox::GetLastPosition() const
244 {
245 HWND hEditWnd = GetHwnd();
246 long lLineLength = 0L;
247 WNDPARAMS vParams;
248
249 //
250 // Get number of characters in the last (only) line. We'll add this to the character
251 // index for the last line, 1st position.
252 //
253
254
255 vParams.fsStatus = WPM_CCHTEXT;
256 if (::WinSendMsg( GetHwnd()
257 ,WM_QUERYWINDOWPARAMS
258 ,&vParams
259 ,0
260 ))
261 {
262 lLineLength = (long)vParams.cchText;
263 }
264 else
265 lLineLength = 0L;
266 return lLineLength;
267 } // end of wxComboBox::GetLastPosition
268
269 void wxComboBox::Replace(
270 long lFrom
271 , long lTo
272 , const wxString& rsValue
273 )
274 {
275 #if wxUSE_CLIPBOARD
276 HWND hWnd = GetHwnd();
277 long lFromChar = lFrom;
278 long lToChar = lTo;
279
280 //
281 // Set selection and remove it
282 //
283 ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
284 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
285
286 //
287 // Now replace with 'value', by pasting.
288 //
289 wxSetClipboardData( wxDF_TEXT
290 ,(wxObject *)rsValue.c_str()
291 ,0
292 ,0
293 );
294
295 //
296 // Paste into edit control
297 //
298 ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0L);
299 #endif
300 } // end of wxComboBox::Replace
301
302 void wxComboBox::Remove(
303 long lFrom
304 , long lTo
305 )
306 {
307 #if wxUSE_CLIPBOARD
308 HWND hWnd = GetHwnd();
309 long lFromChar = lFrom;
310 long lToChar = lTo;
311
312 ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
313 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
314 #endif
315 } // end of wxComboBox::Remove
316
317 void wxComboBox::SetSelection(
318 long lFrom
319 , long lTo
320 )
321 {
322 HWND hWnd = GetHwnd();
323 long lFromChar = lFrom;
324 long lToChar = lTo;
325
326 //
327 // If from and to are both -1, it means
328 // (in wxWindows) that all text should be selected.
329 // This translates into Windows convention
330 //
331 if ((lFrom == -1L) && (lTo == -1L))
332 {
333 lFromChar = 0;
334 lToChar = -1;
335 }
336
337 ::WinSendMsg( hWnd
338 ,EM_SETSEL
339 ,MPFROM2SHORT((USHORT)lFromChar, (USHORT)lToChar)
340 ,(MPARAM)0
341 );
342 } // end of wxComboBox::SetSelection
343
344 void wxComboBox::DoSetSize(
345 int nX
346 , int nY
347 , int nWidth
348 , int nHeight
349 , int nSizeFlags
350 )
351 {
352 wxControl::DoSetSize( nX
353 ,nY
354 ,nWidth
355 ,nHeight
356 ,nSizeFlags
357 );
358 } // end of wxComboBox::DoSetSize
359
360 bool wxComboBox::ProcessEditMsg(
361 WXUINT uMsg
362 , WXWPARAM wParam
363 , WXLPARAM lParam)
364 {
365 SHORT vFlag;
366 switch (uMsg)
367 {
368 case WM_CHAR:
369 vFlag = SHORT1FROMMP(wParam);
370 switch(vFlag)
371 {
372 case KC_CHAR:
373 return (HandleChar( wParam
374 ,lParam
375 ,TRUE /* isASCII */
376 ));
377
378 case KC_PREVDOWN:
379 return (HandleKeyDown( wParam
380 ,lParam
381 ));
382
383 case KC_KEYUP:
384 return (HandleKeyUp( wParam
385 ,lParam
386 ));
387 }
388 break;
389
390 case WM_SETFOCUS:
391 if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
392 return(HandleSetFocus((WXHWND)(HWND)wParam));
393 else
394 return(HandleKillFocus((WXHWND)(HWND)wParam));
395 break;
396 }
397 return FALSE;
398 } // end of WinGuiBase_CComboBox::ProcessEditMsg
399
400 MRESULT EXPENTRY wxComboEditWndProc(
401 HWND hWnd
402 , UINT uMessage
403 , MPARAM wParam
404 , MPARAM lParam
405 )
406 {
407 HWND hWndCombo;
408 wxWindow* pWin = NULL;
409
410 hWndCombo = ::WinQueryWindow(hWnd, QW_PARENT);
411 pWin = (wxWindow*)wxFindWinFromHandle((WXHWND)hWndCombo);
412 switch (uMessage)
413 {
414 //
415 // Forward some messages to the combobox
416 //
417 case WM_SETFOCUS:
418 case WM_CHAR:
419 {
420 wxComboBox* pCombo = wxDynamicCast( pWin
421 ,wxComboBox
422 );
423
424 if (pCombo->ProcessEditMsg( uMessage
425 ,wParam
426 ,lParam
427 ))
428 return ((MRESULT)0);
429 }
430 break;
431
432 //
433 // TODO: Deal with tooltips here
434 //
435 }
436 return (gfnWndprocEdit(hWnd, (ULONG)uMessage, (MPARAM)wParam, (MPARAM)lParam));
437 } // end of wxComboEditWndProc
438
439 #endif
440 // wxUSE_COMBOBOX
441