Bug in System.Windows.Forms.ToolStrip.ProcessCmdKey

  • Thread starter Thread starter Sune Foldager
  • Start date Start date
S

Sune Foldager

Greetings,

There is a bug in the method System.Windows.Forms.ToolStrip.ProcessCmdKey
which can cause application-wide shortcuts to stop working. For instance,
we have an application where there is a global shortcut ctrl + k to open
a form. Whenever the toolstrip is active, however, pressing ctrl + k will
instead behave as if you pressed ctrl + tab.

The problem is the following line from System.Windows.Forms.ToolStrip.ProcessCmdKey
(here reconstructed using the .NET Reflector):

if ((!this.IsDropDown && ((keyData & (Keys.Control | Keys.Tab)) == (Keys.Control
| Keys.Tab))) && (!this.TabStop && this.HasKeyboardInput))

In particular, the following part which is supposed to determine if ctrl
+ tab was pressed:

(keyData & (Keys.Control | Keys.Tab)) == (Keys.Control | Keys.Tab))

But this is clearly a bug, since every keycode for which kc & Keys.Tab ==
Keys.Tab (i.e. 8) will satisfy the condition, including k as well as several
other alphabetic characters. The entire line should instead be:

if ((!this.IsDropDown && ((keyData & Keys.Control) == Keys.Control) &&
((keyData & Keys.KeyCode) == Keys.Tab) && (!this.TabStop && this.HasKeyboardInput))

Which would fix the bug. Right now we had to hack around it instead. The
bug has existed at least since .NET 1.1.

Sincerly,
Sune Foldager
Edlund A/
 
Hi Sune,
For instance, we have an application where there is a global shortcut
ctrl + k to open a form. Whenever the toolstrip is active, however,
pressing ctrl + k will instead behave as if you pressed ctrl + tab.

How do you implement the global shortcut for the application? Have you
derived from the ToolStrip class and override the ProcessCmdKey method? If
so, what code do you add in the override ProcessCmdKey?

It would be better for us to look into this issue if you could reproduce
the problem in a simple project and send it to me. To get my actual email
address, remove 'online' from my displayed email address.

I look forward to your reply!

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hi Linda,
How do you implement the global shortcut for the application? Have you
derived from the ToolStrip class and override the ProcessCmdKey
method? If so, what code do you add in the override ProcessCmdKey?

It's actually just a pretty regular menu shortcut, set using the ToolStripMenuItem.ShortcutKeys
property.
Sorry about that, I realize that the term "global shortcut" is a bit confusing.
It would be better for us to look into this issue if you could
reproduce the problem in a simple project and send it to me. To get my
actual email address, remove 'online' from my displayed email address.

In the mean time Marc Gravell (on this newsgroup) suggested that I file a
report with connect, which I did:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=352678

It also seems they were able to reproduce it. Should I take any additional
steps at this point?

Sincerly,
Sune Foldager
 
Hi Sune,

Thank you for your quick response! I can reproduce the problem on my side
now.

As you have mentioned, the reason behind this issue is that the ToolStrip
class uses the following condition to determine whether Ctrl+Tab were
presssd:
(keyData & (Keys.Control | Keys.Tab)) == (Keys.Control | Keys.Tab))

The workaround is to derive from the ToolStrip class and override the
ProcessCmdKey method. If the Ctrl+K or something else except Ctrl+Tab that
meets the above condition were pressed, return false directly in the
override ProcessCmdKey method.

The following is a sample:

class MyToolStrip : ToolStrip
{
private bool CheckToolStrip(ToolStrip toolStrip, Keys keyData)
{
ToolStripDropDownButton ddb = null;
bool result = false;
for (int i = 0; i < toolStrip.Items.Count; i++)
{
if (toolStrip.Items.GetType() ==
typeof(ToolStripDropDownButton))
{
ddb = toolStrip.Items as ToolStripDropDownButton;
for (int j = 0; j < ddb.DropDownItems.Count; j++)
{
if (ddb.DropDownItems[j].GetType() ==
typeof(ToolStripMenuItem))
{
result = CheckMenuItem(ddb.DropDownItems[j] as
ToolStripMenuItem, keyData);
if (result)
{ break; }
}
}
if (result)
{ break; }
}
}
return result;
}

private bool CheckMenuItem(ToolStripMenuItem menuitem, Keys keyData)
{
bool result = false;
if (menuitem.ShortcutKeys == keyData)
result = true;
else
{
for (int i = 0; i < menuitem.DropDownItems.Count; i++)
{
if (menuitem.DropDownItems.GetType() ==
typeof(ToolStripMenuItem))
{
result = CheckMenuItem(menuitem.DropDownItems as
ToolStripMenuItem, keyData);
if (result)
{
break;
}
}
}
}
return result;
}
protected override bool ProcessCmdKey(ref Message m, Keys keyData)
{
if ((keyData != (Keys.Control | Keys.Tab)) && ((keyData &
(Keys.Control | Keys.Tab)) == (Keys.Control | Keys.Tab)))
{
if (CheckToolStrip(this, keyData))
return base.ProcessCmdKey(ref m, keyData);
else
return false;
}
else
return base.ProcessCmdKey(ref m, keyData);
}
}

Thank you for reporting this issue to us and your contribution to Microsoft
product! It will definitely improve our product.
If you have any concern, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hi Sune,

How about the problem now?

If you have any concern, please feel free to let me know.

Thank you for using our MSDN Managed Newsgroup Support Service!

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hello Linda,
How about the problem now?

Yes, I have been able to hack around it using a variation of the method you
proposed; in fact, we had done something similar back when we discovered
the bug. Thanks :).

Sincerly,
Sun
 
Hi Sune,

Thank you for your response!

If you have any other question in the future, please don't hesitate to
contact us. It's always our pleasure to be of assistance.

Have a nice day!

Sincerely,
Linda Liu
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
 
Back
Top