Extended ProcessTextCommand so processes SETFOCUS/KILLFOCUS; checked for valid
HWND in wxBuddyTextWndProc so if the event handler kills the HWND, it doesn't crash; added support for disabling 3D effect in buddy window. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9069 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -53,6 +53,7 @@
|
|||||||
IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
|
IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(wxSpinCtrl, wxSpinButton)
|
BEGIN_EVENT_TABLE(wxSpinCtrl, wxSpinButton)
|
||||||
|
EVT_CHAR(wxSpinCtrl::OnChar)
|
||||||
EVT_SPIN(-1, wxSpinCtrl::OnSpinChange)
|
EVT_SPIN(-1, wxSpinCtrl::OnSpinChange)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
@@ -92,9 +93,12 @@ LRESULT APIENTRY _EXPORT wxBuddyTextWndProc(HWND hwnd,
|
|||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
spin->MSWWindowProc(message, wParam, lParam);
|
spin->MSWWindowProc(message, wParam, lParam);
|
||||||
|
|
||||||
|
// The control may have been deleted at this point, so check.
|
||||||
|
if (!(::IsWindow(hwnd) && ((wxSpinCtrl *)::GetWindowLong(hwnd, GWL_USERDATA)) == spin))
|
||||||
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ::CallWindowProc(CASTWNDPROC spin->GetBuddyWndProc(),
|
return ::CallWindowProc(CASTWNDPROC spin->GetBuddyWndProc(),
|
||||||
hwnd, message, wParam, lParam);
|
hwnd, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
@@ -120,20 +124,71 @@ wxSpinCtrl *wxSpinCtrl::GetSpinForTextCtrl(WXHWND hwndBuddy)
|
|||||||
// process a WM_COMMAND generated by the buddy text control
|
// process a WM_COMMAND generated by the buddy text control
|
||||||
bool wxSpinCtrl::ProcessTextCommand(WXWORD cmd, WXWORD WXUNUSED(id))
|
bool wxSpinCtrl::ProcessTextCommand(WXWORD cmd, WXWORD WXUNUSED(id))
|
||||||
{
|
{
|
||||||
if ( cmd == EN_CHANGE )
|
switch (cmd)
|
||||||
{
|
{
|
||||||
wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
|
case EN_CHANGE:
|
||||||
event.SetEventObject(this);
|
{
|
||||||
event.SetInt(GetValue());
|
wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
|
||||||
GetEventHandler()->ProcessEvent(event);
|
event.SetEventObject(this);
|
||||||
|
wxString val = wxGetWindowText(m_hwndBuddy);
|
||||||
return TRUE;
|
event.SetString(val);
|
||||||
|
event.SetInt(GetValue());
|
||||||
|
return GetEventHandler()->ProcessEvent(event);
|
||||||
|
}
|
||||||
|
case EN_SETFOCUS:
|
||||||
|
case EN_KILLFOCUS:
|
||||||
|
{
|
||||||
|
wxFocusEvent event(cmd == EN_KILLFOCUS ? wxEVT_KILL_FOCUS
|
||||||
|
: wxEVT_SET_FOCUS,
|
||||||
|
m_windowId);
|
||||||
|
event.SetEventObject( this );
|
||||||
|
return GetEventHandler()->ProcessEvent(event);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not processed
|
// not processed
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxSpinCtrl::OnChar(wxKeyEvent& event)
|
||||||
|
{
|
||||||
|
switch ( event.KeyCode() )
|
||||||
|
{
|
||||||
|
case WXK_RETURN:
|
||||||
|
{
|
||||||
|
wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
|
||||||
|
InitCommandEvent(event);
|
||||||
|
wxString val = wxGetWindowText(m_hwndBuddy);
|
||||||
|
event.SetString(val);
|
||||||
|
event.SetInt(GetValue());
|
||||||
|
if ( GetEventHandler()->ProcessEvent(event) )
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WXK_TAB:
|
||||||
|
// always produce navigation event - even if we process TAB
|
||||||
|
// ourselves the fact that we got here means that the user code
|
||||||
|
// decided to skip processing of this TAB - probably to let it
|
||||||
|
// do its default job.
|
||||||
|
{
|
||||||
|
wxNavigationKeyEvent eventNav;
|
||||||
|
eventNav.SetDirection(!event.ShiftDown());
|
||||||
|
eventNav.SetWindowChange(event.ControlDown());
|
||||||
|
eventNav.SetEventObject(this);
|
||||||
|
|
||||||
|
if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no, we didn't process it
|
||||||
|
event.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// construction
|
// construction
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -181,13 +236,22 @@ bool wxSpinCtrl::Create(wxWindow *parent,
|
|||||||
SetRange(min, max);
|
SetRange(min, max);
|
||||||
SetValue(initial);
|
SetValue(initial);
|
||||||
|
|
||||||
|
bool want3D;
|
||||||
|
WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D);
|
||||||
|
int msStyle = WS_CHILD;
|
||||||
|
|
||||||
|
// Even with extended styles, need to combine with WS_BORDER for them to
|
||||||
|
// look right.
|
||||||
|
if ( want3D || wxStyleHasBorder(style) )
|
||||||
|
msStyle |= WS_BORDER;
|
||||||
|
|
||||||
// create the text window
|
// create the text window
|
||||||
m_hwndBuddy = (WXHWND)::CreateWindowEx
|
m_hwndBuddy = (WXHWND)::CreateWindowEx
|
||||||
(
|
(
|
||||||
WS_EX_CLIENTEDGE, // sunken border
|
exStyle, // sunken border
|
||||||
_T("EDIT"), // window class
|
_T("EDIT"), // window class
|
||||||
NULL, // no window title
|
NULL, // no window title
|
||||||
WS_CHILD | WS_BORDER /* | WS_CLIPSIBLINGS */, // style (will be shown later)
|
msStyle /* | WS_CLIPSIBLINGS */, // style (will be shown later)
|
||||||
pos.x, pos.y, // position
|
pos.x, pos.y, // position
|
||||||
0, 0, // size (will be set later)
|
0, 0, // size (will be set later)
|
||||||
GetHwndOf(parent), // parent
|
GetHwndOf(parent), // parent
|
||||||
|
Reference in New Issue
Block a user