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