Native SmartPhone wxChoice implementation.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@28865 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
c9ecfbe4cd
commit
1550d5f80d
@ -1318,15 +1318,17 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
|
||||
src/generic/dirdlgg.cpp
|
||||
src/generic/fdrepdlg.cpp
|
||||
src/generic/fontdlgg.cpp
|
||||
src/msw/wince/choicece.cpp
|
||||
src/msw/wince/crt.cpp
|
||||
src/msw/wince/filedlgwce.cpp
|
||||
src/msw/wince/helpwce.cpp
|
||||
src/msw/wince/tbarwce.cpp
|
||||
src/msw/wince/menuce.cpp
|
||||
src/msw/wince/tbarwce.cpp
|
||||
</set>
|
||||
<set var="WINCE_HDR" hints="files">
|
||||
wx/generic/fdrepdlg.h
|
||||
wx/generic/fontdlgg.h
|
||||
wx/msw/wince/choicece.h
|
||||
wx/msw/wince/helpwce.h
|
||||
wx/msw/wince/libraries.h
|
||||
wx/msw/wince/missing.h
|
||||
|
@ -273,6 +273,7 @@ wxUniv/X11:
|
||||
|
||||
wxWinCE:
|
||||
|
||||
- added native SmartPhone wxChoice implementation using spinners
|
||||
- added automatized but customizable handling of native SmartPhone menus
|
||||
- fixed wxRadioBox and wxStaticBox
|
||||
|
||||
|
@ -67,6 +67,8 @@ private:
|
||||
|
||||
#if defined(__WXUNIVERSAL__)
|
||||
#include "wx/univ/choice.h"
|
||||
#elif defined(__SMARTPHONE__)
|
||||
#include "wx/msw/wince/choicece.h"
|
||||
#elif defined(__WXMSW__)
|
||||
#include "wx/msw/choice.h"
|
||||
#elif defined(__WXMOTIF__)
|
||||
|
141
include/wx/msw/wince/choicece.h
Normal file
141
include/wx/msw/wince/choicece.h
Normal file
@ -0,0 +1,141 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/msw/wince/choicece.h
|
||||
// Purpose: wxChoice implementation for Smartphones
|
||||
// Author: Wlodzimierz ABX Skiba
|
||||
// Modified by:
|
||||
// Created: 29.07.2004
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Wlodzimierz Skiba
|
||||
// License: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_CHOICECE_H_BASE_
|
||||
#define _WX_CHOICECE_H_BASE_
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma interface "choicece.h"
|
||||
#endif
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
#if wxUSE_CHOICE
|
||||
|
||||
#include "wx/dynarray.h"
|
||||
|
||||
class WXDLLEXPORT wxChoice;
|
||||
WX_DEFINE_EXPORTED_ARRAY_PTR(wxChoice *, wxArrayChoiceSpins);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Choice item
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxChoice : public wxChoiceBase
|
||||
{
|
||||
public:
|
||||
// ctors
|
||||
wxChoice() { }
|
||||
virtual ~wxChoice();
|
||||
|
||||
wxChoice(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
int n = 0, const wxString choices[] = NULL,
|
||||
long style = 0,
|
||||
const wxValidator& validator = wxDefaultValidator,
|
||||
const wxString& name = wxChoiceNameStr)
|
||||
{
|
||||
Create(parent, id, pos, size, n, choices, style, validator, name);
|
||||
}
|
||||
wxChoice(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
const wxArrayString& choices,
|
||||
long style = 0,
|
||||
const wxValidator& validator = wxDefaultValidator,
|
||||
const wxString& name = wxChoiceNameStr)
|
||||
{
|
||||
Create(parent, id, pos, size, choices, style, validator, name);
|
||||
}
|
||||
|
||||
bool Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
int n = 0, const wxString choices[] = NULL,
|
||||
long style = 0,
|
||||
const wxValidator& validator = wxDefaultValidator,
|
||||
const wxString& name = wxChoiceNameStr);
|
||||
|
||||
bool Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
const wxArrayString& choices,
|
||||
long style = 0,
|
||||
const wxValidator& validator = wxDefaultValidator,
|
||||
const wxString& name = wxChoiceNameStr);
|
||||
|
||||
// implement base class pure virtuals
|
||||
virtual int DoAppend(const wxString& item);
|
||||
virtual int DoInsert(const wxString& item, int pos);
|
||||
virtual void Delete(int n);
|
||||
virtual void Clear() ;
|
||||
|
||||
virtual int GetCount() const;
|
||||
virtual int GetSelection() const;
|
||||
virtual void SetSelection(int n);
|
||||
|
||||
virtual int FindString(const wxString& s) const;
|
||||
virtual wxString GetString(int n) const;
|
||||
virtual void SetString(int n, const wxString& s);
|
||||
|
||||
// get the subclassed window proc of the buddy list of choices
|
||||
WXFARPROC GetBuddyWndProc() const { return m_wndProcBuddy; }
|
||||
|
||||
protected:
|
||||
virtual void DoSetItemClientData( int n, void* clientData );
|
||||
virtual void* DoGetItemClientData( int n ) const;
|
||||
virtual void DoSetItemClientObject( int n, wxClientData* clientData );
|
||||
virtual wxClientData* DoGetItemClientObject( int n ) const;
|
||||
|
||||
// MSW implementation
|
||||
virtual void DoGetPosition(int *x, int *y) const;
|
||||
virtual void DoMoveWindow(int x, int y, int width, int height);
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
virtual void DoGetSize(int *width, int *height) const;
|
||||
|
||||
virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
|
||||
|
||||
// create and initialize the control
|
||||
bool CreateAndInit(wxWindow *parent, wxWindowID id,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
int n, const wxString choices[],
|
||||
long style,
|
||||
const wxValidator& validator,
|
||||
const wxString& name);
|
||||
|
||||
// free all memory we have (used by Clear() and dtor)
|
||||
void Free();
|
||||
|
||||
// the data for the "buddy" list
|
||||
WXHWND m_hwndBuddy;
|
||||
WXFARPROC m_wndProcBuddy;
|
||||
|
||||
// all existing wxChoice - this allows to find the one corresponding to
|
||||
// the given buddy window in GetSpinChoiceCtrl()
|
||||
static wxArrayChoiceSpins ms_allChoiceSpins;
|
||||
|
||||
private:
|
||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxChoice)
|
||||
};
|
||||
|
||||
#endif // wxUSE_CHOICE
|
||||
|
||||
#endif // _WX_CHOICECE_H_BASE_
|
@ -28,7 +28,7 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#if wxUSE_CHOICE
|
||||
#if wxUSE_CHOICE && !defined(__SMARTPHONE__)
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/choice.h"
|
||||
@ -601,4 +601,4 @@ WXHBRUSH wxChoice::OnCtlColor(WXHDC pDC, WXHWND WXUNUSED(pWnd), WXUINT WXUNUSED(
|
||||
return (WXHBRUSH)brush->GetResourceHandle();
|
||||
}
|
||||
|
||||
#endif // wxUSE_CHOICE
|
||||
#endif // wxUSE_CHOICE && !__SMARTPHONE__
|
||||
|
@ -213,8 +213,14 @@ wxSize wxControl::DoGetBestSize() const
|
||||
wxSize wxControl::GetBestSpinerSize(const bool is_vertical) const
|
||||
{
|
||||
// take size according to layout
|
||||
wxSize bestSize(GetSystemMetrics(is_vertical ? SM_CXVSCROLL : SM_CXHSCROLL),
|
||||
GetSystemMetrics(is_vertical ? SM_CYVSCROLL : SM_CYHSCROLL));
|
||||
wxSize bestSize(
|
||||
#ifdef __SMARTPHONE__
|
||||
0,GetCharHeight()
|
||||
#else !__SMARTPHONE__
|
||||
GetSystemMetrics(is_vertical ? SM_CXVSCROLL : SM_CXHSCROLL),
|
||||
GetSystemMetrics(is_vertical ? SM_CYVSCROLL : SM_CYHSCROLL)
|
||||
#endif __SMARTPHONE__/!__SMARTPHONE__
|
||||
);
|
||||
|
||||
// correct size as for undocumented MSW variants cases (WinCE and perhaps others)
|
||||
if (bestSize.x==0)
|
||||
|
550
src/msw/wince/choicece.cpp
Normal file
550
src/msw/wince/choicece.cpp
Normal file
@ -0,0 +1,550 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: src/msw/wince/choicece.cpp
|
||||
// Purpose: wxChoice implementation for Smartphones
|
||||
// Author: Wlodzimierz ABX Skiba
|
||||
// Modified by:
|
||||
// Created: 29.07.2004
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) Wlodzimierz Skiba
|
||||
// License: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// declarations
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma implementation "choicece.h"
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/choice.h"
|
||||
#endif
|
||||
|
||||
#include "wx/spinbutt.h" // for wxSpinnerBestSize
|
||||
|
||||
#include <commctrl.h>
|
||||
#include "wx/msw/missing.h"
|
||||
#include "wx/msw/winundef.h"
|
||||
|
||||
#if wxUSE_CHOICE && defined(__SMARTPHONE__)
|
||||
|
||||
#if wxUSE_EXTENDED_RTTI
|
||||
// TODO
|
||||
#else
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl)
|
||||
#endif
|
||||
|
||||
#define GetBuddyHwnd() (HWND)(m_hwndBuddy)
|
||||
|
||||
#define IsVertical(wxStyle) ( (wxStyle & wxSP_HORIZONTAL) != wxSP_HORIZONTAL )
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// the margin between the up-down control and its buddy (can be arbitrary,
|
||||
// choose what you like - or may be decide during run-time depending on the
|
||||
// font size?)
|
||||
static const int MARGIN_BETWEEN = 0;
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
// ============================================================================
|
||||
|
||||
wxArrayChoiceSpins wxChoice::ms_allChoiceSpins;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wnd proc for the buddy text ctrl
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
LRESULT APIENTRY _EXPORT wxBuddyChoiceWndProc(HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
wxChoice *spin = (wxChoice *)wxGetWindowUserData(hwnd);
|
||||
|
||||
// forward some messages (the key and focus ones only so far) to
|
||||
// the spin ctrl
|
||||
switch ( message )
|
||||
{
|
||||
case WM_SETFOCUS:
|
||||
// if the focus comes from the spin control itself, don't set it
|
||||
// back to it -- we don't want to go into an infinite loop
|
||||
if ( (WXHWND)wParam == spin->GetHWND() )
|
||||
break;
|
||||
//else: fall through
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
case WM_CHAR:
|
||||
case WM_DEADCHAR:
|
||||
case WM_KEYUP:
|
||||
case WM_KEYDOWN:
|
||||
spin->MSWWindowProc(message, wParam, lParam);
|
||||
|
||||
// The control may have been deleted at this point, so check.
|
||||
if ( !::IsWindow(hwnd) || wxGetWindowUserData(hwnd) != spin )
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case WM_GETDLGCODE:
|
||||
// we want to get WXK_RETURN in order to generate the event for it
|
||||
return DLGC_WANTCHARS;
|
||||
}
|
||||
|
||||
return ::CallWindowProc(CASTWNDPROC spin->GetBuddyWndProc(),
|
||||
hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// creation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxChoice::Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
int n, const wxString choices[],
|
||||
long style,
|
||||
const wxValidator& validator,
|
||||
const wxString& name)
|
||||
{
|
||||
return CreateAndInit(parent, id, pos, size, n, choices, style,
|
||||
validator, name);
|
||||
}
|
||||
|
||||
bool wxChoice::CreateAndInit(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
int n, const wxString choices[],
|
||||
long style,
|
||||
const wxValidator& validator,
|
||||
const wxString& name)
|
||||
{
|
||||
if ( !(style & wxSP_VERTICAL) )
|
||||
style |= wxSP_HORIZONTAL;
|
||||
|
||||
if ( (style & wxBORDER_MASK) == wxBORDER_DEFAULT )
|
||||
style |= wxBORDER_SIMPLE;
|
||||
|
||||
style |= wxSP_ARROW_KEYS;
|
||||
|
||||
SetWindowStyle(style);
|
||||
|
||||
WXDWORD exStyle = 0;
|
||||
WXDWORD msStyle = MSWGetStyle(GetWindowStyle(), & exStyle) ;
|
||||
|
||||
wxSize sizeText(size), sizeBtn(size);
|
||||
sizeBtn.x = GetBestSpinerSize(IsVertical(style)).x;
|
||||
|
||||
sizeBtn.x;
|
||||
|
||||
if ( sizeText.x == wxDefaultCoord )
|
||||
{
|
||||
// DEFAULT_ITEM_WIDTH is the default width for the text control
|
||||
sizeText.x = DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN + sizeBtn.x;
|
||||
}
|
||||
|
||||
sizeText.x -= sizeBtn.x + MARGIN_BETWEEN;
|
||||
if ( sizeText.x <= 0 )
|
||||
{
|
||||
wxLogDebug(_T("not enough space for wxSpinCtrl!"));
|
||||
}
|
||||
|
||||
wxPoint posBtn(pos);
|
||||
posBtn.x += sizeText.x + MARGIN_BETWEEN;
|
||||
|
||||
// we must create the list control before the spin button for the purpose
|
||||
// of the dialog navigation: if there is a static text just before the spin
|
||||
// control, activating it by Alt-letter should give focus to the text
|
||||
// control, not the spin and the dialog navigation code will give focus to
|
||||
// the next control (at Windows level), not the one after it
|
||||
|
||||
// create the text window
|
||||
|
||||
m_hwndBuddy = (WXHWND)::CreateWindowEx
|
||||
(
|
||||
exStyle, // sunken border
|
||||
_T("LISTBOX"), // window class
|
||||
NULL, // no window title
|
||||
msStyle, // style (will be shown later)
|
||||
pos.x, pos.y, // position
|
||||
0, 0, // size (will be set later)
|
||||
GetHwndOf(parent), // parent
|
||||
(HMENU)-1, // control id
|
||||
wxGetInstance(), // app instance
|
||||
NULL // unused client data
|
||||
);
|
||||
|
||||
if ( !m_hwndBuddy )
|
||||
{
|
||||
wxLogLastError(wxT("CreateWindow(buddy text window)"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialize wxControl
|
||||
if ( !CreateControl(parent, id, posBtn, sizeBtn, style, validator, name) )
|
||||
return false;
|
||||
|
||||
// now create the real HWND
|
||||
WXDWORD spiner_style = WS_VISIBLE |
|
||||
UDS_ALIGNRIGHT |
|
||||
UDS_ARROWKEYS |
|
||||
UDS_SETBUDDYINT |
|
||||
UDS_EXPANDABLE;
|
||||
|
||||
if ( !IsVertical(style) )
|
||||
spiner_style |= UDS_HORZ;
|
||||
|
||||
if ( style & wxSP_WRAP )
|
||||
spiner_style |= UDS_WRAP;
|
||||
|
||||
if ( !MSWCreateControl(UPDOWN_CLASS, spiner_style, posBtn, sizeBtn, _T(""), 0) )
|
||||
return false;
|
||||
|
||||
// subclass the text ctrl to be able to intercept some events
|
||||
wxSetWindowUserData(GetBuddyHwnd(), this);
|
||||
m_wndProcBuddy = (WXFARPROC)wxSetWindowProc(GetBuddyHwnd(),
|
||||
wxBuddyChoiceWndProc);
|
||||
|
||||
// set up fonts and colours (This is nomally done in MSWCreateControl)
|
||||
InheritAttributes();
|
||||
if (!m_hasFont)
|
||||
SetFont(GetDefaultAttributes().font);
|
||||
|
||||
// set the size of the text window - can do it only now, because we
|
||||
// couldn't call DoGetBestSize() before as font wasn't set
|
||||
if ( sizeText.y <= 0 )
|
||||
{
|
||||
int cx, cy;
|
||||
wxGetCharSize(GetHWND(), &cx, &cy, GetFont());
|
||||
|
||||
sizeText.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
|
||||
}
|
||||
|
||||
SetBestSize(size);
|
||||
|
||||
(void)::ShowWindow(GetBuddyHwnd(), SW_SHOW);
|
||||
|
||||
// associate the list window with the spin button
|
||||
(void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)GetBuddyHwnd(), 0);
|
||||
|
||||
// do it after finishing with m_hwndBuddy creation to avoid generating
|
||||
// initial wxEVT_COMMAND_TEXT_UPDATED message
|
||||
ms_allChoiceSpins.Add(this);
|
||||
|
||||
// initialize the controls contents
|
||||
for ( int i = 0; i < n; i++ )
|
||||
{
|
||||
Append(choices[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxChoice::Create(wxWindow *parent,
|
||||
wxWindowID id,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
const wxArrayString& choices,
|
||||
long style,
|
||||
const wxValidator& validator,
|
||||
const wxString& name)
|
||||
{
|
||||
wxCArrayString chs(choices);
|
||||
return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
|
||||
style, validator, name);
|
||||
}
|
||||
|
||||
WXDWORD wxChoice::MSWGetStyle(long style, WXDWORD *exstyle) const
|
||||
{
|
||||
// we never have an external border
|
||||
WXDWORD msStyle = wxControl::MSWGetStyle
|
||||
(
|
||||
(style & ~wxBORDER_MASK) | wxBORDER_NONE, exstyle
|
||||
);
|
||||
|
||||
msStyle |= WS_VISIBLE;
|
||||
|
||||
// wxChoice-specific styles
|
||||
msStyle |= LBS_NOINTEGRALHEIGHT;
|
||||
if ( style & wxCB_SORT )
|
||||
msStyle |= LBS_SORT;
|
||||
|
||||
return msStyle;
|
||||
}
|
||||
|
||||
wxChoice::~wxChoice()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// adding/deleting items to/from the list
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int wxChoice::DoAppend(const wxString& item)
|
||||
{
|
||||
int n = (int)SendMessage(GetBuddyHwnd(), LB_ADDSTRING, 0, (LPARAM)item.c_str());
|
||||
|
||||
if ( n == LB_ERR )
|
||||
{
|
||||
wxLogLastError(wxT("SendMessage(LB_ADDSTRING)"));
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int wxChoice::DoInsert(const wxString& item, int pos)
|
||||
{
|
||||
wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into choice"));
|
||||
wxCHECK_MSG((pos>=0) && (pos<=GetCount()), -1, wxT("invalid index"));
|
||||
|
||||
int n = (int)SendMessage(GetBuddyHwnd(), LB_INSERTSTRING, pos, (LPARAM)item.c_str());
|
||||
if ( n == LB_ERR )
|
||||
{
|
||||
wxLogLastError(wxT("SendMessage(LB_INSERTSTRING)"));
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void wxChoice::Delete(int n)
|
||||
{
|
||||
wxCHECK_RET( n < GetCount(), wxT("invalid item index in wxChoice::Delete") );
|
||||
|
||||
if ( HasClientObjectData() )
|
||||
{
|
||||
delete GetClientObject(n);
|
||||
}
|
||||
|
||||
SendMessage(GetBuddyHwnd(), LB_DELETESTRING, n, 0);
|
||||
}
|
||||
|
||||
void wxChoice::Clear()
|
||||
{
|
||||
Free();
|
||||
|
||||
SendMessage(GetBuddyHwnd(), LB_RESETCONTENT, 0, 0);
|
||||
}
|
||||
|
||||
void wxChoice::Free()
|
||||
{
|
||||
if ( HasClientObjectData() )
|
||||
{
|
||||
size_t count = GetCount();
|
||||
for ( size_t n = 0; n < count; n++ )
|
||||
{
|
||||
delete GetClientObject(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// selection
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int wxChoice::GetSelection() const
|
||||
{
|
||||
return (int)SendMessage(GetBuddyHwnd(), LB_GETCURSEL, 0, 0);
|
||||
}
|
||||
|
||||
void wxChoice::SetSelection(int n)
|
||||
{
|
||||
SendMessage(GetBuddyHwnd(), LB_SETCURSEL, n, 0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// string list functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int wxChoice::GetCount() const
|
||||
{
|
||||
return (int)SendMessage(GetBuddyHwnd(), LB_GETCOUNT, 0, 0);
|
||||
}
|
||||
|
||||
int wxChoice::FindString(const wxString& s) const
|
||||
{
|
||||
int pos = (int)SendMessage(GetBuddyHwnd(), LB_FINDSTRINGEXACT,
|
||||
(WPARAM)-1, (LPARAM)s.c_str());
|
||||
|
||||
return pos == LB_ERR ? wxNOT_FOUND : pos;
|
||||
}
|
||||
|
||||
void wxChoice::SetString(int n, const wxString& s)
|
||||
{
|
||||
wxCHECK_RET( n >= 0 && n < GetCount(),
|
||||
wxT("invalid item index in wxChoice::SetString") );
|
||||
|
||||
// we have to delete and add back the string as there is no way to change a
|
||||
// string in place
|
||||
|
||||
// we need to preserve the client data
|
||||
void *data;
|
||||
if ( m_clientDataItemsType != wxClientData_None )
|
||||
{
|
||||
data = DoGetItemClientData(n);
|
||||
}
|
||||
else // no client data
|
||||
{
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
::SendMessage(GetBuddyHwnd(), LB_DELETESTRING, n, 0);
|
||||
::SendMessage(GetBuddyHwnd(), LB_INSERTSTRING, n, (LPARAM)s.c_str() );
|
||||
|
||||
if ( data )
|
||||
{
|
||||
DoSetItemClientData(n, data);
|
||||
}
|
||||
//else: it's already NULL by default
|
||||
}
|
||||
|
||||
wxString wxChoice::GetString(int n) const
|
||||
{
|
||||
int len = (int)::SendMessage(GetBuddyHwnd(), LB_GETTEXTLEN, n, 0);
|
||||
|
||||
wxString str;
|
||||
if ( len != LB_ERR && len > 0 )
|
||||
{
|
||||
if ( ::SendMessage
|
||||
(
|
||||
GetBuddyHwnd(),
|
||||
LB_GETTEXT,
|
||||
n,
|
||||
(LPARAM)(wxChar *)wxStringBuffer(str, len)
|
||||
) == LB_ERR )
|
||||
{
|
||||
wxLogLastError(wxT("SendMessage(LB_GETLBTEXT)"));
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// client data
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void wxChoice::DoSetItemClientData( int n, void* clientData )
|
||||
{
|
||||
if ( ::SendMessage(GetHwnd(), LB_SETITEMDATA,
|
||||
n, (LPARAM)clientData) == LB_ERR )
|
||||
{
|
||||
wxLogLastError(wxT("LB_SETITEMDATA"));
|
||||
}
|
||||
}
|
||||
|
||||
void* wxChoice::DoGetItemClientData( int n ) const
|
||||
{
|
||||
LPARAM rc = SendMessage(GetHwnd(), LB_GETITEMDATA, n, 0);
|
||||
if ( rc == LB_ERR )
|
||||
{
|
||||
wxLogLastError(wxT("LB_GETITEMDATA"));
|
||||
|
||||
// unfortunately, there is no way to return an error code to the user
|
||||
rc = (LPARAM) NULL;
|
||||
}
|
||||
|
||||
return (void *)rc;
|
||||
}
|
||||
|
||||
void wxChoice::DoSetItemClientObject( int n, wxClientData* clientData )
|
||||
{
|
||||
DoSetItemClientData(n, clientData);
|
||||
}
|
||||
|
||||
wxClientData* wxChoice::DoGetItemClientObject( int n ) const
|
||||
{
|
||||
return (wxClientData *)DoGetItemClientData(n);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// size calculations
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxSize wxChoice::DoGetBestSize() const
|
||||
{
|
||||
wxSize sizeBtn = GetBestSpinerSize(IsVertical(GetWindowStyle()));
|
||||
sizeBtn.x += DEFAULT_ITEM_WIDTH + MARGIN_BETWEEN;
|
||||
|
||||
int y;
|
||||
wxGetCharSize(GetHWND(), NULL, &y, GetFont());
|
||||
y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(y);
|
||||
|
||||
// JACS: we should always use the height calculated
|
||||
// from above, because otherwise we'll get a spin control
|
||||
// that's too big. So never use the height calculated
|
||||
// from wxSpinButton::DoGetBestSize().
|
||||
|
||||
// if ( sizeBtn.y < y )
|
||||
{
|
||||
// make the text tall enough
|
||||
sizeBtn.y = y;
|
||||
}
|
||||
|
||||
return sizeBtn;
|
||||
}
|
||||
|
||||
void wxChoice::DoMoveWindow(int x, int y, int width, int height)
|
||||
{
|
||||
int widthBtn = GetBestSpinerSize(IsVertical(GetWindowStyle())).x;
|
||||
int widthText = width - widthBtn - MARGIN_BETWEEN;
|
||||
if ( widthText <= 0 )
|
||||
{
|
||||
wxLogDebug(_T("not enough space for wxSpinCtrl!"));
|
||||
}
|
||||
|
||||
if ( !::MoveWindow(GetBuddyHwnd(), x, y, widthText, height, TRUE) )
|
||||
{
|
||||
wxLogLastError(wxT("MoveWindow(buddy)"));
|
||||
}
|
||||
|
||||
x += widthText + MARGIN_BETWEEN;
|
||||
if ( !::MoveWindow(GetHwnd(), x, y, widthBtn, height, TRUE) )
|
||||
{
|
||||
wxLogLastError(wxT("MoveWindow"));
|
||||
}
|
||||
}
|
||||
|
||||
// get total size of the control
|
||||
void wxChoice::DoGetSize(int *x, int *y) const
|
||||
{
|
||||
RECT spinrect, textrect, ctrlrect;
|
||||
GetWindowRect(GetHwnd(), &spinrect);
|
||||
GetWindowRect(GetBuddyHwnd(), &textrect);
|
||||
UnionRect(&ctrlrect, &textrect, &spinrect);
|
||||
|
||||
if ( x )
|
||||
*x = ctrlrect.right - ctrlrect.left;
|
||||
if ( y )
|
||||
*y = ctrlrect.bottom - ctrlrect.top;
|
||||
}
|
||||
|
||||
void wxChoice::DoGetPosition(int *x, int *y) const
|
||||
{
|
||||
// hack: pretend that our HWND is the text control just for a moment
|
||||
WXHWND hWnd = GetHWND();
|
||||
wxConstCast(this, wxChoice)->m_hWnd = m_hwndBuddy;
|
||||
|
||||
wxChoiceBase::DoGetPosition(x, y);
|
||||
|
||||
wxConstCast(this, wxChoice)->m_hWnd = hWnd;
|
||||
}
|
||||
|
||||
#endif // wxUSE_CHOICE && __SMARTPHONE__
|
Loading…
Reference in New Issue
Block a user