]> git.saurik.com Git - wxWidgets.git/blob - src/os2/combobox.cpp
survive delete within Notify
[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 (!CreateControl( 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 wxFont* pTextFont = new wxFont( 10
147 ,wxMODERN
148 ,wxNORMAL
149 ,wxNORMAL
150 );
151 SetFont(*pTextFont);
152
153 int i;
154 for (i = 0; i < n; i++)
155 {
156 Append(asChoices[i]);
157 }
158
159 SetSize( rPos.x
160 ,rPos.y
161 ,rSize.x
162 ,rSize.y
163 );
164 if (!rsValue.IsEmpty())
165 {
166 SetValue(rsValue);
167 }
168 gfnWndprocEdit = (WXFARPROC)::WinSubclassWindow( (HWND)GetHwnd()
169 ,(PFNWP)wxComboEditWndProc
170 );
171 ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
172 delete pTextFont;
173 return TRUE;
174 } // end of wxComboBox::Create
175
176 void wxComboBox::SetValue(
177 const wxString& rsValue
178 )
179 {
180 //
181 // If newlines are denoted by just 10, must stick 13 in front.
182 //
183 int nSingletons = 0;
184 int nLen = rsValue.Length();
185 int i;
186
187 for (i = 0; i < nLen; i ++)
188 {
189 if ((i > 0) && (rsValue[i] == 10) && (rsValue[i - 1] != 13))
190 nSingletons ++;
191 }
192 if (nSingletons > 0)
193 {
194 wxChar* zTmp = new wxChar[nLen + nSingletons + 1];
195 int j = 0;
196
197 for (i = 0; i < nLen; i ++)
198 {
199 if ((i > 0) && (rsValue[i] == 10) && (rsValue[i - 1] != 13))
200 {
201 zTmp[j] = 13;
202 j++;
203 }
204 zTmp[j] = rsValue[i];
205 j++;
206 }
207 zTmp[j] = 0;
208 ::WinSetWindowText(GetHwnd(), zTmp);
209 delete[] zTmp;
210 }
211 else
212 ::WinSetWindowText(GetHwnd(), rsValue.c_str());
213 } // end of wxComboBox::SetValue
214
215 //
216 // Clipboard operations
217 //
218 void wxComboBox::Copy()
219 {
220 HWND hWnd = GetHwnd();
221
222 ::WinSendMsg(hWnd, EM_COPY, (MPARAM)0, (MPARAM)0);
223 } // end of wxComboBox::Copy
224
225 void wxComboBox::Cut()
226 {
227 HWND hWnd = GetHwnd();
228
229 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
230 } // end of wxComboBox::Cut
231
232 void wxComboBox::Paste()
233 {
234 HWND hWnd = GetHwnd();
235
236 ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0);
237 } // end of wxComboBox::Paste
238
239 void wxComboBox::SetEditable(
240 bool bEditable
241 )
242 {
243 HWND hWnd = GetHwnd();
244
245 ::WinSendMsg(hWnd, EM_SETREADONLY, (MPARAM)!bEditable, (MPARAM)0L);
246 } // end of wxComboBox::SetEditable
247
248 void wxComboBox::SetInsertionPoint(
249 long lPos
250 )
251 {
252 HWND hWnd = GetHwnd();
253
254 ::WinSendMsg(hWnd, EM_SETFIRSTCHAR, MPFROMLONG(lPos), (MPARAM)0);
255 } // end of wxComboBox::SetInsertionPoint
256
257 void wxComboBox::SetInsertionPointEnd()
258 {
259 long lPos = GetLastPosition();
260
261 SetInsertionPoint(lPos);
262 } // end of wxComboBox::SetInsertionPointEnd
263
264 long wxComboBox::GetInsertionPoint() const
265 {
266 long lPos = LONGFROMMR(::WinSendMsg( GetHwnd()
267 ,LM_QUERYSELECTION
268 ,(MPARAM)0
269 ,(MPARAM)0
270 ));
271 if (lPos == LIT_NONE)
272 return wxNOT_FOUND;
273 return lPos;
274 } // end of wxComboBox::GetInsertionPoint
275
276 long wxComboBox::GetLastPosition() const
277 {
278 HWND hEditWnd = GetHwnd();
279 long lLineLength = 0L;
280 WNDPARAMS vParams;
281
282 //
283 // Get number of characters in the last (only) line. We'll add this to the character
284 // index for the last line, 1st position.
285 //
286
287
288 vParams.fsStatus = WPM_CCHTEXT;
289 if (::WinSendMsg( GetHwnd()
290 ,WM_QUERYWINDOWPARAMS
291 ,&vParams
292 ,0
293 ))
294 {
295 lLineLength = (long)vParams.cchText;
296 }
297 else
298 lLineLength = 0L;
299 return lLineLength;
300 } // end of wxComboBox::GetLastPosition
301
302 void wxComboBox::Replace(
303 long lFrom
304 , long lTo
305 , const wxString& rsValue
306 )
307 {
308 #if wxUSE_CLIPBOARD
309 HWND hWnd = GetHwnd();
310 long lFromChar = lFrom;
311 long lToChar = lTo;
312
313 //
314 // Set selection and remove it
315 //
316 ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
317 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
318
319 //
320 // Now replace with 'value', by pasting.
321 //
322 wxSetClipboardData( wxDF_TEXT
323 ,(wxObject *)rsValue.c_str()
324 ,0
325 ,0
326 );
327
328 //
329 // Paste into edit control
330 //
331 ::WinSendMsg(hWnd, EM_PASTE, (MPARAM)0, (MPARAM)0L);
332 #endif
333 } // end of wxComboBox::Replace
334
335 void wxComboBox::Remove(
336 long lFrom
337 , long lTo
338 )
339 {
340 #if wxUSE_CLIPBOARD
341 HWND hWnd = GetHwnd();
342 long lFromChar = lFrom;
343 long lToChar = lTo;
344
345 ::WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT((USHORT)lFrom, (USHORT)lTo), 0);
346 ::WinSendMsg(hWnd, EM_CUT, (MPARAM)0, (MPARAM)0);
347 #endif
348 } // end of wxComboBox::Remove
349
350 void wxComboBox::SetSelection(
351 long lFrom
352 , long lTo
353 )
354 {
355 HWND hWnd = GetHwnd();
356 long lFromChar = lFrom;
357 long lToChar = lTo;
358
359 //
360 // If from and to are both -1, it means
361 // (in wxWindows) that all text should be selected.
362 // This translates into Windows convention
363 //
364 if ((lFrom == -1L) && (lTo == -1L))
365 {
366 lFromChar = 0;
367 lToChar = -1;
368 }
369
370 ::WinSendMsg( hWnd
371 ,EM_SETSEL
372 ,MPFROM2SHORT((USHORT)lFromChar, (USHORT)lToChar)
373 ,(MPARAM)0
374 );
375 } // end of wxComboBox::SetSelection
376
377 void wxComboBox::DoSetSize(
378 int nX
379 , int nY
380 , int nWidth
381 , int nHeight
382 , int nSizeFlags
383 )
384 {
385 wxControl::DoSetSize( nX
386 ,nY
387 ,nWidth
388 ,nHeight
389 ,nSizeFlags
390 );
391 } // end of wxComboBox::DoSetSize
392
393 bool wxComboBox::ProcessEditMsg(
394 WXUINT uMsg
395 , WXWPARAM wParam
396 , WXLPARAM lParam)
397 {
398 SHORT vFlag;
399 switch (uMsg)
400 {
401 case WM_CHAR:
402 vFlag = SHORT1FROMMP(wParam);
403 switch(vFlag)
404 {
405 case KC_CHAR:
406 return (HandleChar( wParam
407 ,lParam
408 ,TRUE /* isASCII */
409 ));
410
411 case KC_PREVDOWN:
412 return (HandleKeyDown( wParam
413 ,lParam
414 ));
415
416 case KC_KEYUP:
417 return (HandleKeyUp( wParam
418 ,lParam
419 ));
420 }
421 break;
422
423 case WM_SETFOCUS:
424 if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
425 return(HandleSetFocus((WXHWND)(HWND)wParam));
426 else
427 return(HandleKillFocus((WXHWND)(HWND)wParam));
428 break;
429 }
430 return FALSE;
431 } // end of WinGuiBase_CComboBox::ProcessEditMsg
432
433 MRESULT EXPENTRY wxComboEditWndProc(
434 HWND hWnd
435 , UINT uMessage
436 , MPARAM wParam
437 , MPARAM lParam
438 )
439 {
440 HWND hWndCombo;
441 wxWindow* pWin = NULL;
442
443 hWndCombo = ::WinQueryWindow(hWnd, QW_PARENT);
444 pWin = (wxWindow*)wxFindWinFromHandle((WXHWND)hWndCombo);
445 switch (uMessage)
446 {
447 //
448 // Forward some messages to the combobox
449 //
450 case WM_SETFOCUS:
451 case WM_CHAR:
452 {
453 wxComboBox* pCombo = wxDynamicCast( pWin
454 ,wxComboBox
455 );
456
457 if (pCombo->ProcessEditMsg( uMessage
458 ,wParam
459 ,lParam
460 ))
461 return ((MRESULT)0);
462 }
463 break;
464
465 //
466 // TODO: Deal with tooltips here
467 //
468 }
469 return (gfnWndprocEdit(hWnd, (ULONG)uMessage, (MPARAM)wParam, (MPARAM)lParam));
470 } // end of wxComboEditWndProc
471
472 #endif
473 // wxUSE_COMBOBOX
474