git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18601 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
413 lines
12 KiB
C++
413 lines
12 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: choice.cpp
|
|
// Purpose: wxChoice
|
|
// Author: David Webster
|
|
// Modified by:
|
|
// Created: 10/13/99
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) David Webster
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/choice.h"
|
|
#include "wx/utils.h"
|
|
#include "wx/log.h"
|
|
#include "wx/settings.h"
|
|
#endif
|
|
|
|
#include "wx/os2/private.h"
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl)
|
|
|
|
bool wxChoice::Create(
|
|
wxWindow* pParent
|
|
, wxWindowID vId
|
|
, const wxPoint& rPos
|
|
, const wxSize& rSize
|
|
, int n
|
|
, const wxString asChoices[]
|
|
, long lStyle
|
|
, const wxValidator& rValidator
|
|
, const wxString& rsName
|
|
)
|
|
{
|
|
long lSstyle;
|
|
|
|
if (!CreateControl( pParent
|
|
,vId
|
|
,rPos
|
|
,rSize
|
|
,lStyle
|
|
,rValidator
|
|
,rsName
|
|
))
|
|
return FALSE;
|
|
lSstyle = CBS_DROPDOWNLIST |
|
|
WS_TABSTOP |
|
|
WS_VISIBLE;
|
|
|
|
if (lStyle & wxCLIP_SIBLINGS )
|
|
lSstyle |= WS_CLIPSIBLINGS;
|
|
|
|
wxASSERT_MSG( !(lStyle & wxCB_DROPDOWN) &&
|
|
!(lStyle & wxCB_READONLY) &&
|
|
!(lStyle & wxCB_SIMPLE),
|
|
wxT("this style flag is ignored by wxChoice, you "
|
|
"probably want to use a wxComboBox") );
|
|
|
|
if (!OS2CreateControl( wxT("COMBOBOX")
|
|
,lSstyle
|
|
))
|
|
return FALSE;
|
|
|
|
//
|
|
// A choice/combobox normally has a white background (or other, depending
|
|
// on global settings) rather than inheriting the parent's background colour.
|
|
//
|
|
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
Append(asChoices[i]);
|
|
}
|
|
wxFont* pTextFont = new wxFont( 10
|
|
,wxMODERN
|
|
,wxNORMAL
|
|
,wxNORMAL
|
|
);
|
|
SetFont(*pTextFont);
|
|
SetSize( rPos.x
|
|
,rPos.y
|
|
,rSize.x
|
|
,rSize.y
|
|
);
|
|
delete pTextFont;
|
|
return TRUE;
|
|
} // end of wxChoice::Create
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// adding/deleting items to/from the list
|
|
// ----------------------------------------------------------------------------
|
|
|
|
int wxChoice::DoAppend(
|
|
const wxString& rsItem
|
|
)
|
|
{
|
|
int nIndex;
|
|
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()
|
|
);
|
|
return nIndex;
|
|
} // end of wxChoice::DoAppend
|
|
|
|
void wxChoice::Delete(
|
|
int n
|
|
)
|
|
{
|
|
wxCHECK_RET( n < GetCount(), wxT("invalid item index in wxChoice::Delete") );
|
|
::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0);
|
|
} // end of wxChoice::Delete
|
|
|
|
void wxChoice::Clear()
|
|
{
|
|
Free();
|
|
::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
|
|
} // end of wxChoice::Clear
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// selection
|
|
// ----------------------------------------------------------------------------
|
|
|
|
int wxChoice::GetSelection() const
|
|
{
|
|
return((int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0)));
|
|
} // end of wxChoice::GetSelection
|
|
|
|
void wxChoice::SetSelection(
|
|
int n
|
|
)
|
|
{
|
|
::WinSendMsg( GetHwnd()
|
|
,LM_SELECTITEM
|
|
,(MPARAM)n
|
|
,(MPARAM)TRUE
|
|
);
|
|
} // end of wxChoice::SetSelection
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// string list functions
|
|
// ----------------------------------------------------------------------------
|
|
|
|
int wxChoice::GetCount() const
|
|
{
|
|
return((int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMCOUNT, (MPARAM)0, (MPARAM)0)));
|
|
} // end of wxChoice::GetCount
|
|
|
|
int wxChoice::FindString(
|
|
const wxString& rsStr
|
|
) const
|
|
{
|
|
int nPos;
|
|
int nTextLength;
|
|
PSZ zStr;
|
|
int nItemCount;
|
|
|
|
nItemCount = (int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMCOUNT, (MPARAM)0, (MPARAM)0));
|
|
for (nPos = 0; nPos < nItemCount; nPos++)
|
|
{
|
|
nTextLength = (int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)nPos, (MPARAM)0));
|
|
zStr = new char[nTextLength + 1];
|
|
::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXT, MPFROM2SHORT((SHORT)nPos, (SHORT)nTextLength), (MPARAM)zStr);
|
|
if (rsStr == (char*)zStr)
|
|
{
|
|
delete [] zStr;
|
|
break;
|
|
}
|
|
delete [] zStr;
|
|
}
|
|
return nPos;
|
|
} // end of wxChoice::FindString
|
|
|
|
void wxChoice::SetString(
|
|
int n
|
|
, const wxString& rsStr
|
|
)
|
|
{
|
|
SHORT nIndexType = 0;
|
|
void* pData;
|
|
|
|
if ( m_clientDataItemsType != wxClientData_None )
|
|
{
|
|
pData = DoGetItemClientData(n);
|
|
}
|
|
else // no client data
|
|
{
|
|
pData = NULL;
|
|
}
|
|
|
|
::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, 0);
|
|
|
|
if (m_windowStyle & wxLB_SORT)
|
|
nIndexType = LIT_SORTASCENDING;
|
|
else
|
|
nIndexType = LIT_END;
|
|
::WinSendMsg( GetHwnd()
|
|
,LM_INSERTITEM
|
|
,(MPARAM)nIndexType
|
|
,(MPARAM)rsStr.c_str()
|
|
);
|
|
|
|
if (pData)
|
|
{
|
|
DoSetItemClientData( n
|
|
,pData
|
|
);
|
|
}
|
|
} // end of wxChoice::SetString
|
|
|
|
wxString wxChoice::GetString(
|
|
int n
|
|
) const
|
|
{
|
|
size_t nLen = 0;
|
|
wxString sStr = "";
|
|
char* zBuf;
|
|
|
|
nLen = (size_t)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)n, (MPARAM)0));
|
|
if (nLen != LIT_ERROR && nLen > 0)
|
|
{
|
|
zBuf = new char[nLen + 1];
|
|
::WinSendMsg( GetHwnd()
|
|
,LM_QUERYITEMTEXT
|
|
,MPFROM2SHORT((SHORT)n, (SHORT)nLen)
|
|
,(MPARAM)zBuf
|
|
);
|
|
sStr = zBuf;
|
|
delete [] zBuf;
|
|
}
|
|
return sStr;
|
|
} // end of wxChoice::GetString
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// client data
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxChoice::DoSetItemClientData(
|
|
int n
|
|
, void* pClientData
|
|
)
|
|
{
|
|
::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)n, MPFROMP(pClientData));
|
|
} // end of wxChoice::DoSetItemClientData
|
|
|
|
void* wxChoice::DoGetItemClientData( int n ) const
|
|
{
|
|
MRESULT rc = 0L;
|
|
|
|
rc = ::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, (MPARAM)n, (MPARAM)0);
|
|
return((void*)rc);
|
|
} // end of wxChoice::DoSetItemClientData
|
|
|
|
void wxChoice::DoSetItemClientObject(
|
|
int n
|
|
, wxClientData* pClientData
|
|
)
|
|
{
|
|
DoSetItemClientData( n
|
|
,pClientData
|
|
);
|
|
} // end of wxChoice::DoSetItemClientObject
|
|
|
|
wxClientData* wxChoice::DoGetItemClientObject(
|
|
int n
|
|
) const
|
|
{
|
|
return (wxClientData *)DoGetItemClientData(n);
|
|
} // end of wxChoice::DoGetItemClientObject
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxOS2 specific helpers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxChoice::DoSetSize(
|
|
int nX
|
|
, int nY
|
|
, int nWidth
|
|
, int nHeight
|
|
, int nSizeFlags
|
|
)
|
|
{
|
|
//
|
|
// Ignore height parameter because height doesn't mean 'initially
|
|
// displayed' height, it refers to the drop-down menu as well. The
|
|
// wxWindows interpretation is different; also, getting the size returns
|
|
// the _displayed_ size (NOT the drop down menu size) so
|
|
// setting-getting-setting size would not work.
|
|
//
|
|
wxControl::DoSetSize( nX
|
|
,nY
|
|
,nWidth
|
|
,-1
|
|
,nSizeFlags
|
|
);
|
|
} // end of wxChoice::DoSetSize
|
|
|
|
wxSize wxChoice::DoGetBestSize() const
|
|
{
|
|
//
|
|
// Find the widest string
|
|
//
|
|
int nLineWidth;
|
|
int nChoiceWidth = 0;
|
|
int nItems = GetCount();
|
|
int nCx;
|
|
int nCy;
|
|
|
|
for (int i = 0; i < nItems; i++)
|
|
{
|
|
wxString sStr(GetString(i));
|
|
|
|
GetTextExtent( sStr
|
|
,&nLineWidth
|
|
,NULL
|
|
);
|
|
if (nLineWidth > nChoiceWidth)
|
|
nChoiceWidth = nLineWidth;
|
|
}
|
|
|
|
//
|
|
// Give it some reasonable default value if there are no strings in the
|
|
// list
|
|
//
|
|
if (nChoiceWidth == 0L)
|
|
nChoiceWidth = 100L;
|
|
|
|
//
|
|
// The combobox should be larger than the widest string
|
|
//
|
|
wxGetCharSize( GetHWND()
|
|
,&nCx
|
|
,&nCy
|
|
,(wxFont*)&GetFont()
|
|
);
|
|
nChoiceWidth += 5 * nCx;
|
|
|
|
//
|
|
// Choice drop-down list depends on number of items (limited to 10)
|
|
//
|
|
size_t nStrings = nItems == 0 ? 10 : wxMin(10, nItems) + 1;
|
|
int nChoiceHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * nStrings;
|
|
|
|
return wxSize( nChoiceWidth
|
|
,nChoiceHeight
|
|
);
|
|
} // end of wxChoice::DoGetBestSize
|
|
|
|
MRESULT wxChoice::OS2WindowProc(
|
|
WXUINT uMsg
|
|
, WXWPARAM wParam
|
|
, WXLPARAM lParam
|
|
)
|
|
{
|
|
return wxWindow::OS2WindowProc( uMsg
|
|
,wParam
|
|
,lParam
|
|
);
|
|
} // end of wxChoice::OS2WindowProc
|
|
|
|
bool wxChoice::OS2Command(
|
|
WXUINT uParam
|
|
, WXWORD WXUNUSED(wId)
|
|
)
|
|
{
|
|
if (uParam != LN_SELECT)
|
|
{
|
|
//
|
|
// "selection changed" is the only event we're after
|
|
//
|
|
return FALSE;
|
|
}
|
|
int n = GetSelection();
|
|
|
|
if (n > -1)
|
|
{
|
|
wxCommandEvent vEvent( wxEVT_COMMAND_CHOICE_SELECTED
|
|
,m_windowId
|
|
);
|
|
|
|
vEvent.SetInt(n);
|
|
vEvent.SetEventObject(this);
|
|
vEvent.SetString((char*)GetStringSelection().c_str());
|
|
if (HasClientObjectData())
|
|
vEvent.SetClientObject(GetClientObject(n));
|
|
else if (HasClientUntypedData())
|
|
vEvent.SetClientData(GetClientData(n));
|
|
ProcessCommand(vEvent);
|
|
}
|
|
return TRUE;
|
|
} // end of wxChoice::OS2Command
|
|
|
|
void wxChoice::Free()
|
|
{
|
|
if (HasClientObjectData())
|
|
{
|
|
size_t nCount = GetCount();
|
|
|
|
for (size_t n = 0; n < nCount; n++)
|
|
{
|
|
delete GetClientObject(n);
|
|
}
|
|
}
|
|
} // end of wxhoice::Free
|