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:
@@ -1318,15 +1318,17 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
|
|||||||
src/generic/dirdlgg.cpp
|
src/generic/dirdlgg.cpp
|
||||||
src/generic/fdrepdlg.cpp
|
src/generic/fdrepdlg.cpp
|
||||||
src/generic/fontdlgg.cpp
|
src/generic/fontdlgg.cpp
|
||||||
|
src/msw/wince/choicece.cpp
|
||||||
src/msw/wince/crt.cpp
|
src/msw/wince/crt.cpp
|
||||||
src/msw/wince/filedlgwce.cpp
|
src/msw/wince/filedlgwce.cpp
|
||||||
src/msw/wince/helpwce.cpp
|
src/msw/wince/helpwce.cpp
|
||||||
src/msw/wince/tbarwce.cpp
|
|
||||||
src/msw/wince/menuce.cpp
|
src/msw/wince/menuce.cpp
|
||||||
|
src/msw/wince/tbarwce.cpp
|
||||||
</set>
|
</set>
|
||||||
<set var="WINCE_HDR" hints="files">
|
<set var="WINCE_HDR" hints="files">
|
||||||
wx/generic/fdrepdlg.h
|
wx/generic/fdrepdlg.h
|
||||||
wx/generic/fontdlgg.h
|
wx/generic/fontdlgg.h
|
||||||
|
wx/msw/wince/choicece.h
|
||||||
wx/msw/wince/helpwce.h
|
wx/msw/wince/helpwce.h
|
||||||
wx/msw/wince/libraries.h
|
wx/msw/wince/libraries.h
|
||||||
wx/msw/wince/missing.h
|
wx/msw/wince/missing.h
|
||||||
|
@@ -273,6 +273,7 @@ wxUniv/X11:
|
|||||||
|
|
||||||
wxWinCE:
|
wxWinCE:
|
||||||
|
|
||||||
|
- added native SmartPhone wxChoice implementation using spinners
|
||||||
- added automatized but customizable handling of native SmartPhone menus
|
- added automatized but customizable handling of native SmartPhone menus
|
||||||
- fixed wxRadioBox and wxStaticBox
|
- fixed wxRadioBox and wxStaticBox
|
||||||
|
|
||||||
|
@@ -67,6 +67,8 @@ private:
|
|||||||
|
|
||||||
#if defined(__WXUNIVERSAL__)
|
#if defined(__WXUNIVERSAL__)
|
||||||
#include "wx/univ/choice.h"
|
#include "wx/univ/choice.h"
|
||||||
|
#elif defined(__SMARTPHONE__)
|
||||||
|
#include "wx/msw/wince/choicece.h"
|
||||||
#elif defined(__WXMSW__)
|
#elif defined(__WXMSW__)
|
||||||
#include "wx/msw/choice.h"
|
#include "wx/msw/choice.h"
|
||||||
#elif defined(__WXMOTIF__)
|
#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
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if wxUSE_CHOICE
|
#if wxUSE_CHOICE && !defined(__SMARTPHONE__)
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#include "wx/choice.h"
|
#include "wx/choice.h"
|
||||||
@@ -601,4 +601,4 @@ WXHBRUSH wxChoice::OnCtlColor(WXHDC pDC, WXHWND WXUNUSED(pWnd), WXUINT WXUNUSED(
|
|||||||
return (WXHBRUSH)brush->GetResourceHandle();
|
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
|
wxSize wxControl::GetBestSpinerSize(const bool is_vertical) const
|
||||||
{
|
{
|
||||||
// take size according to layout
|
// take size according to layout
|
||||||
wxSize bestSize(GetSystemMetrics(is_vertical ? SM_CXVSCROLL : SM_CXHSCROLL),
|
wxSize bestSize(
|
||||||
GetSystemMetrics(is_vertical ? SM_CYVSCROLL : SM_CYHSCROLL));
|
#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)
|
// correct size as for undocumented MSW variants cases (WinCE and perhaps others)
|
||||||
if (bestSize.x==0)
|
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__
|
Reference in New Issue
Block a user