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