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