Cosmetic fixes.
[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 for (int i = 0; i < n; i++)
160 {
161 Append(asChoices[i]);
162 }
163
164 SetSize( rPos.x
165 ,rPos.y
166 ,rSize.x
167 ,rSize.y
168 );
169 if (!rsValue.empty())
170 {
171 SetValue(rsValue);
172 }
173 gfnWndprocEdit = (WXFARPROC)::WinSubclassWindow( (HWND)GetHwnd()
174 ,(PFNWP)wxComboEditWndProc
175 );
176 ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
177 Show(true);
178 return true;
179 } // end of wxComboBox::Create
180
181 void wxComboBox::SetValue(
182 const wxString& rsValue
183 )
184 {
185 if ( HasFlag(wxCB_READONLY) )
186 SetStringSelection(rsValue);
187 else
188 ::WinSetWindowText(GetHwnd(), (PSZ)rsValue.c_str());
189 } // end of wxComboBox::SetValue
190
191 //
192 // Clipboard operations
193 //
194 void wxComboBox::Copy()
195 {
196 HWND hWnd = GetHwnd();
197
198 ::WinSendMsg(hWnd, EM_COPY, (MPARAM)0, (MPARAM)0);
199 } // end of wxComboBox::Copy
200
201 void wxComboBox::Cut()
202 {
203 HWND hWnd = GetHwnd();
204
205 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
206 } // end of wxComboBox::Cut
207
208 void wxComboBox::Paste()
209 {
210 HWND hWnd = GetHwnd();
211
212 ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0);
213 } // end of wxComboBox::Paste
214
215 void wxComboBox::SetEditable(
216 bool bEditable
217 )
218 {
219 HWND hWnd = GetHwnd();
220
221 ::WinSendMsg(hWnd, EM_SETREADONLY, (MPARAM)!bEditable, (MPARAM)0L);
222 } // end of wxComboBox::SetEditable
223
224 void wxComboBox::SetInsertionPoint(
225 long lPos
226 )
227 {
228 HWND hWnd = GetHwnd();
229
230 ::WinSendMsg(hWnd, EM_SETFIRSTCHAR, MPFROMLONG(lPos), (MPARAM)0);
231 } // end of wxComboBox::SetInsertionPoint
232
233 void wxComboBox::SetInsertionPointEnd()
234 {
235 wxTextPos lPos = GetLastPosition();
236
237 SetInsertionPoint(lPos);
238 } // end of wxComboBox::SetInsertionPointEnd
239
240 long wxComboBox::GetInsertionPoint() const
241 {
242 long lPos = LONGFROMMR(::WinSendMsg( GetHwnd()
243 ,LM_QUERYSELECTION
244 ,(MPARAM)0
245 ,(MPARAM)0
246 ));
247 if (lPos == LIT_NONE)
248 return wxNOT_FOUND;
249 return lPos;
250 } // end of wxComboBox::GetInsertionPoint
251
252 wxTextPos wxComboBox::GetLastPosition() const
253 {
254 long lLineLength = 0L;
255 WNDPARAMS vParams;
256
257 //
258 // Get number of characters in the last (only) line. We'll add this to the character
259 // index for the last line, 1st position.
260 //
261
262
263 vParams.fsStatus = WPM_CCHTEXT;
264 if (::WinSendMsg( GetHwnd()
265 ,WM_QUERYWINDOWPARAMS
266 ,&vParams
267 ,0
268 ))
269 {
270 lLineLength = (long)vParams.cchText;
271 }
272 else
273 lLineLength = 0L;
274 return lLineLength;
275 } // end of wxComboBox::GetLastPosition
276
277 void wxComboBox::Replace( long lFrom,
278 long lTo,
279 const wxString& rsValue )
280 {
281 #if wxUSE_CLIPBOARD
282 HWND hWnd = GetHwnd();
283
284 //
285 // Set selection and remove it
286 //
287 ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
288 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
289
290 //
291 // Now replace with 'value', by pasting.
292 //
293 wxSetClipboardData( wxDF_TEXT
294 ,(wxObject *)rsValue.c_str()
295 ,0
296 ,0
297 );
298
299 //
300 // Paste into edit control
301 //
302 ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0L);
303 #else
304 wxUnusedVar(lFrom);
305 wxUnusedVar(lTo);
306 wxUnusedVar(rsValue);
307 #endif
308 } // end of wxComboBox::Replace
309
310 void wxComboBox::Remove( long lFrom, long lTo)
311 {
312 #if wxUSE_CLIPBOARD
313 HWND hWnd = GetHwnd();
314
315 ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
316 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
317 #else
318 wxUnusedVar(lFrom);
319 wxUnusedVar(lTo);
320 #endif
321 } // end of wxComboBox::Remove
322
323 void wxComboBox::SetSelection(
324 long lFrom
325 , long lTo
326 )
327 {
328 HWND hWnd = GetHwnd();
329 long lFromChar = 0;
330 long lToChar = 0;
331
332 //
333 // If from and to are both -1, it means
334 // (in wxWidgets) that all text should be selected.
335 // This translates into Windows convention
336 //
337 if ((lFrom == -1L) && (lTo == -1L))
338 {
339 lFromChar = 0;
340 lToChar = -1;
341 }
342
343 ::WinSendMsg( hWnd
344 ,EM_SETSEL
345 ,MPFROM2SHORT((USHORT)lFromChar, (USHORT)lToChar)
346 ,(MPARAM)0
347 );
348 } // end of wxComboBox::SetSelection
349
350 void wxComboBox::DoSetSize(
351 int nX
352 , int nY
353 , int nWidth
354 , int nHeight
355 , int nSizeFlags
356 )
357 {
358 wxControl::DoSetSize( nX
359 ,nY
360 ,nWidth
361 ,nHeight
362 ,nSizeFlags
363 );
364 } // end of wxComboBox::DoSetSize
365
366 bool wxComboBox::ProcessEditMsg(
367 WXUINT uMsg
368 , WXWPARAM wParam
369 , WXLPARAM lParam)
370 {
371 SHORT vFlag;
372 switch (uMsg)
373 {
374 case WM_CHAR:
375 vFlag = SHORT1FROMMP(wParam);
376 switch(vFlag)
377 {
378 case KC_CHAR:
379 return (HandleChar( wParam
380 ,lParam
381 ,true /* isASCII */
382 ));
383
384 case KC_PREVDOWN:
385 return (HandleKeyDown( wParam
386 ,lParam
387 ));
388
389 case KC_KEYUP:
390 return (HandleKeyUp( wParam
391 ,lParam
392 ));
393 }
394 break;
395
396 case WM_SETFOCUS:
397 if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
398 return(HandleSetFocus((WXHWND)(HWND)wParam));
399 else
400 return(HandleKillFocus((WXHWND)(HWND)wParam));
401 }
402 return false;
403 } // end of WinGuiBase_CComboBox::ProcessEditMsg
404
405 MRESULT EXPENTRY wxComboEditWndProc(
406 HWND hWnd
407 , UINT uMessage
408 , MPARAM wParam
409 , MPARAM lParam
410 )
411 {
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 = (wxComboBox *)::WinQueryWindowULong( hWnd
421 ,QWL_USER
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