]> git.saurik.com Git - wxWidgets.git/blob - src/os2/listbox.cpp
synthesize NM_RCLICK ourselves now that def window proc doesn't do it as we don't...
[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.GetColour(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::DoSetSelection(
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 wxFont vFont = (wxFont)GetFont();
729
730 for (int i = 0; i < m_nNumItems; i++)
731 {
732 wxString vStr(GetString(i));
733
734 GetTextExtent( vStr
735 ,&nLine
736 ,NULL
737 );
738 if (nLine > nListbox)
739 nListbox = nLine;
740 }
741
742 //
743 // Give it some reasonable default value if there are no strings in the
744 // list.
745 //
746 if (nListbox == 0)
747 nListbox = 100;
748
749 //
750 // The listbox should be slightly larger than the widest string
751 //
752 wxGetCharSize( GetHWND()
753 ,&nCx
754 ,&nCy
755 ,&vFont
756 );
757 nListbox += 3 * nCx;
758
759 int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7));
760
761 return wxSize( nListbox
762 ,hListbox
763 );
764 } // end of wxListBox::DoGetBestSize
765
766 // ----------------------------------------------------------------------------
767 // callbacks
768 // ----------------------------------------------------------------------------
769
770 bool wxListBox::OS2Command(
771 WXUINT uParam
772 , WXWORD WXUNUSED(wId))
773 {
774 wxEventType eEvtType;
775
776 if (uParam == LN_SELECT)
777 {
778 eEvtType = wxEVT_COMMAND_LISTBOX_SELECTED;
779 }
780 if (uParam == LN_ENTER)
781 {
782 eEvtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
783 }
784 else
785 {
786 //
787 // Some event we're not interested in
788 //
789 return false;
790 }
791 wxCommandEvent vEvent( eEvtType
792 ,m_windowId
793 );
794
795 vEvent.SetEventObject(this);
796
797 wxArrayInt aSelections;
798 int n;
799 int nCount = GetSelections(aSelections);
800
801 if (nCount > 0)
802 {
803 n = aSelections[0];
804 if (HasClientObjectData())
805 vEvent.SetClientObject(GetClientObject(n));
806 else if ( HasClientUntypedData() )
807 vEvent.SetClientData(GetClientData(n));
808 vEvent.SetString(GetString(n));
809 }
810 else
811 {
812 n = -1;
813 }
814 vEvent.SetInt(n);
815 return GetEventHandler()->ProcessEvent(vEvent);
816 } // end of wxListBox::OS2Command
817
818 // ----------------------------------------------------------------------------
819 // wxCheckListBox support
820 // ----------------------------------------------------------------------------
821
822 #if wxUSE_OWNER_DRAWN
823
824 //
825 // Drawing
826 // -------
827 //
828 #define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
829
830 long wxListBox::OS2OnMeasure(
831 WXMEASUREITEMSTRUCT* pItem
832 )
833 {
834 if (!pItem)
835 pItem = (WXMEASUREITEMSTRUCT*)new OWNERITEM;
836
837 POWNERITEM pMeasureStruct = (POWNERITEM)pItem;
838 wxScreenDC vDc;
839
840 //
841 // Only owner-drawn control should receive this message
842 //
843 wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
844
845 vDc.SetFont(GetFont());
846
847 wxCoord vHeight;
848 wxCoord vWidth;
849
850 GetSize( &vWidth
851 ,NULL
852 );
853
854 pMeasureStruct->rclItem.xRight = (USHORT)vWidth;
855 pMeasureStruct->rclItem.xLeft = 0;
856 pMeasureStruct->rclItem.yTop = 0;
857 pMeasureStruct->rclItem.yBottom = 0;
858
859 vHeight = (wxCoord)(vDc.GetCharHeight() * 2.5);
860 pMeasureStruct->rclItem.yTop = (USHORT)vHeight;
861
862 return long(MRFROM2SHORT((USHORT)vHeight, (USHORT)vWidth));
863 } // end of wxListBox::OS2OnMeasure
864
865 bool wxListBox::OS2OnDraw (
866 WXDRAWITEMSTRUCT* pItem
867 )
868 {
869 POWNERITEM pDrawStruct = (POWNERITEM)pItem;
870 LONG lItemID = pDrawStruct->idItem;
871 int eAction = 0;
872 int eStatus = 0;
873
874 //
875 // Only owner-drawn control should receive this message
876 //
877 wxCHECK(((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), false);
878
879
880 //
881 // The item may be -1 for an empty listbox
882 //
883 if (lItemID == -1L)
884 return false;
885
886 wxListBoxItem* pData = (wxListBoxItem*)PVOIDFROMMR( ::WinSendMsg( GetHwnd()
887 ,LM_QUERYITEMHANDLE
888 ,MPFROMLONG(pDrawStruct->idItem)
889 ,(MPARAM)0
890 )
891 );
892
893 wxCHECK(pData, false );
894
895 wxDC vDc;
896 wxRect vRect( wxPoint( pDrawStruct->rclItem.xLeft
897 ,pDrawStruct->rclItem.yTop
898 )
899 ,wxPoint( pDrawStruct->rclItem.xRight
900 ,pDrawStruct->rclItem.yBottom
901 )
902 );
903
904 vDc.SetHPS(pDrawStruct->hps);
905
906 if (pDrawStruct->fsAttribute == pDrawStruct->fsAttributeOld)
907 {
908 //
909 // Entire Item needs to be redrawn (either it has reappeared from
910 // behind another window or is being displayed for the first time
911 //
912 eAction = wxOwnerDrawn::wxODDrawAll;
913
914 if (pDrawStruct->fsAttribute & MIA_HILITED)
915 {
916 //
917 // If it is currently selected we let the system handle it
918 //
919 eStatus |= wxOwnerDrawn::wxODSelected;
920 }
921 if (pDrawStruct->fsAttribute & MIA_CHECKED)
922 {
923 //
924 // If it is currently checked we draw our own
925 //
926 eStatus |= wxOwnerDrawn::wxODChecked;
927 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_CHECKED;
928 }
929 if (pDrawStruct->fsAttribute & MIA_DISABLED)
930 {
931 //
932 // If it is currently disabled we let the system handle it
933 //
934 eStatus |= wxOwnerDrawn::wxODDisabled;
935 }
936 //
937 // Don't really care about framed (indicationg focus) or NoDismiss
938 //
939 }
940 else
941 {
942 if (pDrawStruct->fsAttribute & MIA_HILITED)
943 {
944 eAction = wxOwnerDrawn::wxODDrawAll;
945 eStatus |= wxOwnerDrawn::wxODSelected;
946 //
947 // Keep the system from trying to highlight with its bogus colors
948 //
949 pDrawStruct->fsAttributeOld = pDrawStruct->fsAttribute &= ~MIA_HILITED;
950 }
951 else if (!(pDrawStruct->fsAttribute & MIA_HILITED))
952 {
953 eAction = wxOwnerDrawn::wxODDrawAll;
954 eStatus = 0;
955 //
956 // Keep the system from trying to highlight with its bogus colors
957 //
958 pDrawStruct->fsAttribute = pDrawStruct->fsAttributeOld &= ~MIA_HILITED;
959 }
960 else
961 {
962 //
963 // For now we don't care about anything else
964 // just ignore the entire message!
965 //
966 return true;
967 }
968 }
969 return pData->OnDrawItem( vDc
970 ,vRect
971 ,(wxOwnerDrawn::wxODAction)eAction
972 ,(wxOwnerDrawn::wxODStatus)eStatus
973 );
974 } // end of wxListBox::OS2OnDraw
975
976 #endif // ndef for wxUSE_OWNER_DRAWN
977
978 #endif // ndef for wxUSE_LISTBOX
979