]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/listbox.cpp
Added wxExpr parser/lexer files which had somehow got lost;
[wxWidgets.git] / src / msw / listbox.cpp
index 8c8922b504cff81624ea6e2a5ca6fe99a517848a..d1db5e48b360afc3ffd31e84277716d06e43c1eb 100644 (file)
@@ -42,6 +42,9 @@
   #include  "wx/ownerdrw.h"
 #endif
 
+#include "wx/dynarray.h"
+#include "wx/log.h"
+
 #if !USE_SHARED_LIBRARY
   IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
 #endif
@@ -89,11 +92,11 @@ bool wxListBox::MSWCommand(const WXUINT param, const WXWORD WXUNUSED(id))
   if (param == LBN_SELCHANGE)
   {
     wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
-    int *liste = NULL;
-    int count = GetSelections(&liste) ;
-    if (count && liste)
+    wxArrayInt aSelections;
+    int count = GetSelections(aSelections);
+    if ( count > 0 )
     {
-      event.m_commandInt = liste[0] ;
+      event.m_commandInt = aSelections[0] ;
       event.m_clientData = GetClientData(event.m_commandInt);
       wxString str(GetString(event.m_commandInt));
       if (str != "")
@@ -133,7 +136,6 @@ wxListBox::wxListBox(void)
 {
   m_noItems = 0;
   m_selected = 0;
-  m_selections = NULL;
 }
 
 bool wxListBox::Create(wxWindow *parent, const wxWindowID id,
@@ -147,7 +149,6 @@ bool wxListBox::Create(wxWindow *parent, const wxWindowID id,
   m_noItems = n;
   m_hWnd = 0;
   m_selected = 0;
-  m_selections = NULL;
 
   SetName(name);
   SetValidator(validator);
@@ -184,13 +185,10 @@ bool wxListBox::Create(wxWindow *parent, const wxWindowID id,
       // we don't support LBS_OWNERDRAWVARIABLE yet
       wstyle |= LBS_OWNERDRAWFIXED;
     }
-#else
-  // Change from previous versions of wxWin: JACS Nov. 1995
-  // Not sure whether to have integral, or no integral
-  // style. With the latter we may get partial items showing.
-  // VZ: also it makes life more difficult for owner-drawn controls
-    wstyle |= LBS_NOINTEGRALHEIGHT;
 #endif
+  // Without this style, you get unexpected heights, so e.g. constraint layout
+  // doesn't work properly
+  wstyle |= LBS_NOINTEGRALHEIGHT;
 
   bool want3D;
   WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
@@ -209,6 +207,9 @@ bool wxListBox::Create(wxWindow *parent, const wxWindowID id,
                                 0, 0, 0, 0, 
                                 (HWND)parent->GetHWND(), (HMENU)m_windowId,
                                 wxGetInstance(), NULL);
+
+  m_hWnd = (WXHWND)wx_list;
+
 #if CTL3D
   if (want3D)
   {
@@ -217,12 +218,15 @@ bool wxListBox::Create(wxWindow *parent, const wxWindowID id,
   }
 #endif
 
+  // Subclass again to catch messages
+  SubclassWin((WXHWND)wx_list);
+
   uint ui;
   for (ui = 0; ui < (uint)n; ui++) {
     SendMessage(wx_list, LB_ADDSTRING, 0, (LPARAM)(const char *)choices[ui]);
   }
 
-  #if USE_OWNER_DRAWN
+#if USE_OWNER_DRAWN
     if ( m_windowStyle & wxLB_OWNERDRAW ) {
       for (ui = 0; ui < (uint)n; ui++) {
         // create new item which will process WM_{DRAW|MEASURE}ITEM messages
@@ -232,35 +236,28 @@ bool wxListBox::Create(wxWindow *parent, const wxWindowID id,
         ListBox_SetItemData(wx_list, ui, pNewItem);
       }
     }
-  #endif
+#endif
 
   if ((m_windowStyle & wxLB_MULTIPLE) == 0)
     SendMessage(wx_list, LB_SETCURSEL, 0, 0);
 
-  ShowWindow(wx_list, SW_SHOW);
-
-  m_hWnd = (WXHWND)wx_list;
-
-  // Subclass again for purposes of dialog editing mode
-  SubclassWin((WXHWND)wx_list);
-
   SetFont(* parent->GetFont());
 
   SetSize(x, y, width, height);
 
+  ShowWindow(wx_list, SW_SHOW);
+
   return TRUE;
 }
 
 wxListBox::~wxListBox(void)
 {
-  #if USE_OWNER_DRAWN
+#if USE_OWNER_DRAWN
     uint uiCount = m_aItems.Count();
     while ( uiCount-- != 0 ) {
       delete m_aItems[uiCount];
     }
-  #endif
-
-  DELETEA(m_selections);
+#endif
 }
 
 void wxListBox::SetupColours(void)
@@ -294,14 +291,14 @@ void wxListBox::Append(const wxString& item)
   int index = ListBox_AddString(hwnd, item);
   m_noItems ++;
 
-  #if USE_OWNER_DRAWN
+#if USE_OWNER_DRAWN
     if ( m_windowStyle & wxLB_OWNERDRAW ) {
       wxOwnerDrawn *pNewItem = CreateItem(-1); // dummy argument
       pNewItem->SetName(item);
       m_aItems.Add(pNewItem);
       ListBox_SetItemData(hwnd, index, pNewItem);
     }
-  #endif
+#endif
 
   SetHorizontalExtent(item);
 }
@@ -311,14 +308,14 @@ void wxListBox::Append(const wxString& item, char *Client_data)
   int index = ListBox_AddString(hwnd, item);
   m_noItems ++;
 
-  #if USE_OWNER_DRAWN
+#if USE_OWNER_DRAWN
     if ( m_windowStyle & wxLB_OWNERDRAW ) {
       // client data must be pointer to wxOwnerDrawn, otherwise we would crash
       // in OnMeasure/OnDraw.
       wxFAIL_MSG("Can't use client data with owner-drawn listboxes");
     }
     else
-  #endif
+#endif
       ListBox_SetItemData(hwnd, index, Client_data);
 
   SetHorizontalExtent(item);
@@ -337,7 +334,7 @@ void wxListBox::Set(const int n, const wxString *choices, char** clientData)
   }
   m_noItems = n;
 
-  #if USE_OWNER_DRAWN
+#if USE_OWNER_DRAWN
     if ( m_windowStyle & wxLB_OWNERDRAW ) {
       // first delete old items
       uint ui = m_aItems.Count();
@@ -357,7 +354,7 @@ void wxListBox::Set(const int n, const wxString *choices, char** clientData)
                      "Can't use client data with owner-drawn listboxes");
       }
     }
-  #endif
+#endif
 
   SetHorizontalExtent("");
   ShowWindow(hwnd, SW_SHOW);
@@ -411,63 +408,51 @@ char *wxListBox::GetClientData(const int N) const
 
 void wxListBox::SetClientData(const int N, char *Client_data)
 {
-  (void)SendMessage(hwnd, LB_SETITEMDATA, N, (LONG)Client_data);
-/*
-  if (result == LB_ERR)
-      return -1;
-  else
-      return 0;
- */
+  if ( ListBox_SetItemData(hwnd, N, Client_data) == LB_ERR )
+    wxLogDebug("LB_SETITEMDATA failed");
 }
 
 // Return number of selections and an array of selected integers
-// Use selections field to store data, which will be cleaned up
-// by destructor if necessary.
-int wxListBox::GetSelections(int **list_selections) const
+int wxListBox::GetSelections(wxArrayInt& aSelections) const
 {
-  wxListBox *nonConst = (wxListBox *)this; // const is a white lie!
-  if (nonConst->m_selections)
-    { delete[] nonConst->m_selections; nonConst->m_selections = NULL; };
+  aSelections.Empty();
+
   if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED))
   {
-    int no_sel = (int)SendMessage(hwnd, LB_GETSELCOUNT, 0, 0);
-    if (no_sel == 0)
-      return 0;
-    nonConst->m_selections = new int[no_sel];
-    SendMessage(hwnd, LB_GETSELITEMS, no_sel, (LONG)m_selections);
-    *list_selections = m_selections;
+    int no_sel = ListBox_GetSelCount(hwnd);
+    if (no_sel != 0) {
+      int *selections = new int[no_sel];
+      if ( ListBox_GetSelItems(hwnd, no_sel, selections) == LB_ERR ) {
+        wxFAIL_MSG("This listbox can't have single-selection style!");
+      }
+
+      aSelections.Alloc(no_sel);
+      for ( int n = 0; n < no_sel; n++ )
+        aSelections.Add(selections[n]);
+
+      delete [] selections;
+    }
+
     return no_sel;
   }
