]> git.saurik.com Git - wxWidgets.git/blob - src/os2/listbox.cpp
use correct way to get a pointer to vector elements in DoGetPartialTextExtents()
[wxWidgets.git] / src / os2 / listbox.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: listbox.cpp
3 // Purpose: wxListBox
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/09/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 #include "wx/window.h"
16 #include "wx/os2/private.h"
17
18 #ifndef WX_PRECOMP
19 #include "wx/listbox.h"
20 #include "wx/settings.h"
21 #include "wx/brush.h"
22 #include "wx/font.h"
23 #include "wx/dc.h"
24 #include "wx/dcscreen.h"
25 #include "wx/utils.h"
26 #include "wx/scrolwin.h"
27 #endif
28
29 #define INCL_M
30 #include <os2.h>
31
32 #include "wx/dynarray.h"
33 #include "wx/log.h"
34
35 #if wxUSE_LISTBOX
36
37 #if wxUSE_OWNER_DRAWN
38 #include "wx/ownerdrw.h"
39 #endif
40
41 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
42
43 // ============================================================================
44 // list box item declaration and implementation
45 // ============================================================================
46
47 #if wxUSE_OWNER_DRAWN
48
49 class wxListBoxItem : public wxOwnerDrawn
50 {
51 public:
52 wxListBoxItem(const wxString& rsStr = "");
53 };
54
55 wxListBoxItem::wxListBoxItem(
56 const wxString& rsStr
57 )
58 : wxOwnerDrawn( rsStr
59 ,FALSE
60 )
61 {
62 //
63 // No bitmaps/checkmarks
64 //
65 SetMarginWidth(0);
66 } // end of wxListBoxItem::wxListBoxItem
67
68 wxOwnerDrawn* wxListBox::CreateItem(
69 size_t n
70 )
71 {
72 return new wxListBoxItem();
73 } // end of wxListBox::CreateItem
74
75 #endif //USE_OWNER_DRAWN
76
77 // ============================================================================
78 // list box control implementation
79 // ============================================================================
80
81 // Listbox item
82 wxListBox::wxListBox()
83 {
84 m_nNumItems = 0;
85 m_nSelected = 0;
86 } // end of wxListBox::wxListBox
87
88 bool wxListBox::Create(
89 wxWindow* pParent
90 , wxWindowID vId
91 , const wxPoint& rPos
92 , const wxSize& rSize
93 , const wxArrayString& asChoices
94 , long lStyle
95 , const wxValidator& rValidator
96 , const wxString& rsName
97 )
98 {
99 wxCArrayString chs(asChoices);
100
101 return Create(pParent, vId, rPos, rSize, chs.GetCount(), chs.GetStrings(),
102 lStyle, rValidator, rsName);
103 }
104
105 bool wxListBox::Create(
106 wxWindow* pParent
107 , wxWindowID vId
108 , const wxPoint& rPos
109 , const wxSize& rSize
110 , int n
111 , const wxString asChoices[]
112 , long lStyle
113 , const wxValidator& rValidator
114 , const wxString& rsName
115 )
116 {
117 m_nNumItems = 0;
118 m_hWnd = 0;
119 m_nSelected = 0;
120
121 SetName(rsName);
122 #if wxUSE_VALIDATORS
123 SetValidator(rValidator);
124 #endif
125
126 if (pParent)
127 pParent->AddChild(this);
128
129 wxSystemSettings vSettings;
130
131 SetBackgroundColour(vSettings.GetSystemColour(wxSYS_COLOUR_WINDOW));
132 SetForegroundColour(pParent->GetForegroundColour());
133
134 m_windowId = (vId == -1) ? (int)NewControlId() : vId;
135
136 int nX = rPos.x;
137 int nY = rPos.y;
138 int nWidth = rSize.x;
139 int nHeight = rSize.y;
140
141 m_windowStyle = lStyle;
142
143 lStyle = WS_VISIBLE;
144
145 if (m_windowStyle & wxCLIP_SIBLINGS )
146 lStyle |= WS_CLIPSIBLINGS;
147 if (m_windowStyle & wxLB_MULTIPLE)
148 lStyle |= LS_MULTIPLESEL;
149 else if (m_windowStyle & wxLB_EXTENDED)
150 lStyle |= LS_EXTENDEDSEL;
151 if (m_windowStyle & wxLB_HSCROLL)
152 lStyle |= LS_HORZSCROLL;
153 if (m_windowStyle & wxLB_OWNERDRAW)
154 lStyle |= LS_OWNERDRAW;
155
156 //
157 // Without this style, you get unexpected heights, so e.g. constraint layout
158 // doesn't work properly
159 //
160 lStyle |= LS_NOADJUSTPOS;
161
162 m_hWnd = (WXHWND)::WinCreateWindow( GetWinHwnd(pParent) // Parent
163 ,WC_LISTBOX // Default Listbox class
164 ,"LISTBOX" // Control's name
165 ,lStyle // Initial Style
166 ,0, 0, 0, 0 // Position and size
167 ,GetWinHwnd(pParent) // Owner
168 ,HWND_TOP // Z-Order
169 ,(HMENU)m_windowId // Id
170 ,NULL // Control Data
171 ,NULL // Presentation Parameters
172 );
173 if (m_hWnd == 0)
174 {
175 return FALSE;
176 }
177
178 //
179 // Subclass again for purposes of dialog editing mode
180 //
181 SubclassWin(m_hWnd);
182
183 LONG lUi;
184
185 for (lUi = 0; lUi < (LONG)n; lUi++)
186 {
187 Append(asChoices[lUi]);
188 }
189 wxFont* pTextFont = new wxFont( 10
190 ,wxMODERN
191 ,wxNORMAL
192 ,wxNORMAL
193 );
194 SetFont(*pTextFont);
195
196 //
197 // Set standard wxWindows colors for Listbox items and highlighting
198 //
199 wxColour vColour;
200
201 vColour.Set(wxString("WHITE"));
202
203 LONG lColor = (LONG)vColour.GetPixel();
204
205 ::WinSetPresParam( m_hWnd
206 ,PP_HILITEFOREGROUNDCOLOR
207 ,sizeof(LONG)
208 ,(PVOID)&lColor
209 );
210 vColour.Set(wxString("NAVY"));
211 lColor = (LONG)vColour.GetPixel();
212 ::WinSetPresParam( m_hWnd
213 ,PP_HILITEBACKGROUNDCOLOR
214 ,sizeof(LONG)
215 ,(PVOID)&lColor
216 );
217
218 SetSize( nX
219 ,nY
220 ,nWidth
221 ,nHeight
222 );
223 delete pTextFont;
224 return TRUE;
225 } // end of wxListBox::Create
226
227 wxListBox::~wxListBox()
228 {
229 #if wxUSE_OWNER_DRAWN
230 size_t lUiCount = m_aItems.Count();
231
232 while (lUiCount-- != 0)
233 {
234 delete m_aItems[lUiCount];
235 }
236 #endif // wxUSE_OWNER_DRAWN
237 } // end of wxListBox::~wxListBox
238
239 void wxListBox::SetupColours()
240 {
241 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
242 SetForegroundColour(GetParent()->GetForegroundColour());
243 } // end of wxListBox::SetupColours
244
245 // ----------------------------------------------------------------------------
246 // implementation of wxListBoxBase methods
247 // ----------------------------------------------------------------------------
248
249 void wxListBox::DoSetFirstItem(
250 int N
251 )
252 {
253 wxCHECK_RET( N >= 0 && N < m_nNumItems,
254 wxT("invalid index in wxListBox::SetFirstItem") );
255
256 ::WinSendMsg(GetHwnd(), LM_SETTOPINDEX, MPFROMLONG(N), (MPARAM)0);
257 } // end of wxListBox::DoSetFirstItem
258
259 void wxListBox::Delete(
260 int N
261 )
262 {
263 wxCHECK_RET( N >= 0 && N < m_nNumItems,
264 wxT("invalid index in wxListBox::Delete") );
265
266 #if wxUSE_OWNER_DRAWN
267 delete m_aItems[N];
268 m_aItems.RemoveAt(N);
269 #else // !wxUSE_OWNER_DRAWN
270 if (HasClientObjectData())
271 {
272 delete GetClientObject(N);
273 }
274 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
275
276 ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)N, (MPARAM)0);
277 m_nNumItems--;
278 } // end of wxListBox::DoSetFirstItem
279
280 int wxListBox::DoAppend(
281 const wxString& rsItem
282 )
283 {
284 int nIndex = 0;
285 SHORT nIndexType = 0;
286
287 if (m_windowStyle & wxLB_SORT)
288 nIndexType = LIT_SORTASCENDING;
289 else
290 nIndexType = LIT_END;
291 nIndex = (int)::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)nIndexType, (MPARAM)rsItem.c_str());
292 m_nNumItems++;
293
294 #if wxUSE_OWNER_DRAWN
295 if (m_windowStyle & wxLB_OWNERDRAW)
296 {
297 wxOwnerDrawn* pNewItem = CreateItem(nIndex); // dummy argument
298 wxScreenDC vDc;
299 wxCoord vHeight;
300
301
302 pNewItem->SetName(rsItem);
303 m_aItems.Insert(pNewItem, nIndex);
304 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)((SHORT)nIndex), MPFROMP(pNewItem));
305 pNewItem->SetFont(GetFont());
306 }
307 #endif
308 return nIndex;
309 } // end of wxListBox::DoAppend
310
311 void wxListBox::DoSetItems(
312 const wxArrayString& raChoices
313 , void** ppClientData
314 )
315 {
316 BOOL bHideAndShow = IsShown();
317 int nCount = 0;
318 int i;
319 SHORT nIndexType = 0;
320
321 if (bHideAndShow)
322 {
323 ::WinShowWindow(GetHwnd(), FALSE);
324 }
325 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
326 m_nNumItems = raChoices.GetCount();
327 for (i = 0; i < m_nNumItems; i++)
328 {
329
330 if (m_windowStyle & wxLB_SORT)
331 nIndexType = LIT_SORTASCENDING;
332 else
333 nIndexType = LIT_END;
334 ::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)nIndexType, (MPARAM)raChoices[i].c_str());
335
336 if (ppClientData)
337 {
338 #if wxUSE_OWNER_DRAWN
339 wxASSERT_MSG(ppClientData[i] == NULL,
340 wxT("Can't use client data with owner-drawn listboxes"));
341 #else // !wxUSE_OWNER_DRAWN
342 ::WinSendMsg(WinUtil_GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(lCount), MPFROMP(ppClientData[i]));
343 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
344 }
345 }
346
347 #if wxUSE_OWNER_DRAWN
348 if ( m_windowStyle & wxLB_OWNERDRAW )
349 {
350 //
351 // First delete old items
352 //
353 WX_CLEAR_ARRAY(m_aItems);
354
355 //
356 // Then create new ones
357 //
358 for (size_t ui = 0; ui < (size_t)m_nNumItems; ui++)
359 {
360 wxOwnerDrawn* pNewItem = CreateItem(ui);
361
362 pNewItem->SetName(raChoices[ui]);
363 m_aItems.Add(pNewItem);
364 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(ui), MPFROMP(pNewItem));
365 }
366 }
367 #endif // wxUSE_OWNER_DRAWN
368 ::WinShowWindow(GetHwnd(), TRUE);
369 } // end of wxListBox::DoSetItems
370
371 int wxListBox::FindString(
372 const wxString& rsString
373 ) const
374 {
375 int nPos;
376 LONG lTextLength;
377 PSZ zStr;
378
379
380 for (nPos = 0; nPos < m_nNumItems; nPos++)
381 {
382 lTextLength = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)nPos, (MPARAM)0));
383 zStr = new char[lTextLength + 1];
384 ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT(nPos, (SHORT)lTextLength), (MPARAM)zStr);
385 if (rsString == (char*)zStr)
386 {
387 delete [] zStr;
388 break;
389 }
390 delete [] zStr;
391 }
392 return nPos;
393 } // end of wxListBox::FindString
394
395 void wxListBox::Clear()
396 {
397 #if wxUSE_OWNER_DRAWN
398 size_t lUiCount = m_aItems.Count();
399
400 while (lUiCount-- != 0)
401 {
402 delete m_aItems[lUiCount];
403 }
404
405 m_aItems.Clear();
406 #else // !wxUSE_OWNER_DRAWN
407 if (HasClientObjectData())
408 {
409 for (size_t n = 0; n < (size_t)m_lNumItems; n++)
410 {
411 delete GetClientObject(n);
412 }
413 }
414 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
415 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
416
417 m_nNumItems = 0;
418 } // end of wxListBox::Clear
419
420 void wxListBox::SetSelection(
421 int N
422 , bool bSelect
423 )
424 {
425 wxCHECK_RET( N >= 0 && N < m_nNumItems,
426 wxT("invalid index in wxListBox::SetSelection") );
427 ::WinSendMsg( GetHwnd()
428 ,LM_SELECTITEM
429 ,MPFROMLONG(N)
430 ,(MPARAM)bSelect
431 );
432 if(m_windowStyle & wxLB_OWNERDRAW)
433 Refresh();
434 } // end of wxListBox::SetSelection
435
436 bool wxListBox::IsSelected(
437 int N
438 ) const
439 {
440 wxCHECK_MSG( N >= 0 && N < m_nNumItems, FALSE,
441 wxT("invalid index in wxListBox::Selected") );
442
443 LONG lItem;
444
445 if (GetWindowStyleFlag() & wxLB_EXTENDED)
446 {
447 if (N == 0)
448 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
449 else
450 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)(N - 1), (MPARAM)0));
451 }
452 else
453 {
454 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
455 }
456 return (lItem == (LONG)N && lItem != LIT_NONE);
457 } // end of wxListBox::IsSelected
458
459 wxClientData* wxListBox::DoGetItemClientObject(
460 int n
461 ) const
462 {
463 return (wxClientData *)DoGetItemClientData(n);
464 }
465
466 void* wxListBox::DoGetItemClientData(
467 int n
468 ) const
469 {
470 wxCHECK_MSG( n >= 0 && n < m_nNumItems, NULL,
471 wxT("invalid index in wxListBox::GetClientData") );
472
473 return((void *)::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, MPFROMLONG(n), (MPARAM)0));
474 } // end of wxListBox::DoGetItemClientData
475
476 void wxListBox::DoSetItemClientObject(
477 int n
478 , wxClientData* pClientData
479 )
480 {
481 DoSetItemClientData( n
482 ,pClientData
483 );
484 } // end of wxListBox::DoSetItemClientObject
485
486 void wxListBox::DoSetItemClientData(
487 int n
488 , void* pClientData
489 )
490 {
491 wxCHECK_RET( n >= 0 && n < m_nNumItems,
492 wxT("invalid index in wxListBox::SetClientData") );
493
494 #if wxUSE_OWNER_DRAWN
495 if ( m_windowStyle & wxLB_OWNERDRAW )
496 {
497 //
498 // Client data must be pointer to wxOwnerDrawn, otherwise we would crash
499 // in OnMeasure/OnDraw.
500 //
501 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
502 }
503 #endif // wxUSE_OWNER_DRAWN
504
505 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(n), MPFROMP(pClientData));
506 } // end of wxListBox::DoSetItemClientData
507
508 bool wxListBox::HasMultipleSelection() const
509 {
510 return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
511 } // end of wxListBox::HasMultipleSelection
512
513 int wxListBox::GetSelections(
514 wxArrayInt& raSelections
515 ) const
516 {
517 int nCount = 0;
518 LONG lItem;
519
520
521 raSelections.Empty();
522 if (HasMultipleSelection())
523 {
524 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
525 ,LM_QUERYSELECTION
526 ,(MPARAM)LIT_FIRST
527 ,(MPARAM)0
528 )
529 );
530 if (lItem != LIT_NONE)
531 {
532 nCount++;
533 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
534 ,LM_QUERYSELECTION
535 ,(MPARAM)lItem
536 ,(MPARAM)0
537 )
538 )) != LIT_NONE)
539 {
540 nCount++;
541 }
542 raSelections.Alloc(nCount);
543 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
544 ,LM_QUERYSELECTION
545 ,(MPARAM)LIT_FIRST
546 ,(MPARAM)0
547 )
548 );
549
550 raSelections.Add((int)lItem);
551 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
552 ,LM_QUERYSELECTION
553 ,(MPARAM)lItem
554 ,(MPARAM)0
555 )
556 )) != LIT_NONE)
557 {
558 raSelections.Add((int)lItem);
559 }
560 return nCount;
561 }
562 return 0;
563 }
564 else // single-selection listbox
565 {
566 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
567 ,LM_QUERYSELECTION
568 ,(MPARAM)LIT_FIRST
569 ,(MPARAM)0
570 )
571 );
572 raSelections.Add((int)lItem);
573 return 1;
574 }
575 return 0;
576 } // end of wxListBox::GetSelections
577
578 int wxListBox::GetSelection() const
579 {
580 wxCHECK_MSG( !HasMultipleSelection(),
581 -1,
582 wxT("GetSelection() can't be used with multiple-selection "
583 "listboxes, use GetSelections() instead.") );
584
585 return(LONGFROMMR(::WinSendMsg( GetHwnd()
586 ,LM_QUERYSELECTION
587 ,(MPARAM)LIT_FIRST
588 ,(MPARAM)0
589 )
590 ));
591 } // end of wxListBox::GetSelection
592
593 wxString wxListBox::GetString(
594 int N
595 ) const
596 {
597 LONG lLen = 0;
598 char* zBuf;
599 wxString sResult;
600
601 wxCHECK_MSG( N >= 0 && N < m_nNumItems, "",
602 wxT("invalid index in wxListBox::GetClientData") );
603
604 lLen = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)N, (MPARAM)0));
605 zBuf = new char[lLen + 1];
606 ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT((SHORT)N, (SHORT)lLen), (MPARAM)zBuf);
607 zBuf[lLen] = '\0';
608 sResult = zBuf;
609 delete [] zBuf;
610 return sResult;
611 } // end of wxListBox::GetString
612
613 void wxListBox::DoInsertItems(
614 const wxArrayString& asItems
615 , int nPos
616 )
617 {
618 wxCHECK_RET( nPos >= 0 && nPos <= m_nNumItems,
619 wxT("invalid index in wxListBox::InsertItems") );
620
621 int nItems = asItems.GetCount();
622
623 for (int i = 0; i < nItems; i++)
624 {
625 int nIndex = (int)::WinSendMsg( GetHwnd()
626 ,LM_INSERTITEM
627 ,MPFROMLONG((LONG)(i + nPos))
628 ,(MPARAM)asItems[i].c_str()
629 );
630
631 wxOwnerDrawn* pNewItem = CreateItem(nIndex);
632
633 pNewItem->SetName(asItems[i]);
634 pNewItem->SetFont(GetFont());
635 m_aItems.Insert(pNewItem, nIndex);
636 ::WinSendMsg( GetHwnd()
637 ,LM_SETITEMHANDLE
638 ,(MPARAM)((SHORT)nIndex)
639 ,MPFROMP(pNewItem)
640 );
641 m_nNumItems += nItems;
642 }
643 } // end of wxListBox::DoInsertItems
644
645 void wxListBox::SetString(
646 int N
647 , const wxString& rsString
648 )
649 {
650 wxCHECK_RET( N >= 0 && N < m_nNumItems,
651 wxT("invalid index in wxListBox::SetString") );
652
653 //
654 // Remember the state of the item
655 //
656 bool bWasSelected = IsSelected(N);
657 void* pOldData = NULL;
658 wxClientData* pOldObjData = NULL;
659
660 if (m_clientDataItemsType == wxClientData_Void)
661 pOldData = GetClientData(N);
662 else if (m_clientDataItemsType == wxClientData_Object)
663 pOldObjData = GetClientObject(N);
664
665 //
666 // Delete and recreate it
667 //
668 ::WinSendMsg( GetHwnd()
669 ,LM_DELETEITEM
670 ,(MPARAM)N
671 ,(MPARAM)0
672 );
673
674 int nNewN = N;
675
676 if (N == m_nNumItems - 1)
677 nNewN = -1;
678
679 ::WinSendMsg( GetHwnd()
680 ,LM_INSERTITEM
681 ,(MPARAM)nNewN
682 ,(MPARAM)rsString.c_str()
683 );
684
685 //
686 // Restore the client data
687 //
688 if (pOldData)
689 SetClientData( N
690 ,pOldData
691 );
692 else if (pOldObjData)
693 SetClientObject( N
694 ,pOldObjData
695 );
696
697 //
698 // We may have lost the selection
699 //
700 if (bWasSelected)
701 Select(N);
702
703 #if wxUSE_OWNER_DRAWN
704 if (m_windowStyle & wxLB_OWNERDRAW)
705 //
706 // Update item's text
707 //
708 m_aItems[N]->SetName(rsString);
709 #endif //USE_OWNER_DRAWN
710 } // end of wxListBox::SetString
711
712 int wxListBox::GetCount() const
713 {
714 return m_nNumItems;
715 }
716
717 // ----------------------------------------------------------------------------
718 // helpers
719 // ----------------------------------------------------------------------------
720
721 wxSize wxListBox::DoGetBestSize() const
722 {
723 //
724 // Find the widest string
725 //
726 int nLine;
727 int nListbox = 0;
728 int nCx;
729 int nCy;
730
731 for (int i = 0; i < m_nNumItems; i++)
732 {
733 wxString vStr(GetString(i));
734
735 GetTextExtent( vStr
736 ,&nLine
737 ,NULL
738 );
739 if (nLine > nListbox)
740 nListbox = nLine;
741 }
742
743 //
744 // Give it some reasonable default value if there are no strings in the
745 // list.
746 //
747 if (nListbox == 0)
748 nListbox = 100;
749
750 //
751 // The listbox should be slightly larger than the widest string
752 //
753 wxGetCharSize( GetHWND()
754 ,&nCx
755 ,&nCy
756 ,(wxFont*)&GetFont()
757 );
758 nListbox += 3 * nCx;
759
760 int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7));
761
762 return wxSize( nListbox
763 ,hListbox
764 );
765 } // end of wxListBox::DoGetBestSize
766
767 // ----------------------------------------------------------------------------
768 // callbacks
769 // ----------------------------------------------------------------------------
770
771 bool wxListBox::OS2Command(
772 WXUINT uParam
773 , WXWORD WXUNUSED(wId))
774 {
775 wxEventType eEvtType;
776
777 if (uParam == LN_SELECT)
778 {
779 eEvtType = wxEVT_COMMAND_LISTBOX_SELECTED;
780 }
781 if (uParam == LN_ENTER)
782 {
783 eEvtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
784 }
785 else
786 {
787 //
788 // Some event we're not interested in
789 //
790 return FALSE;
791 }
792 wxCommandEvent vEvent( eEvtType
793 ,m_windowId
794 );
795
796 vEvent.SetEventObject(this);
797
798 wxArrayInt aSelections;
799 int n;
800 int nCount = GetSelections(aSelections);
801
802 if (nCount > 0)
803 {
804 n = aSelections[0];
805 if (HasClientObjectData())
806 vEvent.SetClientObject(GetClientObject(n));
807 else if ( HasClientUntypedData() )
808 vEvent.SetClientData(GetClientData(n));
809 vEvent.SetString(GetString(n));
810 }
811 else
812 {
813 n = -1;
814 }
815 vEvent.m_commandInt = n;
816 return GetEventHandler()->ProcessEvent(vEvent);
817 } // end of wxListBox::OS2Command
818
819 // ----------------------------------------------------------------------------
820 // wxCheckListBox support
821 // ----------------------------------------------------------------------------
822
823 #if wxUSE_OWNER_DRAWN
824
825 //
826 // Drawing
827 // -------
828 //
829 #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
830
831 long wxListBox::OS2OnMeasure(
832 WXMEASUREITEMSTRUCT* pItem
833 )
834 {
835 if (!pItem)
836 pItem = (WXMEASUREITEMSTRUCT*)new OWNERITEM;
837
838 POWNERITEM pMeasureStruct = (POWNERITEM)pItem;
839 wxScreenDC vDc;
840
841 //
842 // Only owner-drawn control should receive this message
843 //
844 wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
845
846 vDc.SetFont(GetFont());
847
848 wxCoord vHeight;
849 wxCoord vWidth;
850
851 GetSize( &vWidth
852 ,NULL
853 );
854
855 pMeasureStruct->rclItem.xRight = (USHORT)vWidth;
856 pMeasureStruct->rclItem.xLeft = 0;
857 pMeasureStruct->rclItem.yTop = 0;
858 pMeasureStruct->rclItem.yBottom = 0;
859
860 vHeight = vDc.GetCharHeight() * 2.5;
861 pMeasureStruct->rclItem.yTop = (USHORT)vHeight;
862
863 return long(MRFROM2SHORT((USHORT)vHeight, (USHORT)vWidth));
864 } // end of wxListBox::OS2OnMeasure
865
866 bool wxListBox::OS2OnDraw (
867 WXDRAWITEMSTRUCT* pItem
868 )
869 {
870 POWNERITEM pDrawStruct = (POWNERITEM)pItem;
871 LONG lItemID = pDrawStruct->idItem;
872 int eAction = 0;
873 int eStatus = 0;
874
875 //
876 // Only owner-drawn control should receive this message
877 //
878 wxCHECK(((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE);
879
880
881 //
882 // The item may be -1 for an empty listbox
883 //
884 if (lItemID == -1L)
885 return FALSE;
886
887 wxListBoxItem* pData = (wxListBoxItem*)PVOIDFROMMR( ::WinSendMsg( GetHwnd()
888 ,LM_QUERYITEMHANDLE
889 ,MPFROMLONG(pDrawStruct->idItem)
890 ,(MPARAM)0
891 )
892 );
893
894 wxCHECK(pData, FALSE );
895
896 wxDC vDc;
897 wxRect vRect( wxPoint( pDrawStruct->rclItem.xLeft
898 ,pDrawStruct->rclItem.yTop
899 )
900 ,wxPoint( pDrawStruct->rclItem.xRight
901 ,pDrawStruct->rclItem.yBottom
902 )
903 );
904
905 vDc.SetHPS(pDrawStruct->hps);
906
907 if (pDrawStruct->fsAttribute == pDrawStruct->fsAttributeOld)
908 {
909 //
910 // Entire Item needs to be redrawn (either it has reappeared from
911 // behind another window or is being displayed for the first time
912 //
913 eAction = wxOwnerDrawn::wxODDrawAll;
914
915 if (pDrawStruct->fsAttribute & MIA_HILITED)
916 {
917 //
918 // If it is currently selected we let the system handle it
919 //
920 eStatus |= wxOwnerDrawn::wxODSelected;
921 }
922 if (pDrawStruct->fsAttribute & MIA_CHECKED)
923 {
924 //
925 // If it is currently checked we draw our own
926 //
927 eStatus |= wxOwnerDrawn::wxODChecked;
928 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_CHECKED;
929 }
930 if (pDrawStruct->fsAttribute & MIA_DISABLED)
931 {
932 //
933 // If it is currently disabled we let the system handle it
934 //
935 eStatus |= wxOwnerDrawn::wxODDisabled;
936 }
937 //
938 // Don't really care about framed (indicationg focus) or NoDismiss
939 //
940 }
941 else
942 {
943 if (pDrawStruct->fsAttribute & MIA_HILITED)
944 {
945 eAction = wxOwnerDrawn::wxODDrawAll;
946 eStatus |= wxOwnerDrawn::wxODSelected;
947 //
948 // Keep the system from trying to highlight with its bogus colors
949 //
950 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_HILITED;
951 }
952 else if (!(pDrawStruct->fsAttribute & MIA_HILITED))
953 {
954 eAction = wxOwnerDrawn::wxODDrawAll;
955 eStatus = 0;
956 //
957 // Keep the system from trying to highlight with its bogus colors
958 //
959 pDrawStruct->fsAttribute = pDrawStruct->fsAttributeOld &= ~MIA_HILITED;
960 }
961 else
962 {
963 //
964 // For now we don't care about anything else
965 // just ignore the entire message!
966 //
967 return TRUE;
968 }
969 }
970 return pData->OnDrawItem( vDc
971 ,vRect
972 ,(wxOwnerDrawn::wxODAction)eAction
973 ,(wxOwnerDrawn::wxODStatus)eStatus
974 );
975 } // end of wxListBox::OS2OnDraw
976
977 #endif // ndef for wxUSE_OWNER_DRAWN
978
979 #endif // ndef for wxUSE_LISTBOX
980