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.
|
||||
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
|
||||
// the dialog containing this control if any.
|
||||
bool ClickDefaultButtonIfPossible();
|
||||
|
@@ -121,21 +121,32 @@ bool wxChoice::Create(wxWindow *parent,
|
||||
style, validator, name);
|
||||
}
|
||||
|
||||
bool wxChoice::MSWShouldPreProcessMessage(WXMSG *pMsg)
|
||||
bool wxChoice::MSWShouldPreProcessMessage(WXMSG *msg)
|
||||
{
|
||||
MSG *msg = (MSG *) pMsg;
|
||||
|
||||
// if the dropdown list is visible, don't preprocess certain keys
|
||||
if ( msg->message == WM_KEYDOWN
|
||||
&& (msg->wParam == VK_ESCAPE || msg->wParam == VK_RETURN) )
|
||||
if ( msg->message == WM_KEYDOWN &&
|
||||
!(HIWORD(msg->lParam) & KF_ALTDOWN) &&
|
||||
!wxIsShiftDown() &&
|
||||
!wxIsCtrlDown() )
|
||||
{
|
||||
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
|
||||
|
@@ -383,26 +383,9 @@ bool wxComboBox::MSWCommand(WXUINT param, WXWORD id)
|
||||
|
||||
bool wxComboBox::MSWShouldPreProcessMessage(WXMSG *pMsg)
|
||||
{
|
||||
// prevent command accelerators from stealing editing
|
||||
// hotkeys when we have the focus
|
||||
if (wxIsCtrlDown())
|
||||
{
|
||||
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);
|
||||
return (HasFlag(wxCB_READONLY) ||
|
||||
wxTextEntry::MSWShouldPreProcessMessage(pMsg)) &&
|
||||
wxChoice::MSWShouldPreProcessMessage(pMsg);
|
||||
}
|
||||
|
||||
#if wxUSE_OLE
|
||||
|
@@ -2058,80 +2058,29 @@ void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
|
||||
|
||||
bool wxTextCtrl::MSWShouldPreProcessMessage(WXMSG* msg)
|
||||
{
|
||||
// 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 )
|
||||
// Handle keys specific to (multiline) text controls here.
|
||||
if ( msg->message == WM_KEYDOWN && !(HIWORD(msg->lParam) & KF_ALTDOWN) )
|
||||
{
|
||||
const WPARAM vkey = msg->wParam;
|
||||
if ( HIWORD(msg->lParam) & KF_ALTDOWN )
|
||||
switch ( msg->wParam )
|
||||
{
|
||||
// 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 VK_RETURN:
|
||||
// This key must be handled only by multiline controls and only
|
||||
// if it's pressed on its own, not with some modifier.
|
||||
if ( !wxIsShiftDown() && !wxIsCtrlDown() && IsMultiLine() )
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
switch ( vkey )
|
||||
{
|
||||
case VK_RETURN:
|
||||
// This one is only special for multi line controls.
|
||||
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;
|
||||
}
|
||||
}
|
||||
case VK_BACK:
|
||||
if ( wxIsCtrlDown() && !wxIsShiftDown() &&
|
||||
MSWNeedsToHandleCtrlBackspace() )
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@@ -1072,4 +1072,74 @@ bool wxTextEntry::ClickDefaultButtonIfPossible()
|
||||
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
|
||||
|
Reference in New Issue
Block a user