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