]> git.saurik.com Git - wxWidgets.git/blob - src/os2/listbox.cpp
Optimized sizers to not call CalcMin more often than neccessary
[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 wxWidgets 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 long lIndex = 0;
285 LONG lIndexType = 0;
286
287 if (m_windowStyle & wxLB_SORT)
288 lIndexType = LIT_SORTASCENDING;
289 else
290 lIndexType = LIT_END;
291 lIndex = (long)::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)lIndexType, (MPARAM)rsItem.c_str());
292 m_nNumItems++;
293
294 #if wxUSE_OWNER_DRAWN
295 if (m_windowStyle & wxLB_OWNERDRAW)
296 {
297 wxOwnerDrawn* pNewItem = CreateItem(lIndex); // dummy argument
298 wxScreenDC vDc;
299
300
301 pNewItem->SetName(rsItem);
302 m_aItems.Insert(pNewItem, lIndex);
303 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)lIndex, MPFROMP(pNewItem));
304 pNewItem->SetFont(GetFont());
305 }
306 #endif
307 return (int)lIndex;
308 } // end of wxListBox::DoAppend
309
310 void wxListBox::DoSetItems(
311 const wxArrayString& raChoices
312 , void** ppClientData
313 )
314 {
315 BOOL bHideAndShow = IsShown();
316 int i;
317 LONG lIndexType = 0;
318
319 if (bHideAndShow)
320 {
321 ::WinShowWindow(GetHwnd(), FALSE);
322 }
323 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
324 m_nNumItems = raChoices.GetCount();
325 for (i = 0; i < m_nNumItems; i++)
326 {
327
328 if (m_windowStyle & wxLB_SORT)
329 lIndexType = LIT_SORTASCENDING;
330 else
331 lIndexType = LIT_END;
332 ::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)lIndexType, (MPARAM)raChoices[i].c_str());
333
334 if (ppClientData)
335 {
336 #if wxUSE_OWNER_DRAWN
337 wxASSERT_MSG(ppClientData[i] == NULL,
338 wxT("Can't use client data with owner-drawn listboxes"));
339 #else // !wxUSE_OWNER_DRAWN
340 ::WinSendMsg(WinUtil_GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(lCount), MPFROMP(ppClientData[i]));
341 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
342 }
343 }
344
345 #if wxUSE_OWNER_DRAWN
346 if ( m_windowStyle & wxLB_OWNERDRAW )
347 {
348 //
349 // First delete old items
350 //
351 WX_CLEAR_ARRAY(m_aItems);
352
353 //
354 // Then create new ones
355 //
356 for (size_t ui = 0; ui < (size_t)m_nNumItems; ui++)
357 {
358 wxOwnerDrawn* pNewItem = CreateItem(ui);
359
360 pNewItem->SetName(raChoices[ui]);
361 m_aItems.Add(pNewItem);
362 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(ui), MPFROMP(pNewItem));
363 }
364 }
365 #endif // wxUSE_OWNER_DRAWN
366 ::WinShowWindow(GetHwnd(), TRUE);
367 } // end of wxListBox::DoSetItems
368
369 int wxListBox::FindString(
370 const wxString& rsString
371 ) const
372 {
373 int nPos;
374 LONG lTextLength;
375 PSZ zStr;
376
377
378 for (nPos = 0; nPos < m_nNumItems; nPos++)
379 {
380 lTextLength = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)nPos, (MPARAM)0));
381 zStr = new char[lTextLength + 1];
382 ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT(nPos, (SHORT)lTextLength), (MPARAM)zStr);
383 if (rsString == (char*)zStr)
384 {
385 delete [] zStr;
386 break;
387 }
388 delete [] zStr;
389 }
390 return nPos;
391 } // end of wxListBox::FindString
392
393 void wxListBox::Clear()
394 {
395 #if wxUSE_OWNER_DRAWN
396 size_t lUiCount = m_aItems.Count();
397
398 while (lUiCount-- != 0)
399 {
400 delete m_aItems[lUiCount];
401 }
402
403 m_aItems.Clear();
404 #else // !wxUSE_OWNER_DRAWN
405 if (HasClientObjectData())
406 {
407 for (size_t n = 0; n < (size_t)m_lNumItems; n++)
408 {
409 delete GetClientObject(n);
410 }
411 }
412 #endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
413 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
414
415 m_nNumItems = 0;
416 } // end of wxListBox::Clear
417
418 void wxListBox::SetSelection(
419 int N
420 , bool bSelect
421 )
422 {
423 wxCHECK_RET( N >= 0 && N < m_nNumItems,
424 wxT("invalid index in wxListBox::SetSelection") );
425 ::WinSendMsg( GetHwnd()
426 ,LM_SELECTITEM
427 ,MPFROMLONG(N)
428 ,(MPARAM)bSelect
429 );
430 if(m_windowStyle & wxLB_OWNERDRAW)
431 Refresh();
432 } // end of wxListBox::SetSelection
433
434 bool wxListBox::IsSelected(
435 int N
436 ) const
437 {
438 wxCHECK_MSG( N >= 0 && N < m_nNumItems, FALSE,
439 wxT("invalid index in wxListBox::Selected") );
440
441 LONG lItem;
442
443 if (GetWindowStyleFlag() & wxLB_EXTENDED)
444 {
445 if (N == 0)
446 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
447 else
448 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)(N - 1), (MPARAM)0));
449 }
450 else
451 {
452 lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0));
453 }
454 return (lItem == (LONG)N && lItem != LIT_NONE);
455 } // end of wxListBox::IsSelected
456
457 wxClientData* wxListBox::DoGetItemClientObject(
458 int n
459 ) const
460 {
461 return (wxClientData *)DoGetItemClientData(n);
462 }
463
464 void* wxListBox::DoGetItemClientData(
465 int n
466 ) const
467 {
468 wxCHECK_MSG( n >= 0 && n < m_nNumItems, NULL,
469 wxT("invalid index in wxListBox::GetClientData") );
470
471 return((void *)::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, MPFROMLONG(n), (MPARAM)0));
472 } // end of wxListBox::DoGetItemClientData
473
474 void wxListBox::DoSetItemClientObject(
475 int n
476 , wxClientData* pClientData
477 )
478 {
479 DoSetItemClientData( n
480 ,pClientData
481 );
482 } // end of wxListBox::DoSetItemClientObject
483
484 void wxListBox::DoSetItemClientData(
485 int n
486 , void* pClientData
487 )
488 {
489 wxCHECK_RET( n >= 0 && n < m_nNumItems,
490 wxT("invalid index in wxListBox::SetClientData") );
491
492 #if wxUSE_OWNER_DRAWN
493 if ( m_windowStyle & wxLB_OWNERDRAW )
494 {
495 //
496 // Client data must be pointer to wxOwnerDrawn, otherwise we would crash
497 // in OnMeasure/OnDraw.
498 //
499 wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
500 }
501 #endif // wxUSE_OWNER_DRAWN
502
503 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(n), MPFROMP(pClientData));
504 } // end of wxListBox::DoSetItemClientData
505
506 bool wxListBox::HasMultipleSelection() const
507 {
508 return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
509 } // end of wxListBox::HasMultipleSelection
510
511 int wxListBox::GetSelections(
512 wxArrayInt& raSelections
513 ) const
514 {
515 int nCount = 0;
516 LONG lItem;
517
518
519 raSelections.Empty();
520 if (HasMultipleSelection())
521 {
522 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
523 ,LM_QUERYSELECTION
524 ,(MPARAM)LIT_FIRST
525 ,(MPARAM)0
526 )
527 );
528 if (lItem != LIT_NONE)
529 {
530 nCount++;
531 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
532 ,LM_QUERYSELECTION
533 ,(MPARAM)lItem
534 ,(MPARAM)0
535 )
536 )) != LIT_NONE)
537 {
538 nCount++;
539 }
540 raSelections.Alloc(nCount);
541 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
542 ,LM_QUERYSELECTION
543 ,(MPARAM)LIT_FIRST
544 ,(MPARAM)0
545 )
546 );
547
548 raSelections.Add((int)lItem);
549 while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
550 ,LM_QUERYSELECTION
551 ,(MPARAM)lItem
552 ,(MPARAM)0
553 )
554 )) != LIT_NONE)
555 {
556 raSelections.Add((int)lItem);
557 }
558 return nCount;
559 }
560 return 0;
561 }
562 else // single-selection listbox
563 {
564 lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
565 ,LM_QUERYSELECTION
566 ,(MPARAM)LIT_FIRST
567 ,(MPARAM)0
568 )
569 );
570 raSelections.Add((int)lItem);
571 return 1;
572 }
573 return 0;
574 } // end of wxListBox::GetSelections
575
576 int wxListBox::GetSelection() const
577 {
578 wxCHECK_MSG( !HasMultipleSelection(),
579 -1,
580 wxT("GetSelection() can't be used with multiple-selection "
581 "listboxes, use GetSelections() instead.") );
582
583 return(LONGFROMMR(::WinSendMsg( GetHwnd()
584 ,LM_QUERYSELECTION
585 ,(MPARAM)LIT_FIRST
586 ,(MPARAM)0
587 )
588 ));
589 } // end of wxListBox::GetSelection
590
591 wxString wxListBox::GetString(
592 int N
593 ) const
594 {
595 LONG lLen = 0;
596 char* zBuf;
597 wxString sResult;
598
599 wxCHECK_MSG( N >= 0 && N < m_nNumItems, "",
600 wxT("invalid index in wxListBox::GetClientData") );
601
602 lLen = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)N, (MPARAM)0));
603 zBuf = new char[lLen + 1];
604 ::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT((SHORT)N, (SHORT)lLen), (MPARAM)zBuf);
605 zBuf[lLen] = '\0';
606 sResult = zBuf;
607 delete [] zBuf;
608 return sResult;
609 } // end of wxListBox::GetString
610
611 void wxListBox::DoInsertItems(
612 const wxArrayString& asItems
613 , int nPos
614 )
615 {
616 wxCHECK_RET( nPos >= 0 && nPos <= m_nNumItems,
617 wxT("invalid index in wxListBox::InsertItems") );
618
619 int nItems = asItems.GetCount();
620
621 for (int i = 0; i < nItems; i++)
622 {
623 int nIndex = (int)::WinSendMsg( GetHwnd()
624 ,LM_INSERTITEM
625 ,MPFROMLONG((LONG)(i + nPos))
626 ,(MPARAM)asItems[i].c_str()
627 );
628
629 wxOwnerDrawn* pNewItem = CreateItem(nIndex);
630
631 pNewItem->SetName(asItems[i]);
632 pNewItem->SetFont(GetFont());
633 m_aItems.Insert(pNewItem, nIndex);
634 ::WinSendMsg( GetHwnd()
635 ,LM_SETITEMHANDLE
636 ,(MPARAM)((LONG)nIndex)
637 ,MPFROMP(pNewItem)
638 );
639 m_nNumItems += nItems;
640 }
641 } // end of wxListBox::DoInsertItems
642
643 void wxListBox::SetString(
644 int N
645 , const wxString& rsString
646 )
647 {
648 wxCHECK_RET( N >= 0 && N < m_nNumItems,
649 wxT("invalid index in wxListBox::SetString") );
650
651 //
652 // Remember the state of the item
653 //
654 bool bWasSelected = IsSelected(N);
655 void* pOldData = NULL;
656 wxClientData* pOldObjData = NULL;
657
658 if (m_clientDataItemsType == wxClientData_Void)
659 pOldData = GetClientData(N);
660 else if (m_clientDataItemsType == wxClientData_Object)
661 pOldObjData = GetClientObject(N);
662
663 //
664 // Delete and recreate it
665 //
666 ::WinSendMsg( GetHwnd()
667 ,LM_DELETEITEM
668 ,(MPARAM)N
669 ,(MPARAM)0
670 );
671
672 int nNewN = N;
673
674 if (N == m_nNumItems - 1)
675 nNewN = -1;
676
677 ::WinSendMsg( GetHwnd()
678 ,LM_INSERTITEM
679 ,(MPARAM)nNewN
680 ,(MPARAM)rsString.c_str()
681 );
682
683 //
684 // Restore the client data
685 //
686 if (pOldData)
687 SetClientData( N
688 ,pOldData
689 );
690 else if (pOldObjData)
691 SetClientObject( N
692 ,pOldObjData
693 );
694
695 //
696 // We may have lost the selection
697 //
698 if (bWasSelected)
699 Select(N);
700
701 #if wxUSE_OWNER_DRAWN
702 if (m_windowStyle & wxLB_OWNERDRAW)
703 //
704 // Update item's text
705 //
706 m_aItems[N]->SetName(rsString);
707 #endif //USE_OWNER_DRAWN
708 } // end of wxListBox::SetString
709
710 int wxListBox::GetCount() const
711 {
712 return m_nNumItems;
713 }
714
715 // ----------------------------------------------------------------------------
716 // helpers
717 // ----------------------------------------------------------------------------
718
719 wxSize wxListBox::DoGetBestSize() const
720 {
721 //
722 // Find the widest string
723 //
724 int nLine;
725 int nListbox = 0;
726 int nCx;
727 int nCy;
728
729 for (int i = 0; i < m_nNumItems; i++)
730 {
731 wxString vStr(GetString(i));
732
733 GetTextExtent( vStr
734 ,&nLine
735 ,NULL
736 );
737 if (nLine > nListbox)
738 nListbox = nLine;
739 }
740
741 //
742 // Give it some reasonable default value if there are no strings in the
743 // list.
744 //
745 if (nListbox == 0)
746 nListbox = 100;
747
748 //
749 // The listbox should be slightly larger than the widest string
750 //
751 wxGetCharSize( GetHWND()
752 ,&nCx
753 ,&nCy
754 ,(wxFont*)&GetFont()
755 );
756 nListbox += 3 * nCx;
757
758 int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7));
759
760 return wxSize( nListbox
761 ,hListbox
762 );
763 } // end of wxListBox::DoGetBestSize
764
765 // ----------------------------------------------------------------------------
766 // callbacks
767 // ----------------------------------------------------------------------------
768
769 bool wxListBox::OS2Command(
770 WXUINT uParam
771 , WXWORD WXUNUSED(wId))
772 {
773 wxEventType eEvtType;
774
775 if (uParam == LN_SELECT)
776 {
777 eEvtType = wxEVT_COMMAND_LISTBOX_SELECTED;
778 }
779 if (uParam == LN_ENTER)
780 {
781 eEvtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
782 }
783 else
784 {
785 //
786 // Some event we're not interested in
787 //
788 return FALSE;
789 }
790 wxCommandEvent vEvent( eEvtType
791 ,m_windowId
792 );
793
794 vEvent.SetEventObject(this);
795
796 wxArrayInt aSelections;
797 int n;
798 int nCount = GetSelections(aSelections);
799
800 if (nCount > 0)
801 {
802 n = aSelections[0];
803 if (HasClientObjectData())
804 vEvent.SetClientObject(GetClientObject(n));
805 else if ( HasClientUntypedData() )
806 vEvent.SetClientData(GetClientData(n));
807 vEvent.SetString(GetString(n));
808 }
809 else
810 {
811 n = -1;
812 }
813 vEvent.m_commandInt = n;
814 return GetEventHandler()->ProcessEvent(vEvent);
815 } // end of wxListBox::OS2Command
816
817 // ----------------------------------------------------------------------------
818 // wxCheckListBox support
819 // ----------------------------------------------------------------------------
820
821 #if wxUSE_OWNER_DRAWN
822
823 //
824 // Drawing
825 // -------
826 //
827 #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
828
829 long wxListBox::OS2OnMeasure(
830 WXMEASUREITEMSTRUCT* pItem
831 )
832 {
833 if (!pItem)
834 pItem = (WXMEASUREITEMSTRUCT*)new OWNERITEM;
835
836 POWNERITEM pMeasureStruct = (POWNERITEM)pItem;
837 wxScreenDC vDc;
838
839 //
840 // Only owner-drawn control should receive this message
841 //
842 wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
843
844 vDc.SetFont(GetFont());
845
846 wxCoord vHeight;
847 wxCoord vWidth;
848
849 GetSize( &vWidth
850 ,NULL
851 );
852
853 pMeasureStruct->rclItem.xRight = (USHORT)vWidth;
854 pMeasureStruct->rclItem.xLeft = 0;
855 pMeasureStruct->rclItem.yTop = 0;
856 pMeasureStruct->rclItem.yBottom = 0;
857
858 vHeight = (wxCoord)(vDc.GetCharHeight() * 2.5);
859 pMeasureStruct->rclItem.yTop = (USHORT)vHeight;
860
861 return long(MRFROM2SHORT((USHORT)vHeight, (USHORT)vWidth));
862 } // end of wxListBox::OS2OnMeasure
863
864 bool wxListBox::OS2OnDraw (
865 WXDRAWITEMSTRUCT* pItem
866 )
867 {
868 POWNERITEM pDrawStruct = (POWNERITEM)pItem;
869 LONG lItemID = pDrawStruct->idItem;
870 int eAction = 0;
871 int eStatus = 0;
872
873 //
874 // Only owner-drawn control should receive this message
875 //
876 wxCHECK(((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE);
877
878
879 //
880 // The item may be -1 for an empty listbox
881 //
882 if (lItemID == -1L)
883 return FALSE;
884
885 wxListBoxItem* pData = (wxListBoxItem*)PVOIDFROMMR( ::WinSendMsg( GetHwnd()
886 ,LM_QUERYITEMHANDLE
887 ,MPFROMLONG(pDrawStruct->idItem)
888 ,(MPARAM)0
889 )
890 );
891
892 wxCHECK(pData, FALSE );
893
894 wxDC vDc;
895 wxRect vRect( wxPoint( pDrawStruct->rclItem.xLeft
896 ,pDrawStruct->rclItem.yTop
897 )
898 ,wxPoint( pDrawStruct->rclItem.xRight
899 ,pDrawStruct->rclItem.yBottom
900 )
901 );
902
903 vDc.SetHPS(pDrawStruct->hps);
904
905 if (pDrawStruct->fsAttribute == pDrawStruct->fsAttributeOld)
906 {
907 //
908 // Entire Item needs to be redrawn (either it has reappeared from
909 // behind another window or is being displayed for the first time
910 //
911 eAction = wxOwnerDrawn::wxODDrawAll;
912
913 if (pDrawStruct->fsAttribute & MIA_HILITED)
914 {
915 //
916 // If it is currently selected we let the system handle it
917 //
918 eStatus |= wxOwnerDrawn::wxODSelected;
919 }
920 if (pDrawStruct->fsAttribute & MIA_CHECKED)
921 {
922 //
923 // If it is currently checked we draw our own
924 //
925 eStatus |= wxOwnerDrawn::wxODChecked;
926 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_CHECKED;
927 }
928 if (pDrawStruct->fsAttribute & MIA_DISABLED)
929 {
930 //
931 // If it is currently disabled we let the system handle it
932 //
933 eStatus |= wxOwnerDrawn::wxODDisabled;
934 }
935 //
936 // Don't really care about framed (indicationg focus) or NoDismiss
937 //
938 }
939 else
940 {
941 if (pDrawStruct->fsAttribute & MIA_HILITED)
942 {
943 eAction = wxOwnerDrawn::wxODDrawAll;
944 eStatus |= wxOwnerDrawn::wxODSelected;
945 //
946 // Keep the system from trying to highlight with its bogus colors
947 //
948 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_HILITED;
949 }
950 else if (!(pDrawStruct->fsAttribute & MIA_HILITED))
951 {
952 eAction = wxOwnerDrawn::wxODDrawAll;
953 eStatus = 0;
954 //
955 // Keep the system from trying to highlight with its bogus colors
956 //
957 pDrawStruct->fsAttribute = pDrawStruct->fsAttributeOld &= ~MIA_HILITED;
958 }
959 else
960 {
961 //
962 // For now we don't care about anything else
963 // just ignore the entire message!
964 //
965 return TRUE;
966 }
967 }
968 return pData->OnDrawItem( vDc
969 ,vRect
970 ,(wxOwnerDrawn::wxODAction)eAction
971 ,(wxOwnerDrawn::wxODStatus)eStatus
972 );
973 } // end of wxListBox::OS2OnDraw
974
975 #endif // ndef for wxUSE_OWNER_DRAWN
976
977 #endif // ndef for wxUSE_LISTBOX
978