]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/choice.cpp
fixed memory leak in RestoreState
[wxWidgets.git] / src / os2 / choice.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/os2/choice.cpp
3// Purpose: wxChoice
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_CHOICE
16
17#include "wx/choice.h"
18
19#ifndef WX_PRECOMP
20 #include "wx/utils.h"
21 #include "wx/log.h"
22 #include "wx/settings.h"
23#endif
24
25#include "wx/os2/private.h"
26
27IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControlWithItems)
28
29bool wxChoice::Create(
30 wxWindow* pParent
31, wxWindowID vId
32, const wxPoint& rPos
33, const wxSize& rSize
34, const wxArrayString& asChoices
35, long lStyle
36, const wxValidator& rValidator
37, const wxString& rsName
38)
39{
40 wxCArrayString chs(asChoices);
41
42 return Create(pParent, vId, rPos, rSize, chs.GetCount(), chs.GetStrings(),
43 lStyle, rValidator, rsName);
44}
45
46bool wxChoice::Create(
47 wxWindow* pParent
48, wxWindowID vId
49, const wxPoint& rPos
50, const wxSize& rSize
51, int n
52, const wxString asChoices[]
53, long lStyle
54, const wxValidator& rValidator
55, const wxString& rsName
56)
57{
58 long lSstyle;
59
60 if (!CreateControl( pParent
61 ,vId
62 ,rPos
63 ,rSize
64 ,lStyle
65 ,rValidator
66 ,rsName
67 ))
68 return false;
69 lSstyle = CBS_DROPDOWNLIST |
70 WS_TABSTOP |
71 WS_VISIBLE;
72
73 // clipping siblings does not yet work
74 // if (lStyle & wxCLIP_SIBLINGS )
75 // lSstyle |= WS_CLIPSIBLINGS;
76
77 wxASSERT_MSG( !(lStyle & wxCB_DROPDOWN) &&
78 !(lStyle & wxCB_READONLY) &&
79 !(lStyle & wxCB_SIMPLE),
80 wxT("this style flag is ignored by wxChoice, you "
81 "probably want to use a wxComboBox") );
82
83 if (!OS2CreateControl( wxT("COMBOBOX")
84 ,lSstyle
85 ))
86 return false;
87
88 //
89 // A choice/combobox normally has a white background (or other, depending
90 // on global settings) rather than inheriting the parent's background colour.
91 //
92 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
93
94 // initialize the controls contents
95 for (int i = 0; i < n; i++)
96 {
97 Append(asChoices[i]);
98 }
99 SetSize( rPos.x
100 ,rPos.y
101 ,rSize.x
102 ,rSize.y
103 );
104
105 // Set height to use with sizers i.e. without the dropdown listbox
106 wxFont vFont = GetFont();
107 int nEditHeight;
108 wxGetCharSize( GetHWND(), NULL, &nEditHeight, &vFont );
109 nEditHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nEditHeight);
110 SetInitialSize(wxSize(-1,nEditHeight+4)); // +2x2 for the border
111
112 return true;
113} // end of wxChoice::Create
114
115wxChoice::~wxChoice()
116{
117 Clear();
118}
119
120// ----------------------------------------------------------------------------
121// adding/deleting items to/from the list
122// ----------------------------------------------------------------------------
123
124int wxChoice::DoInsertItems(const wxArrayStringsAdapter& items
125 , unsigned int pos
126 , void **clientData
127 , wxClientDataType type
128 )
129{
130 int nIndex = wxNOT_FOUND;
131 LONG nIndexType = 0;
132 bool incrementPos = false;
133 if ( IsSorted() )
134 nIndexType = LIT_SORTASCENDING;
135 else if (pos == GetCount())
136 nIndexType = LIT_END;
137 else
138 {
139 nIndexType = pos;
140 incrementPos = true;
141 }
142
143 const unsigned int count = items.GetCount();
144 for( unsigned int i = 0; i < count; ++i )
145 {
146 nIndex = (int)::WinSendMsg( GetHwnd()
147 ,LM_INSERTITEM
148 ,(MPARAM)nIndexType
149 ,(MPARAM)items[i].wx_str()
150 );
151 if (nIndex < 0)
152 {
153 nIndex = wxNOT_FOUND;
154 break;
155 }
156 AssignNewItemClientData(nIndex, clientData, i, type);
157
158 if (incrementPos)
159 ++nIndexType;
160 }
161 return nIndex;
162} // end of wxChoice::DoInsertAppendItemsWithData
163
164void wxChoice::DoDeleteOneItem(unsigned int n)
165{
166 wxCHECK_RET( IsValid(n), wxT("invalid item index in wxChoice::Delete") );
167
168 ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0);
169} // end of wxChoice::Delete
170
171void wxChoice::DoClear()
172{
173 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
174} // end of wxChoice::Clear
175
176// ----------------------------------------------------------------------------
177// selection
178// ----------------------------------------------------------------------------
179
180int wxChoice::GetSelection() const
181{
182 return((int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0)));
183} // end of wxChoice::GetSelection
184
185void wxChoice::SetSelection(
186 int n
187)
188{
189 ::WinSendMsg( GetHwnd()
190 ,LM_SELECTITEM
191 ,(MPARAM)n
192 ,(MPARAM)TRUE
193 );
194} // end of wxChoice::SetSelection
195
196// ----------------------------------------------------------------------------
197// string list functions
198// ----------------------------------------------------------------------------
199
200unsigned int wxChoice::GetCount() const
201{
202 return((unsigned int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMCOUNT, (MPARAM)0, (MPARAM)0)));
203} // end of wxChoice::GetCount
204
205void wxChoice::SetString(unsigned int n, const wxString& rsStr)
206{
207 LONG nIndexType = 0;
208 void* pData;
209
210 if ( m_clientDataItemsType != wxClientData_None )
211 {
212 pData = DoGetItemClientData(n);
213 }
214 else // no client data
215 {
216 pData = NULL;
217 }
218
219 ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, 0);
220
221 if (m_windowStyle & wxCB_SORT)
222 nIndexType = LIT_SORTASCENDING;
223 else
224 nIndexType = LIT_END;
225 ::WinSendMsg( GetHwnd()
226 ,LM_INSERTITEM
227 ,(MPARAM)nIndexType
228 ,(MPARAM)rsStr.wx_str()
229 );
230
231 if (pData)
232 {
233 DoSetItemClientData(n, pData);
234 }
235} // end of wxChoice::SetString
236
237wxString wxChoice::GetString(unsigned int n) const
238{
239 int nLen = 0;
240 wxString sStr = wxEmptyString;
241 wxChar* zBuf;
242
243 nLen = (size_t)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)n, (MPARAM)0));
244 if (nLen != LIT_ERROR && nLen > 0)
245 {
246 zBuf = new wxChar[++nLen];
247 ::WinSendMsg( GetHwnd()
248 ,LM_QUERYITEMTEXT
249 ,MPFROM2SHORT((SHORT)n, (SHORT)nLen)
250 ,(MPARAM)zBuf
251 );
252 sStr = zBuf;
253 delete [] zBuf;
254 }
255 return sStr;
256} // end of wxChoice::GetString
257
258// ----------------------------------------------------------------------------
259// client data
260// ----------------------------------------------------------------------------
261
262void wxChoice::DoSetItemClientData(unsigned int n, void* pClientData)
263{
264 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)n, MPFROMP(pClientData));
265} // end of wxChoice::DoSetItemClientData
266
267void* wxChoice::DoGetItemClientData(unsigned int n) const
268{
269 MRESULT rc = ::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, (MPARAM)n, (MPARAM)0);
270 return((void*)rc);
271} // end of wxChoice::DoGetItemClientData
272
273// ----------------------------------------------------------------------------
274// wxOS2 specific helpers
275// ----------------------------------------------------------------------------
276
277void wxChoice::DoSetSize(int nX,
278 int nY,
279 int nWidth,
280 int WXUNUSED(nHeight),
281 int nSizeFlags)
282{
283 //
284 // Ignore height parameter because height doesn't mean 'initially
285 // displayed' height, it refers to the drop-down menu as well. The
286 // wxWidgets interpretation is different; also, getting the size returns
287 // the _displayed_ size (NOT the drop down menu size) so
288 // setting-getting-setting size would not work.
289 //
290 wxControl::DoSetSize( nX
291 ,nY
292 ,nWidth
293 ,wxDefaultCoord
294 ,nSizeFlags
295 );
296} // end of wxChoice::DoSetSize
297
298wxSize wxChoice::DoGetBestSize() const
299{
300 //
301 // Find the widest string
302 //
303 int nLineWidth;
304 int nChoiceWidth = 0;
305 int nCx;
306 int nCy;
307 wxFont vFont = (wxFont)GetFont();
308
309 const unsigned int nItems = GetCount();
310
311 for (unsigned int i = 0; i < nItems; i++)
312 {
313 wxString sStr(GetString(i));
314 GetTextExtent( sStr, &nLineWidth, NULL );
315 if (nLineWidth > nChoiceWidth)
316 nChoiceWidth = nLineWidth;
317 }
318
319 //
320 // Give it some reasonable default value if there are no strings in the
321 // list
322 //
323 if (nChoiceWidth == 0L)
324 nChoiceWidth = 100L;
325
326 //
327 // The combobox should be larger than the widest string
328 //
329 wxGetCharSize( GetHWND(), &nCx, &nCy, &vFont );
330 nChoiceWidth += 5 * nCx;
331
332 //
333 // Choice drop-down list depends on number of items (limited to 10)
334 //
335 size_t nStrings = nItems == 0 ? 10 : wxMin(10, nItems) + 1;
336 int nChoiceHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * nStrings;
337
338 return wxSize(nChoiceWidth, nChoiceHeight);
339} // end of wxChoice::DoGetBestSize
340
341MRESULT wxChoice::OS2WindowProc(
342 WXUINT uMsg
343, WXWPARAM wParam
344, WXLPARAM lParam
345)
346{
347 return wxWindow::OS2WindowProc( uMsg
348 ,wParam
349 ,lParam
350 );
351} // end of wxChoice::OS2WindowProc
352
353bool wxChoice::OS2Command(
354 WXUINT uParam
355, WXWORD WXUNUSED(wId)
356)
357{
358 if (uParam != LN_SELECT)
359 {
360 //
361 // "selection changed" is the only event we're after
362 //
363 return false;
364 }
365 int n = GetSelection();
366
367 if (n > -1)
368 {
369 wxCommandEvent vEvent( wxEVT_COMMAND_CHOICE_SELECTED
370 ,m_windowId
371 );
372
373 vEvent.SetInt(n);
374 vEvent.SetEventObject(this);
375 vEvent.SetString(GetStringSelection());
376 if (HasClientObjectData())
377 vEvent.SetClientObject(GetClientObject(n));
378 else if (HasClientUntypedData())
379 vEvent.SetClientData(GetClientData(n));
380 ProcessCommand(vEvent);
381 }
382 return true;
383} // end of wxChoice::OS2Command
384
385#endif // wxUSE_CHOICE