]> git.saurik.com Git - wxWidgets.git/blob - src/os2/combobox.cpp
Fix memory leak if wxDC::DrawBitmap() fails in wxOS2.
[wxWidgets.git] / src / os2 / combobox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/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 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxUSE_COMBOBOX
16
17 #include "wx/combobox.h"
18
19 #ifndef WX_PRECOMP
20 #include "wx/settings.h"
21 #endif
22
23 #include "wx/clipbrd.h"
24 #include "wx/os2/private.h"
25
26 #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
27
28 MRESULT EXPENTRY wxComboEditWndProc( HWND hWnd
29 ,UINT uMessage
30 ,MPARAM wParam
31 ,MPARAM lParam
32 );
33 //
34 // The pointer to standard wnd proc
35 //
36 static WXFARPROC gfnWndprocEdit = (WXFARPROC)NULL;
37
38 IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)
39
40 bool wxComboBox::OS2Command( WXUINT uParam, WXWORD WXUNUSED(wId) )
41 {
42 long lSel = GetSelection();
43 wxString sValue;
44
45 switch (uParam)
46 {
47 case CBN_LBSELECT:
48 if (lSel > -1)
49 {
50 wxCommandEvent vEvent( wxEVT_COMMAND_COMBOBOX_SELECTED, GetId() );
51
52 vEvent.SetInt(lSel);
53 vEvent.SetEventObject(this);
54 vEvent.SetString(GetStringSelection());
55
56 ProcessCommand(vEvent);
57 }
58 break;
59
60 case CBN_EFCHANGE:
61 {
62 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED, GetId() );
63
64 if (lSel == -1L)
65 sValue = GetValue();
66 else
67 sValue = GetStringSelection();
68 vEvent.SetString(sValue);
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
76 // false from here to pass the message to DefWindowProc()
77 //
78 return false;
79 } // end of wxComboBox::OS2Command
80
81 bool 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
99 bool 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
108 , const wxValidator& rValidator
109 , const wxString& rsName
110 )
111 {
112 m_isShown = false;
113
114 if (!CreateControl( pParent
115 ,vId
116 ,rPos
117 ,rSize
118 ,lStyle
119 ,rValidator
120 ,rsName
121 ))
122 return false;
123
124 //
125 // Get the right style
126 //
127 long lSstyle = 0L;
128
129 lSstyle = WS_TABSTOP |
130 WS_VISIBLE;
131
132 // clipping siblings does not yet work
133 // if (lStyle & wxCLIP_SIBLINGS )
134 // lSstyle |= WS_CLIPSIBLINGS;
135 if (lStyle & wxCB_READONLY)
136 lSstyle |= CBS_DROPDOWNLIST;
137 else if (lStyle & wxCB_SIMPLE)
138 lSstyle |= CBS_SIMPLE; // A list (shown always) and edit control
139 else
140 lSstyle |= CBS_DROPDOWN;
141
142
143 if (!OS2CreateControl( wxT("COMBOBOX")
144 ,lSstyle
145 ))
146 return false;
147
148 //
149 // A choice/combobox normally has a white background (or other, depending
150 // on global settings) rather than inheriting the parent's background colour.
151 //
152 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
153
154 for (int 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
165 // Set height to use with sizers i.e. without the dropdown listbox
166 wxFont vFont = GetFont();
167 int nEditHeight;
168 wxGetCharSize( GetHWND(), NULL, &nEditHeight, &vFont );
169 nEditHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nEditHeight);
170 SetInitialSize(wxSize(-1,nEditHeight+4)); // +2x2 for the border
171
172 if (!rsValue.empty())
173 {
174 SetValue(rsValue);
175 }
176 gfnWndprocEdit = (WXFARPROC)::WinSubclassWindow( (HWND)GetHwnd()
177 ,(PFNWP)wxComboEditWndProc
178 );
179 ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
180 Show(true);
181 return true;
182 } // end of wxComboBox::Create
183
184 wxString wxComboBox::GetValue() const
185 {
186 return HasFlag(wxCB_READONLY) ? GetStringSelection()
187 : wxTextEntry::GetValue();
188 }
189
190 void wxComboBox::SetValue(const wxString& value)
191 {
192 if ( HasFlag(wxCB_READONLY) )
193 SetStringSelection(value);
194 else
195 wxTextEntry::SetValue(value);
196 }
197
198 void wxComboBox::Clear()
199 {
200 wxChoice::Clear();
201 if ( !HasFlag(wxCB_READONLY) )
202 wxTextEntry::Clear();
203 }
204
205 bool wxComboBox::IsEditable() const
206 {
207 return !HasFlag(wxCB_READONLY) && wxTextEntry::IsEditable();
208 }
209
210 bool wxComboBox::ProcessEditMsg(
211 WXUINT uMsg
212 , WXWPARAM wParam
213 , WXLPARAM lParam)
214 {
215 SHORT vFlag;
216 switch (uMsg)
217 {
218 case WM_CHAR:
219 vFlag = SHORT1FROMMP(wParam);
220 switch(vFlag)
221 {
222 case KC_CHAR:
223 return (HandleChar( wParam
224 ,lParam
225 ,true /* isASCII */
226 ));
227
228 case KC_PREVDOWN:
229 return (HandleKeyDown( wParam
230 ,lParam
231 ));
232
233 case KC_KEYUP:
234 return (HandleKeyUp( wParam
235 ,lParam
236 ));
237 }
238 break;
239
240 case WM_SETFOCUS:
241 if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
242 return(HandleSetFocus((WXHWND)(HWND)wParam));
243 else
244 return(HandleKillFocus((WXHWND)(HWND)wParam));
245 }
246 return false;
247 } // end of wxComboBox::ProcessEditMsg
248
249 MRESULT EXPENTRY wxComboEditWndProc(
250 HWND hWnd
251 , UINT uMessage
252 , MPARAM wParam
253 , MPARAM lParam
254 )
255 {
256 switch (uMessage)
257 {
258 //
259 // Forward some messages to the combobox
260 //
261 case WM_SETFOCUS:
262 case WM_CHAR:
263 {
264 wxComboBox* pCombo = (wxComboBox *)::WinQueryWindowULong( hWnd
265 ,QWL_USER
266 );
267
268 if (pCombo->ProcessEditMsg( uMessage
269 ,wParam
270 ,lParam
271 ))
272 return ((MRESULT)0);
273 }
274 break;
275
276 //
277 // TODO: Deal with tooltips here
278 //
279 }
280 return (gfnWndprocEdit(hWnd, (ULONG)uMessage, (MPARAM)wParam, (MPARAM)lParam));
281 } // end of wxComboEditWndProc
282
283 #endif
284 // wxUSE_COMBOBOX