📄 choicece.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
// Name: src/msw/wince/choicece.cpp
// Purpose: wxChoice implementation for smart phones driven by WinCE
// Author: Wlodzimierz ABX Skiba
// Modified by:
// Created: 29.07.2004
// RCS-ID: $Id: choicece.cpp,v 1.5 2005/03/13 15:32:30 ABX Exp $
// 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__) && defined(__WXWINCE__)
#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);
}
wxChoice *wxChoice::GetChoiceForListBox(WXHWND hwndBuddy)
{
wxChoice *choice = (wxChoice *)wxGetWindowUserData((HWND)hwndBuddy);
int i = ms_allChoiceSpins.Index(choice);
if ( i == wxNOT_FOUND )
return NULL;
// sanity check
wxASSERT_MSG( choice->m_hwndBuddy == hwndBuddy,
_T("wxChoice has incorrect buddy HWND!") );
return choice;
}
// ----------------------------------------------------------------------------
// 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 = GetBestSpinnerSize(IsVertical(style)).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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -