Merge branch 'msw-combo-keys'
Fix behaviour of comboboxes in presence of accelerators in wxMSW. See https://github.com/wxWidgets/wxWidgets/pull/2443
This commit is contained in:
@@ -84,6 +84,10 @@ protected:
|
|||||||
// Returns true if this control uses standard file names completion.
|
// Returns true if this control uses standard file names completion.
|
||||||
bool MSWUsesStandardAutoComplete() const;
|
bool MSWUsesStandardAutoComplete() const;
|
||||||
|
|
||||||
|
// Returns false if this message shouldn't be preprocessed, but is always
|
||||||
|
// handled by the EDIT control represented by this object itself.
|
||||||
|
bool MSWShouldPreProcessMessage(WXMSG* msg) const;
|
||||||
|
|
||||||
// Helper for wxTE_PROCESS_ENTER handling: activates the default button in
|
// Helper for wxTE_PROCESS_ENTER handling: activates the default button in
|
||||||
// the dialog containing this control if any.
|
// the dialog containing this control if any.
|
||||||
bool ClickDefaultButtonIfPossible();
|
bool ClickDefaultButtonIfPossible();
|
||||||
|
@@ -121,21 +121,32 @@ bool wxChoice::Create(wxWindow *parent,
|
|||||||
style, validator, name);
|
style, validator, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxChoice::MSWShouldPreProcessMessage(WXMSG *pMsg)
|
bool wxChoice::MSWShouldPreProcessMessage(WXMSG *msg)
|
||||||
{
|
{
|
||||||
MSG *msg = (MSG *) pMsg;
|
if ( msg->message == WM_KEYDOWN &&
|
||||||
|
!(HIWORD(msg->lParam) & KF_ALTDOWN) &&
|
||||||
// if the dropdown list is visible, don't preprocess certain keys
|
!wxIsShiftDown() &&
|
||||||
if ( msg->message == WM_KEYDOWN
|
!wxIsCtrlDown() )
|
||||||
&& (msg->wParam == VK_ESCAPE || msg->wParam == VK_RETURN) )
|
|
||||||
{
|
{
|
||||||
if (::SendMessage(GetHwndOf(this), CB_GETDROPPEDSTATE, 0, 0))
|
switch ( msg->wParam )
|
||||||
{
|
{
|
||||||
return false;
|
case VK_ESCAPE:
|
||||||
|
case VK_RETURN:
|
||||||
|
// These keys are needed by the control itself when the
|
||||||
|
// dropdown list is visible, so don't preprocess them then.
|
||||||
|
if (::SendMessage(GetHwndOf(this), CB_GETDROPPEDSTATE, 0, 0))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VK_F4:
|
||||||
|
// This key can always be used to show the dropdown.
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxControl::MSWShouldPreProcessMessage(pMsg);
|
return wxControl::MSWShouldPreProcessMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
WXDWORD wxChoice::MSWGetStyle(long style, WXDWORD *exstyle) const
|
WXDWORD wxChoice::MSWGetStyle(long style, WXDWORD *exstyle) const
|
||||||
|
@@ -383,26 +383,9 @@ bool wxComboBox::MSWCommand(WXUINT param, WXWORD id)
|
|||||||
|
|
||||||
bool wxComboBox::MSWShouldPreProcessMessage(WXMSG *pMsg)
|
bool wxComboBox::MSWShouldPreProcessMessage(WXMSG *pMsg)
|
||||||
{
|
{
|
||||||
// prevent command accelerators from stealing editing
|
return (HasFlag(wxCB_READONLY) ||
|
||||||
// hotkeys when we have the focus
|
wxTextEntry::MSWShouldPreProcessMessage(pMsg)) &&
|
||||||
if (wxIsCtrlDown())
|
wxChoice::MSWShouldPreProcessMessage(pMsg);
|
||||||
{
|
|
||||||
WPARAM vkey = pMsg->wParam;
|
|
||||||
|
|
||||||
switch (vkey)
|
|
||||||
{
|
|
||||||
case 'C':
|
|
||||||
case 'V':
|
|
||||||
case 'X':
|
|
||||||
case VK_INSERT:
|
|
||||||
case VK_DELETE:
|
|
||||||
case VK_HOME:
|
|
||||||
case VK_END:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxChoice::MSWShouldPreProcessMessage(pMsg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if wxUSE_OLE
|
#if wxUSE_OLE
|
||||||
|
@@ -2058,80 +2058,29 @@ void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
|
|||||||
|
|
||||||
bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* msg)
|
bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* msg)
|
||||||
{
|
{
|
||||||
// check for our special keys here: if we don't do it and the parent frame
|
// Handle keys specific to (multiline) text controls here.
|
||||||
// uses them as accelerators, they wouldn't work at all, so we disable
|
if ( msg->message == WM_KEYDOWN && !(HIWORD(msg->lParam) & KF_ALTDOWN) )
|
||||||
// usual preprocessing for them
|
|
||||||
if ( msg->message == WM_KEYDOWN )
|
|
||||||
{
|
{
|
||||||
const WPARAM vkey = msg->wParam;
|
switch ( msg->wParam )
|
||||||
if ( HIWORD(msg->lParam) & KF_ALTDOWN )
|
|
||||||
{
|
{
|
||||||
// Alt-Backspace is accelerator for "Undo"
|
case VK_RETURN:
|
||||||
if ( vkey == VK_BACK )
|
// This key must be handled only by multiline controls and only
|
||||||
return false;
|
// if it's pressed on its own, not with some modifier.
|
||||||
}
|
if ( !wxIsShiftDown() && !wxIsCtrlDown() && IsMultiLine() )
|
||||||
else // no Alt
|
return false;
|
||||||
{
|
break;
|
||||||
// we want to process some Ctrl-foo and Shift-bar but no key
|
|
||||||
// combinations without either Ctrl or Shift nor with both of them
|
|
||||||
// pressed
|
|
||||||
const int ctrl = wxIsCtrlDown(),
|
|
||||||
shift = wxIsShiftDown();
|
|
||||||
switch ( ctrl + shift )
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
wxFAIL_MSG( wxT("how many modifiers have we got?") );
|
|
||||||
wxFALLTHROUGH;
|
|
||||||
|
|
||||||
case 0:
|
case VK_BACK:
|
||||||
switch ( vkey )
|
if ( wxIsCtrlDown() && !wxIsShiftDown() &&
|
||||||
{
|
MSWNeedsToHandleCtrlBackspace() )
|
||||||
case VK_RETURN:
|
return false;
|
||||||
// This one is only special for multi line controls.
|
break;
|
||||||
if ( !IsMultiLine() )
|
|
||||||
break;
|
|
||||||
wxFALLTHROUGH;
|
|
||||||
|
|
||||||
case VK_DELETE:
|
|
||||||
case VK_HOME:
|
|
||||||
case VK_END:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
wxFALLTHROUGH;
|
|
||||||
case 2:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
// either Ctrl or Shift pressed
|
|
||||||
if ( ctrl )
|
|
||||||
{
|
|
||||||
switch ( vkey )
|
|
||||||
{
|
|
||||||
case 'A':
|
|
||||||
case 'C':
|
|
||||||
case 'V':
|
|
||||||
case 'X':
|
|
||||||
case VK_INSERT:
|
|
||||||
case VK_DELETE:
|
|
||||||
case VK_HOME:
|
|
||||||
case VK_END:
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case VK_BACK:
|
|
||||||
if ( MSWNeedsToHandleCtrlBackspace() )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // Shift is pressed
|
|
||||||
{
|
|
||||||
if ( vkey == VK_INSERT || vkey == VK_DELETE )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxControl::MSWShouldPreProcessMessage(msg);
|
// Delegate all the other checks to the base classes.
|
||||||
|
return wxTextEntry::MSWShouldPreProcessMessage(msg) &&
|
||||||
|
wxControl::MSWShouldPreProcessMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxTextCtrl::OnChar(wxKeyEvent& event)
|
void wxTextCtrl::OnChar(wxKeyEvent& event)
|
||||||
|
@@ -1072,4 +1072,74 @@ bool wxTextEntry::ClickDefaultButtonIfPossible()
|
|||||||
wxWindow::MSWGetDefaultButtonFor(GetEditableWindow()));
|
wxWindow::MSWGetDefaultButtonFor(GetEditableWindow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxTextEntry::MSWShouldPreProcessMessage(WXMSG* msg) const
|
||||||
|
{
|
||||||
|
// check for our special keys here: if we don't do it and the parent frame
|
||||||
|
// uses them as accelerators, they wouldn't work at all, so we disable
|
||||||
|
// usual preprocessing for them
|
||||||
|
if ( msg->message == WM_KEYDOWN )
|
||||||
|
{
|
||||||
|
const WPARAM vkey = msg->wParam;
|
||||||
|
if ( HIWORD(msg->lParam) & KF_ALTDOWN )
|
||||||
|
{
|
||||||
|
// Alt-Backspace is accelerator for "Undo"
|
||||||
|
if ( vkey == VK_BACK )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else // no Alt
|
||||||
|
{
|
||||||
|
// we want to process some Ctrl-foo and Shift-bar but no key
|
||||||
|
// combinations without either Ctrl or Shift nor with both of them
|
||||||
|
// pressed
|
||||||
|
const int ctrl = wxIsCtrlDown(),
|
||||||
|
shift = wxIsShiftDown();
|
||||||
|
switch ( ctrl + shift )
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG( wxT("how many modifiers have we got?") );
|
||||||
|
wxFALLTHROUGH;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
switch ( vkey )
|
||||||
|
{
|
||||||
|
case VK_DELETE:
|
||||||
|
case VK_HOME:
|
||||||
|
case VK_END:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
// either Ctrl or Shift pressed
|
||||||
|
if ( ctrl )
|
||||||
|
{
|
||||||
|
switch ( vkey )
|
||||||
|
{
|
||||||
|
case 'A':
|
||||||
|
case 'C':
|
||||||
|
case 'V':
|
||||||
|
case 'X':
|
||||||
|
case VK_INSERT:
|
||||||
|
case VK_DELETE:
|
||||||
|
case VK_HOME:
|
||||||
|
case VK_END:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Shift is pressed
|
||||||
|
{
|
||||||
|
if ( vkey == VK_INSERT || vkey == VK_DELETE )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_TEXTCTRL || wxUSE_COMBOBOX
|
#endif // wxUSE_TEXTCTRL || wxUSE_COMBOBOX
|
||||||
|
Reference in New Issue
Block a user