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