-  else
+  else  // single-selection listbox
   {
-    int sel = (int)SendMessage(hwnd, LB_GETCURSEL, 0, 0);
-    if (sel == LB_ERR)
-      return 0;
-    nonConst->m_selections = new int[1];
-    nonConst->m_selections[0] = sel;
-    *list_selections = m_selections;
+    aSelections.Add(ListBox_GetCurSel(hwnd));
+
     return 1;
   }
 }
 
 // Get single selection, for single choice list items
-int wxListBox::GetSelection(void) const
+int wxListBox::GetSelection() const
 {
-  wxListBox *nonConst = (wxListBox *)this; // const is a white lie!
-  if (nonConst->m_selections)
-    { delete[] nonConst->m_selections; nonConst->m_selections = NULL; };
-  if ((m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED))
-    return -1;
-  else
-  {
-    int sel = (int)SendMessage(hwnd, LB_GETCURSEL, 0, 0);
-    if (sel == LB_ERR)
-      return -1;
-    else
-    {
-      return sel;
-    }
-  }
+  wxCHECK_MSG( !(m_windowStyle & wxLB_MULTIPLE) && 
+               !(m_windowStyle & wxLB_EXTENDED), 
+               -1,
+               "GetSelection() can't be used with multiple-selection "
+               "listboxes, use GetSelections() instead." );
+
+  return ListBox_GetCurSel(hwnd);
 }
 
 // Find string for position
