Added various #includes for non-precompiled headers.
[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 LN_SELECT:
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 EN_CHANGE:
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
105 if (!OS2CreateControl( pParent
106 ,vId
107 ,rPos
108 ,rSize
109 ,lStyle
110 #if wxUSE_VALIDATORS
111 ,rValidator
112 #endif
113 ,rsName
114 ))
115 return FALSE;
116
117 //
118 // Get the right style
119 //
120 long lSstyle = 0L;
121
122 lSstyle = WS_TABSTOP |
123 WS_VISIBLE;
124
125 if (lStyle & wxCLIP_SIBLINGS )
126 lSstyle |= WS_CLIPSIBLINGS;
127 if (lStyle & wxCB_READONLY)
128 lSstyle |= CBS_DROPDOWNLIST;
129 else if (lStyle & wxCB_SIMPLE)
130 lSstyle |= CBS_SIMPLE; // A list (shown always) and edit control
131 else
132 lSstyle |= CBS_DROPDOWN;
133
134
135 if (!OS2CreateControl( "COMBOBOX"
136 ,lSstyle
137 ))
138 return FALSE;
139
140 //
141 // A choice/combobox normally has a white background (or other, depending
142 // on global settings) rather than inheriting the parent's background colour.
143 //
144 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
145
146 SetFont(pParent->GetFont());
147
148 int i;
149
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 return TRUE;
169 } // end of wxComboBox::Create
170
171 void wxComboBox::SetValue(
172 const wxString& rsValue
173 )
174 {
175 //
176 // If newlines are denoted by just 10, must stick 13 in front.
177 //
178 int nSingletons = 0;
179 int nLen = rsValue.Length();
180 int i;
181
182 for (i = 0; i < nLen; i ++)
183 {
184 if ((i > 0) && (rsValue[i] == 10) && (rsValue[i - 1] != 13))
185 nSingletons ++;
186 }
187 if (nSingletons > 0)
188 {
189 wxChar* zTmp = new wxChar[nLen + nSingletons + 1];
190 int j = 0;
191
192 for (i = 0; i < nLen; i ++)
193 {
194 if ((i > 0) && (rsValue[i] == 10) && (rsValue[i - 1] != 13))
195 {
196 zTmp[j] = 13;
197 j++;
198 }
199 zTmp[j] = rsValue[i];
200 j++;
201 }
202 zTmp[j] = 0;
203 ::WinSetWindowText(GetHwnd(), zTmp);
204 delete[] zTmp;
205 }
206 else
207 ::WinSetWindowText(GetHwnd(), rsValue.c_str());
208 } // end of wxComboBox::SetValue
209
210 //
211 // Clipboard operations
212 //
213 void wxComboBox::Copy()
214 {
215 HWND hWnd = GetHwnd();
216
217 ::WinSendMsg(hWnd, EM_COPY, (MPARAM)0, (MPARAM)0);
218 } // end of wxComboBox::Copy
219
220 void wxComboBox::Cut()
221 {
222 HWND hWnd = GetHwnd();
223
224 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
225 } // end of wxComboBox::Cut
226
227 void wxComboBox::Paste()
228 {
229 HWND hWnd = GetHwnd();
230
231 ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0);
232 } // end of wxComboBox::Paste
233
234 void wxComboBox::SetEditable(
235 bool bEditable
236 )
237 {
238 HWND hWnd = GetHwnd();
239
240 ::WinSendMsg(hWnd, EM_SETREADONLY, (MPARAM)!bEditable, (MPARAM)0L);
241 } // end of wxComboBox::SetEditable
242
243 void wxComboBox::SetInsertionPoint(
244 long lPos
245 )
246 {
247 HWND hWnd = GetHwnd();
248
249 ::WinSendMsg(hWnd, EM_SETFIRSTCHAR, MPFROMLONG(lPos), (MPARAM)0);
250 } // end of wxComboBox::SetInsertionPoint
251
252 void wxComboBox::SetInsertionPointEnd()
253 {
254 long lPos = GetLastPosition();
255
256 SetInsertionPoint(lPos);
257 } // end of wxComboBox::SetInsertionPointEnd
258
259 long wxComboBox::GetInsertionPoint() const
260 {
261 long lPos = LONGFROMMR(::WinSendMsg( GetHwnd()
262 ,LM_QUERYSELECTION
263 ,(MPARAM)0
264 ,(MPARAM)0
265 ));
266 if (lPos == LIT_NONE)
267 return wxNOT_FOUND;
268 return lPos;
269 } // end of wxComboBox::GetInsertionPoint
270
271 long wxComboBox::GetLastPosition() const
272 {
273 HWND hEditWnd = GetHwnd();
274 long lLineLength = 0L;
275 WNDPARAMS vParams;
276
277 //
278 // Get number of characters in the last (only) line. We'll add this to the character
279 // index for the last line, 1st position.
280 //
281
282
283 vParams.fsStatus = WPM_CCHTEXT;
284 if (::WinSendMsg( GetHwnd()
285 ,WM_QUERYWINDOWPARAMS
286 ,&vParams
287 ,0
288 ))
289 {
290 lLineLength = (long)vParams.cchText;
291 }
292 else
293 lLineLength = 0L;
294 return lLineLength;
295 } // end of wxComboBox::GetLastPosition
296
297 void wxComboBox::Replace(
298 long lFrom
299 , long lTo
300 , const wxString& rsValue
301 )
302 {
303 #if wxUSE_CLIPBOARD
304 HWND hWnd = GetHwnd();
305 long lFromChar = lFrom;
306 long lToChar = lTo;
307
308 //
309 // Set selection and remove it
310 //
311 ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
312 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
313
314 //
315 // Now replace with 'value', by pasting.
316 //
317 wxSetClipboardData( wxDF_TEXT
318 ,(wxObject *)rsValue.c_str()
319 ,0
320 ,0
321 );
322
323 //
324 // Paste into edit control
325 //
326 ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0L);
327 #endif
328 } // end of wxComboBox::Replace
329
330 void wxComboBox::Remove(
331 long lFrom
332 , long lTo
333 )
334 {
335 #if wxUSE_CLIPBOARD
336 HWND hWnd = GetHwnd();
337 long lFromChar = lFrom;
338 long lToChar = lTo;
339
340 ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
341 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
342 #endif
343 } // end of wxComboBox::Remove
344
345 void wxComboBox::SetSelection(
346 long lFrom
347 , long lTo
348 )
349 {
350 HWND hWnd = GetHwnd();
351 long lFromChar = lFrom;
352 long lToChar = lTo;
353
354 //
355 // If from and to are both -1, it means
356 // (in wxWindows) that all text should be selected.
357 // This translates into Windows convention
358 //
359 if ((lFrom == -1L) && (lTo == -1L))
360 {
361 lFromChar = 0;
362 lToChar = -1;
363 }
364
365 ::WinSendMsg( hWnd
366 ,EM_SETSEL
367 ,MPFROM2SHORT((USHORT)lFromChar, (USHORT)lToChar)
368 ,(MPARAM)0
369 );
370 } // end of wxComboBox::SetSelection
371
372 void wxComboBox::DoSetSize(
373 int nX
374 , int nY
375 , int nWidth
376 , int nHeight
377 , int nSizeFlags
378 )
379 {
380 wxControl::DoSetSize( nX
381 ,nY
382 ,nWidth
383 ,nHeight
384 ,nSizeFlags
385 );
386 } // end of wxComboBox::DoSetSize
387
388 bool wxComboBox::ProcessEditMsg(
389 WXUINT uMsg
390 , WXWPARAM wParam
391 , WXLPARAM lParam)
392 {
393 SHORT vFlag;
394 switch (uMsg)
395 {
396 case WM_CHAR:
397 vFlag = SHORT1FROMMP(wParam);
398 switch(vFlag)
399 {
400 case KC_CHAR:
401 return (HandleChar( SHORT1FROMMP(wParam)
402 ,lParam
403 ,TRUE /* isASCII */
404 ));
405
406 case KC_PREVDOWN:
407 return (HandleKeyDown( SHORT1FROMMP(wParam)
408 ,lParam
409 ));
410
411 case KC_KEYUP:
412 return (HandleKeyUp( SHORT1FROMMP(wParam)
413 ,lParam
414 ));
415 }
416 break;
417 }
418 return FALSE;
419 } // end of WinGuiBase_CComboBox::ProcessEditMsg
420
421 MRESULT EXPENTRY wxComboEditWndProc(
422 HWND hWnd
423 , UINT uMessage
424 , MPARAM wParam
425 , MPARAM lParam
426 )
427 {
428 HWND hWndCombo;
429 wxWindow* pWin = NULL;
430
431 hWndCombo = ::WinQueryWindow(hWnd, QW_PARENT);
432 pWin = (wxWindow*)wxFindWinFromHandle((WXHWND)hWndCombo);
433 switch (uMessage)
434 {
435 //
436 // Forward some messages to the combobox
437 //
438 case WM_CHAR:
439 {
440 wxComboBox* pCombo = wxDynamicCast( pWin
441 ,wxComboBox
442 );
443
444 if (pCombo->ProcessEditMsg( uMessage
445 ,wParam
446 ,lParam
447 ))
448 return ((MRESULT)0);
449 }
450 break;
451
452 //
453 // TODO: Deal with tooltips here
454 //
455 }
456 return (gfnWndprocEdit(hWnd, (ULONG)uMessage, (MPARAM)wParam, (MPARAM)lParam));
457 } // end of wxComboEditWndProc
458
459 #endif
460 // wxUSE_COMBOBOX
461