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