@@ -727,7 +712,7 @@ WXHBRUSH wxListBox::OnCtlColor(const WXHDC pDC, const WXHWND pWnd, const WXUINT
 
 long wxListBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
 {
-/*
+#if 0
   switch (nMsg)
   {
         case WM_INITDIALOG:
@@ -746,7 +731,7 @@ long wxListBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
         case WM_MBUTTONDBLCLK:
         case WM_LBUTTONDOWN:
         case WM_LBUTTONUP:
-//        case WM_LBUTTONDBLCLK:
+        case WM_LBUTTONDBLCLK:
         case WM_MOUSEMOVE:
         case WM_DESTROY:
         case WM_COMMAND:
@@ -777,7 +762,7 @@ long wxListBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
                case WM_NCHITTEST:
             return MSWDefWindowProc(nMsg, wParam, lParam );
     }
-*/
+#endif
   return wxControl::MSWWindowProc(nMsg, wParam, lParam);
 }
 
@@ -797,7 +782,7 @@ long wxListBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
 bool wxListBox::MSWOnMeasure(WXMEASUREITEMSTRUCT *item)
 {
   // only owner-drawn control should receive this message
-  wxCHECK_RET( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
+  wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
 
   MEASUREITEMSTRUCT *pStruct = (MEASUREITEMSTRUCT *)item;
 
@@ -815,13 +800,13 @@ bool wxListBox::MSWOnMeasure(WXMEASUREITEMSTRUCT *item)
 bool wxListBox::MSWOnDraw(WXDRAWITEMSTRUCT *item)
 {
   // only owner-drawn control should receive this message
-  wxCHECK_RET( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
+  wxCHECK( ((m_windowStyle & wxLB_OWNERDRAW) == wxLB_OWNERDRAW), FALSE );
 
   DRAWITEMSTRUCT *pStruct = (DRAWITEMSTRUCT *)item;
   wxListBoxItem *pItem = (wxListBoxItem *)SendMessage(hwnd, LB_GETITEMDATA, 
                                                       pStruct->itemID, 0);
 
-  wxCHECK_RET( (int)pItem != LB_ERR, FALSE );
+  wxCHECK( (int)pItem != LB_ERR, FALSE );
 
   wxDC dc;
   dc.SetHDC((WXHDC)pStruct->hDC, FALSE);