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)
|
||||
|
||||
BEGIN_EVENT_TABLE(wxSpinCtrl, wxSpinButton)
|
||||
EVT_CHAR(wxSpinCtrl::OnChar)
|
||||
EVT_SPIN(-1, wxSpinCtrl::OnSpinChange)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
@@ -92,9 +93,12 @@ LRESULT APIENTRY _EXPORT wxBuddyTextWndProc(HWND hwnd,
|
||||
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) && ((wxSpinCtrl *)::GetWindowLong(hwnd, GWL_USERDATA)) == spin))
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ::CallWindowProc(CASTWNDPROC spin->GetBuddyWndProc(),
|
||||
hwnd, message, wParam, lParam);
|
||||
}
|
||||
@@ -120,20 +124,71 @@ wxSpinCtrl *wxSpinCtrl::GetSpinForTextCtrl(WXHWND hwndBuddy)
|
||||
// process a WM_COMMAND generated by the buddy text control
|
||||
bool wxSpinCtrl::ProcessTextCommand(WXWORD cmd, WXWORD WXUNUSED(id))
|
||||
{
|
||||
if ( cmd == EN_CHANGE )
|
||||
switch (cmd)
|
||||
{
|
||||
wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
|
||||
event.SetEventObject(this);
|
||||
event.SetInt(GetValue());
|
||||
GetEventHandler()->ProcessEvent(event);
|
||||
|
||||
return TRUE;
|
||||
case EN_CHANGE:
|
||||
{
|
||||
wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
|
||||
event.SetEventObject(this);
|
||||
wxString val = wxGetWindowText(m_hwndBuddy);
|
||||
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
|
||||
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
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -181,13 +236,22 @@ bool wxSpinCtrl::Create(wxWindow *parent,
|
||||
SetRange(min, max);
|
||||
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
|
||||
m_hwndBuddy = (WXHWND)::CreateWindowEx
|
||||
(
|
||||
WS_EX_CLIENTEDGE, // sunken border
|
||||
exStyle, // sunken border
|
||||
_T("EDIT"), // window class
|
||||
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
|
||||
0, 0, // size (will be set later)
|
||||
GetHwndOf(parent), // parent
|
||||
|
Reference in New Issue
Block a user