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