git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@13712 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
811 lines
22 KiB
C++
811 lines
22 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: listbox.cpp
|
|
// Purpose: wxListBox
|
|
// Author: David Webster
|
|
// Modified by:
|
|
// Created: 10/09/99
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) David Webster
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#include "wx/window.h"
|
|
#include "wx/os2/private.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/listbox.h"
|
|
#include "wx/settings.h"
|
|
#include "wx/brush.h"
|
|
#include "wx/font.h"
|
|
#include "wx/dc.h"
|
|
#include "wx/utils.h"
|
|
#include "wx/scrolwin.h"
|
|
#endif
|
|
|
|
#define INCL_M
|
|
#include <os2.h>
|
|
|
|
#include "wx/dynarray.h"
|
|
#include "wx/log.h"
|
|
|
|
#if wxUSE_LISTBOX
|
|
|
|
#if wxUSE_OWNER_DRAWN
|
|
#include "wx/ownerdrw.h"
|
|
#endif
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
|
|
|
|
// ============================================================================
|
|
// list box item declaration and implementation
|
|
// ============================================================================
|
|
|
|
#if wxUSE_OWNER_DRAWN
|
|
|
|
class wxListBoxItem : public wxOwnerDrawn
|
|
{
|
|
public:
|
|
wxListBoxItem(const wxString& rsStr = "");
|
|
};
|
|
|
|
wxListBoxItem::wxListBoxItem(
|
|
const wxString& rsStr
|
|
)
|
|
: wxOwnerDrawn( rsStr
|
|
,FALSE
|
|
)
|
|
{
|
|
//
|
|
// No bitmaps/checkmarks
|
|
//
|
|
SetMarginWidth(0);
|
|
} // end of wxListBoxItem::wxListBoxItem
|
|
|
|
wxOwnerDrawn* wxListBox::CreateItem(
|
|
size_t n
|
|
)
|
|
{
|
|
return new wxListBoxItem();
|
|
} // end of wxListBox::CreateItem
|
|
|
|
#endif //USE_OWNER_DRAWN
|
|
|
|
// ============================================================================
|
|
// list box control implementation
|
|
// ============================================================================
|
|
|
|
// Listbox item
|
|
wxListBox::wxListBox()
|
|
{
|
|
m_nNumItems = 0;
|
|
m_nSelected = 0;
|
|
} // end of wxListBox::wxListBox
|
|
|
|
bool wxListBox::Create(
|
|
wxWindow* pParent
|
|
, wxWindowID vId
|
|
, const wxPoint& rPos
|
|
, const wxSize& rSize
|
|
, int n
|
|
, const wxString asChoices[]
|
|
, long lStyle
|
|
#if wxUSE_VALIDATORS
|
|
, const wxValidator& rValidator
|
|
#endif
|
|
, const wxString& rsName
|
|
)
|
|
{
|
|
m_nNumItems = 0;
|
|
m_hWnd = 0;
|
|
m_nSelected = 0;
|
|
|
|
SetName(rsName);
|
|
#if wxUSE_VALIDATORS
|
|
SetValidator(rValidator);
|
|
#endif
|
|
|
|
if (pParent)
|
|
pParent->AddChild(this);
|
|
|
|
wxSystemSettings vSettings;
|
|
|
|
SetBackgroundColour(vSettings.GetSystemColour(wxSYS_COLOUR_WINDOW));
|
|
SetForegroundColour(pParent->GetForegroundColour());
|
|
|
|
m_windowId = (vId == -1) ? (int)NewControlId() : vId;
|
|
|
|
int nX = rPos.x;
|
|
int nY = rPos.y;
|
|
int nWidth = rSize.x;
|
|
int nHeight = rSize.y;
|
|
|
|
m_windowStyle = lStyle;
|
|
|
|
lStyle = WS_VISIBLE;
|
|
|
|
if (m_windowStyle & wxCLIP_SIBLINGS )
|
|
lStyle |= WS_CLIPSIBLINGS;
|
|
if (m_windowStyle & wxLB_MULTIPLE)
|
|
lStyle |= LS_MULTIPLESEL;
|
|
else if (m_windowStyle & wxLB_EXTENDED)
|
|
lStyle |= LS_EXTENDEDSEL;
|
|
if (m_windowStyle & wxLB_HSCROLL)
|
|
lStyle |= LS_HORZSCROLL;
|
|
if (m_windowStyle & wxLB_OWNERDRAW)
|
|
lStyle |= LS_OWNERDRAW;
|
|
|
|
//
|
|
// Without this style, you get unexpected heights, so e.g. constraint layout
|
|
// doesn't work properly
|
|
//
|
|
lStyle |= LS_NOADJUSTPOS;
|
|
|
|
//
|
|
// If the parent is a scrolled window the controls must
|
|
// have this style or they will overlap the scrollbars
|
|
//
|
|
if (pParent)
|
|
if (pParent->IsKindOf(CLASSINFO(wxScrolledWindow)) ||
|
|
pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)))
|
|
lStyle |= WS_CLIPSIBLINGS;
|
|
|
|
m_hWnd = (WXHWND)::WinCreateWindow( GetWinHwnd(pParent) // Parent
|
|
,WC_LISTBOX // Default Listbox class
|
|
,"LISTBOX" // Control's name
|
|
,lStyle // Initial Style
|
|
,0, 0, 0, 0 // Position and size
|
|
,GetWinHwnd(pParent) // Owner
|
|
,HWND_TOP // Z-Order
|
|
,(HMENU)m_windowId // Id
|
|
,NULL // Control Data
|
|
,NULL // Presentation Parameters
|
|
);
|
|
if (m_hWnd == 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Subclass again for purposes of dialog editing mode
|
|
//
|
|
SubclassWin(m_hWnd);
|
|
|
|
LONG lUi;
|
|
|
|
for (lUi = 0; lUi < (LONG)n; lUi++)
|
|
{
|
|
Append(asChoices[lUi]);
|
|
}
|
|
SetFont(pParent->GetFont());
|
|
|
|
//
|
|
// Set standard wxWindows colors for Listbox items and highlighting
|
|
//
|
|
wxColour vColour;
|
|
|
|
vColour.Set(wxString("WHITE"));
|
|
|
|
LONG lColor = (LONG)vColour.GetPixel();
|
|
|
|
::WinSetPresParam( m_hWnd
|
|
,PP_HILITEFOREGROUNDCOLOR
|
|
,sizeof(LONG)
|
|
,(PVOID)&lColor
|
|
);
|
|
vColour.Set(wxString("NAVY"));
|
|
lColor = (LONG)vColour.GetPixel();
|
|
::WinSetPresParam( m_hWnd
|
|
,PP_HILITEBACKGROUNDCOLOR
|
|
,sizeof(LONG)
|
|
,(PVOID)&lColor
|
|
);
|
|
|
|
SetSize( nX
|
|
,nY
|
|
,nWidth
|
|
,nHeight
|
|
);
|
|
return TRUE;
|
|
} // end of wxListBox::Create
|
|
|
|
wxListBox::~wxListBox()
|
|
{
|
|
#if wxUSE_OWNER_DRAWN
|
|
size_t lUiCount = m_aItems.Count();
|
|
|
|
while (lUiCount-- != 0)
|
|
{
|
|
delete m_aItems[lUiCount];
|
|
}
|
|
#endif // wxUSE_OWNER_DRAWN
|
|
} // end of wxListBox::~wxListBox
|
|
|
|
void wxListBox::SetupColours()
|
|
{
|
|
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
|
SetForegroundColour(GetParent()->GetForegroundColour());
|
|
} // end of wxListBox::SetupColours
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// implementation of wxListBoxBase methods
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxListBox::DoSetFirstItem(
|
|
int N
|
|
)
|
|
{
|
|
wxCHECK_RET( N >= 0 && N < m_nNumItems,
|
|
wxT("invalid index in wxListBox::SetFirstItem") );
|
|
|
|
::WinSendMsg(GetHwnd(), LM_SETTOPINDEX, MPFROMLONG(N), (MPARAM)0);
|
|
} // end of wxListBox::DoSetFirstItem
|
|
|
|
void wxListBox::Delete(
|
|
int N
|
|
)
|
|
{
|
|
wxCHECK_RET( N >= 0 && N < m_nNumItems,
|
|
wxT("invalid index in wxListBox::Delete") );
|
|
|
|
#if wxUSE_OWNER_DRAWN
|
|
delete m_aItems[N];
|
|
m_aItems.RemoveAt(N);
|
|
#else // !wxUSE_OWNER_DRAWN
|
|
if (HasClientObjectData())
|
|
{
|
|
delete GetClientObject(N);
|
|
}
|
|
#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
|
|
|
|
::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)N, (MPARAM)0);
|
|
m_nNumItems--;
|
|
} // end of wxListBox::DoSetFirstItem
|
|
|
|
int wxListBox::DoAppend(
|
|
const wxString& rsItem
|
|
)
|
|
{
|
|
int nIndex = 0;
|
|
SHORT nIndexType = 0;
|
|
|
|
if (m_windowStyle & wxLB_SORT)
|
|
nIndexType = LIT_SORTASCENDING;
|
|
else
|
|
nIndexType = LIT_END;
|
|
nIndex = (int)::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)nIndexType, (MPARAM)rsItem.c_str());
|
|
m_nNumItems++;
|
|
|
|
#if wxUSE_OWNER_DRAWN
|
|
if (m_windowStyle & wxLB_OWNERDRAW)
|
|
{
|
|
wxOwnerDrawn* pNewItem = CreateItem(nIndex); // dummy argument
|
|
|
|
pNewItem->SetName(rsItem);
|
|
m_aItems.Add(pNewItem);
|
|
::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)((SHORT)nIndex), MPFROMP(pNewItem));
|
|
pNewItem->SetFont(GetFont());
|
|
}
|
|
#endif
|
|
return nIndex;
|
|
} // end of wxListBox::DoAppend
|
|
|
|
void wxListBox::DoSetItems(
|
|
const wxArrayString& raChoices
|
|
, void** ppClientData
|
|
)
|
|
{
|
|
BOOL bHideAndShow = IsShown();
|
|
int nCount = 0;
|
|
int i;
|
|
SHORT nIndexType = 0;
|
|
|
|
if (bHideAndShow)
|
|
{
|
|
::WinShowWindow(GetHwnd(), FALSE);
|
|
}
|
|
::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
|
|
m_nNumItems = raChoices.GetCount();
|
|
for (i = 0; i < m_nNumItems; i++)
|
|
{
|
|
|
|
if (m_windowStyle & wxLB_SORT)
|
|
nIndexType = LIT_SORTASCENDING;
|
|
else
|
|
nIndexType = LIT_END;
|
|
::WinSendMsg(GetHwnd(), LM_INSERTITEM, (MPARAM)nIndexType, (MPARAM)raChoices[i].c_str());
|
|
|
|
if (ppClientData)
|
|
{
|
|
#if wxUSE_OWNER_DRAWN
|
|
wxASSERT_MSG(ppClientData[i] == NULL,
|
|
wxT("Can't use client data with owner-drawn listboxes"));
|
|
#else // !wxUSE_OWNER_DRAWN
|
|
::WinSendMsg(WinUtil_GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(lCount), MPFROMP(ppClientData[i]));
|
|
#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
|
|
}
|
|
}
|
|
|
|
#if wxUSE_OWNER_DRAWN
|
|
if ( m_windowStyle & wxLB_OWNERDRAW )
|
|
{
|
|
//
|
|
// First delete old items
|
|
//
|
|
size_t lUi = m_aItems.Count();
|
|
|
|
while (lUi-- != 0)
|
|
{
|
|
delete m_aItems[lUi];
|
|
}
|
|
m_aItems.Empty();
|
|
|
|
//
|
|
// Then create new ones
|
|
//
|
|
for (lUi = 0; lUi < (size_t)m_nNumItems; lUi++)
|
|
{
|
|
wxOwnerDrawn* pNewItem = CreateItem(lUi);
|
|
|
|
pNewItem->SetName(raChoices[lUi]);
|
|
m_aItems.Add(pNewItem);
|
|
::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(lUi), MPFROMP(pNewItem));
|
|
}
|
|
}
|
|
#endif // wxUSE_OWNER_DRAWN
|
|
::WinShowWindow(GetHwnd(), TRUE);
|
|
} // end of wxListBox::DoSetItems
|
|
|
|
int wxListBox::FindString(
|
|
const wxString& rsString
|
|
) const
|
|
{
|
|
int nPos;
|
|
LONG lTextLength;
|
|
PSZ zStr;
|
|
|
|
|
|
for (nPos = 0; nPos < m_nNumItems; nPos++)
|
|
{
|
|
lTextLength = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)nPos, (MPARAM)0));
|
|
zStr = new char[lTextLength + 1];
|
|
::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT(nPos, (SHORT)lTextLength), (MPARAM)zStr);
|
|
if (rsString == (char*)zStr)
|
|
{
|
|
delete [] zStr;
|
|
break;
|
|
}
|
|
delete [] zStr;
|
|
}
|
|
return nPos;
|
|
} // end of wxListBox::FindString
|
|
|
|
void wxListBox::Clear()
|
|
{
|
|
#if wxUSE_OWNER_DRAWN
|
|
size_t lUiCount = m_aItems.Count();
|
|
|
|
while (lUiCount-- != 0)
|
|
{
|
|
delete m_aItems[lUiCount];
|
|
}
|
|
|
|
m_aItems.Clear();
|
|
#else // !wxUSE_OWNER_DRAWN
|
|
if (HasClientObjectData())
|
|
{
|
|
for (size_t n = 0; n < (size_t)m_lNumItems; n++)
|
|
{
|
|
delete GetClientObject(n);
|
|
}
|
|
}
|
|
#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
|
|
::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
|
|
|
|
m_nNumItems = 0;
|
|
} // end of wxListBox::Clear
|
|
|
|
void wxListBox::SetSelection(
|
|
int N
|
|
, bool bSelect
|
|
)
|
|
{
|
|
wxCHECK_RET( N >= 0 && N < m_nNumItems,
|
|
wxT("invalid index in wxListBox::SetSelection") );
|
|
::WinSendMsg( GetHwnd()
|
|
,LM_SELECTITEM
|
|
,MPFROMLONG(N)
|
|
,(MPARAM)bSelect
|
|
);
|
|
} // end of wxListBox::SetSelection
|
|
|
|
bool wxListBox::IsSelected(
|
|
int N
|
|
) const
|
|
{
|
|
wxCHECK_MSG( N >= 0 && N < m_nNumItems, FALSE,
|
|
wxT("invalid index in wxListBox::Selected") );
|
|
|
|
LONG lItem;
|
|
|
|
lItem = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)N, (MPARAM)0));
|
|
return (lItem != LIT_NONE);
|
|
} // end of wxListBox::IsSelected
|
|
|
|
wxClientData* wxListBox::DoGetItemClientObject(
|
|
int n
|
|
) const
|
|
{
|
|
return (wxClientData *)DoGetItemClientData(n);
|
|
}
|
|
|
|
void* wxListBox::DoGetItemClientData(
|
|
int n
|
|
) const
|
|
{
|
|
wxCHECK_MSG( n >= 0 && n < m_nNumItems, NULL,
|
|
wxT("invalid index in wxListBox::GetClientData") );
|
|
|
|
return((void *)::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, MPFROMLONG(n), (MPARAM)0));
|
|
} // end of wxListBox::DoGetItemClientData
|
|
|
|
void wxListBox::DoSetItemClientObject(
|
|
int n
|
|
, wxClientData* pClientData
|
|
)
|
|
{
|
|
DoSetItemClientData( n
|
|
,pClientData
|
|
);
|
|
} // end of wxListBox::DoSetItemClientObject
|
|
|
|
void wxListBox::DoSetItemClientData(
|
|
int n
|
|
, void* pClientData
|
|
)
|
|
{
|
|
wxCHECK_RET( n >= 0 && n < m_nNumItems,
|
|
wxT("invalid index in wxListBox::SetClientData") );
|
|
|
|
#if wxUSE_OWNER_DRAWN
|
|
if ( m_windowStyle & wxLB_OWNERDRAW )
|
|
{
|
|
//
|
|
// Client data must be pointer to wxOwnerDrawn, otherwise we would crash
|
|
// in OnMeasure/OnDraw.
|
|
//
|
|
wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
|
|
}
|
|
#endif // wxUSE_OWNER_DRAWN
|
|
|
|
::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, MPFROMLONG(n), MPFROMP(pClientData));
|
|
} // end of wxListBox::DoSetItemClientData
|
|
|
|
bool wxListBox::HasMultipleSelection() const
|
|
{
|
|
return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
|
|
} // end of wxListBox::HasMultipleSelection
|
|
|
|
int wxListBox::GetSelections(
|
|
wxArrayInt& raSelections
|
|
) const
|
|
{
|
|
int nCount = 0;
|
|
LONG lItem;
|
|
|
|
|
|
raSelections.Empty();
|
|
if (HasMultipleSelection())
|
|
{
|
|
lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
|
|
,LM_QUERYSELECTION
|
|
,(MPARAM)LIT_FIRST
|
|
,(MPARAM)0
|
|
)
|
|
);
|
|
if (lItem != LIT_NONE)
|
|
{
|
|
nCount++;
|
|
while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
|
|
,LM_QUERYSELECTION
|
|
,(MPARAM)lItem
|
|
,(MPARAM)0
|
|
)
|
|
)) != LIT_NONE)
|
|
{
|
|
nCount++;
|
|
}
|
|
raSelections.Alloc(nCount);
|
|
lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
|
|
,LM_QUERYSELECTION
|
|
,(MPARAM)LIT_FIRST
|
|
,(MPARAM)0
|
|
)
|
|
);
|
|
|
|
raSelections.Add((int)lItem);
|
|
while ((lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
|
|
,LM_QUERYSELECTION
|
|
,(MPARAM)lItem
|
|
,(MPARAM)0
|
|
)
|
|
)) != LIT_NONE)
|
|
{
|
|
raSelections.Add((int)lItem);
|
|
}
|
|
return nCount;
|
|
}
|
|
return 0;
|
|
}
|
|
else // single-selection listbox
|
|
{
|
|
lItem = LONGFROMMR(::WinSendMsg( GetHwnd()
|
|
,LM_QUERYSELECTION
|
|
,(MPARAM)LIT_FIRST
|
|
,(MPARAM)0
|
|
)
|
|
);
|
|
raSelections.Add((int)lItem);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
} // end of wxListBox::GetSelections
|
|
|
|
int wxListBox::GetSelection() const
|
|
{
|
|
wxCHECK_MSG( !HasMultipleSelection(),
|
|
-1,
|
|
wxT("GetSelection() can't be used with multiple-selection "
|
|
"listboxes, use GetSelections() instead.") );
|
|
|
|
return(LONGFROMMR(::WinSendMsg( GetHwnd()
|
|
,LM_QUERYSELECTION
|
|
,(MPARAM)LIT_FIRST
|
|
,(MPARAM)0
|
|
)
|
|
));
|
|
} // end of wxListBox::GetSelection
|
|
|
|
wxString wxListBox::GetString(
|
|
int N
|
|
) const
|
|
{
|
|
LONG lLen = 0;
|
|
char* zBuf;
|
|
wxString sResult;
|
|
|
|
wxCHECK_MSG( N >= 0 && N < m_nNumItems, "",
|
|
wxT("invalid index in wxListBox::GetClientData") );
|
|
|
|
lLen = LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)N, (MPARAM)0));
|
|
zBuf = new char[lLen + 1];
|
|
::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT((SHORT)N, (SHORT)lLen), (MPARAM)zBuf);
|
|
zBuf[lLen] = '\0';
|
|
sResult = zBuf;
|
|
delete [] zBuf;
|
|
return sResult;
|
|
} // end of wxListBox::GetString
|
|
|
|
void wxListBox::DoInsertItems(
|
|
const wxArrayString& asItems
|
|
, int nPos
|
|
)
|
|
{
|
|
wxCHECK_RET( nPos >= 0 && nPos <= m_nNumItems,
|
|
wxT("invalid index in wxListBox::InsertItems") );
|
|
|
|
int nItems = asItems.GetCount();
|
|
|
|
for (int i = 0; i < nItems; i++)
|
|
::WinSendMsg(GetHwnd(), LM_INSERTITEM, MPFROMLONG((LONG)(i + nPos)), (MPARAM)asItems[i].c_str());
|
|
m_nNumItems += nItems;
|
|
} // end of wxListBox::DoInsertItems
|
|
|
|
void wxListBox::SetString(
|
|
int N
|
|
, const wxString& rsString
|
|
)
|
|
{
|
|
wxCHECK_RET( N >= 0 && N < m_nNumItems,
|
|
wxT("invalid index in wxListBox::SetString") );
|
|
|
|
//
|
|
// Remember the state of the item
|
|
//
|
|
bool bWasSelected = IsSelected(N);
|
|
void* pOldData = NULL;
|
|
wxClientData* pOldObjData = NULL;
|
|
|
|
if (m_clientDataItemsType == wxClientData_Void)
|
|
pOldData = GetClientData(N);
|
|
else if (m_clientDataItemsType == wxClientData_Object)
|
|
pOldObjData = GetClientObject(N);
|
|
|
|
//
|
|
// Delete and recreate it
|
|
//
|
|
::WinSendMsg( GetHwnd()
|
|
,LM_DELETEITEM
|
|
,(MPARAM)N
|
|
,(MPARAM)0
|
|
);
|
|
|
|
int nNewN = N;
|
|
|
|
if (N == m_nNumItems - 1)
|
|
nNewN = -1;
|
|
|
|
::WinSendMsg( GetHwnd()
|
|
,LM_INSERTITEM
|
|
,(MPARAM)nNewN
|
|
,(MPARAM)rsString.c_str()
|
|
);
|
|
|
|
//
|
|
// Restore the client data
|
|
//
|
|
if (pOldData)
|
|
SetClientData( N
|
|
,pOldData
|
|
);
|
|
else if (pOldObjData)
|
|
SetClientObject( N
|
|
,pOldObjData
|
|
);
|
|
|
|
//
|
|
// We may have lost the selection
|
|
//
|
|
if (bWasSelected)
|
|
Select(N);
|
|
|
|
#if wxUSE_OWNER_DRAWN
|
|
if (m_windowStyle & wxLB_OWNERDRAW)
|
|
//
|
|
// Update item's text
|
|
//
|
|
m_aItems[N]->SetName(rsString);
|
|
#endif //USE_OWNER_DRAWN
|
|
} // end of wxListBox::SetString
|
|
|
|
int wxListBox::GetCount() const
|
|
{
|
|
return m_nNumItems;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// helpers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxSize wxListBox::DoGetBestSize() const
|
|
{
|
|
//
|
|
// Find the widest string
|
|
//
|
|
int nLine;
|
|
int nListbox = 0;
|
|
int nCx;
|
|
int nCy;
|
|
|
|
for (int i = 0; i < m_nNumItems; i++)
|
|
{
|
|
wxString vStr(GetString(i));
|
|
|
|
GetTextExtent( vStr
|
|
,&nLine
|
|
,NULL
|
|
);
|
|
if (nLine > nListbox)
|
|
nListbox = nLine;
|
|
}
|
|
|
|
//
|
|
// Give it some reasonable default value if there are no strings in the
|
|
// list.
|
|
//
|
|
if (nListbox == 0)
|
|
nListbox = 100;
|
|
|
|
//
|
|
// The listbox should be slightly larger than the widest string
|
|
//
|
|
wxGetCharSize( GetHWND()
|
|
,&nCx
|
|
,&nCy
|
|
,(wxFont*)&GetFont()
|
|
);
|
|
nListbox += 3 * nCx;
|
|
|
|
int hListbox = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * (wxMax(m_nNumItems, 7));
|
|
|
|
return wxSize( nListbox
|
|
,hListbox
|
|
);
|
|
} // end of wxListBox::DoGetBestSize
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// callbacks
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool wxListBox::OS2Command(
|
|
WXUINT uParam
|
|
, WXWORD WXUNUSED(wId))
|
|
{
|
|
wxEventType eEvtType;
|
|
|
|
if (uParam == LN_SELECT)
|
|
{
|
|
eEvtType = wxEVT_COMMAND_LISTBOX_SELECTED;
|
|
}
|
|
if (uParam == LN_ENTER)
|
|
{
|
|
eEvtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Some event we're not interested in
|
|
//
|
|
return FALSE;
|
|
}
|
|
wxCommandEvent vEvent( eEvtType
|
|
,m_windowId
|
|
);
|
|
|
|
vEvent.SetEventObject(this);
|
|
|
|
wxArrayInt aSelections;
|
|
int n;
|
|
int nCount = GetSelections(aSelections);
|
|
|
|
if (nCount > 0)
|
|
{
|
|
n = aSelections[0];
|
|
if (HasClientObjectData())
|
|
vEvent.SetClientObject(GetClientObject(n));
|
|
else if ( HasClientUntypedData() )
|
|
vEvent.SetClientData(GetClientData(n));
|
|
vEvent.SetString(GetString(n));
|
|
}
|
|
else
|
|
{
|
|
n = -1;
|
|
}
|
|
vEvent.m_commandInt = n;
|
|
return GetEventHandler()->ProcessEvent(vEvent);
|
|
} // end of wxListBox::OS2Command
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxCheckListBox support
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#if wxUSE_OWNER_DRAWN
|
|
|
|
//
|
|
// Drawing
|
|
// -------
|
|
//
|
|
#define OWNER_DRAWN_LISTBOX_EXTRA_SPACE (1)
|
|
|
|
bool wxListBox::OS2OnMeasure(WXMEASUREITEMSTRUCT *item)
|
|
{
|
|
//
|
|
// TODO: Get to this eventually
|
|
//
|
|
return TRUE;
|
|
}
|
|
|
|
bool wxListBox::OS2OnDraw(WXDRAWITEMSTRUCT *item)
|
|
{
|
|
//
|
|
// TODO: Get to this eventually
|
|
//
|
|
return FALSE;
|
|
}
|
|
#endif // ndef for wxUSE_OWNER_DRAWN
|
|
|
|
#endif // ndef for wxUSE_LISTBOX
|
|
|