Skip to content

WI01087563 - Fix ToopStrip issue#39

Open
jaywang-cn wants to merge 2 commits into
masterfrom
JWA/WI01087563
Open

WI01087563 - Fix ToopStrip issue#39
jaywang-cn wants to merge 2 commits into
masterfrom
JWA/WI01087563

Conversation

@jaywang-cn

Copy link
Copy Markdown

Root Cause

In the affected .NET 10 WinForms implementation, ToolStrip.WndProc contains the following behavior for WM_SETFOCUS:

if (m.MsgInternal == PInvokeCore.WM_SETFOCUS)
{
    SnapFocus((HWND)(nint)m.WParamInternal);
    ToolStripManager.ModalMenuFilter.SetActiveToolStrip(this);
}

This registers the ToolStrip as the active ToolStrip and enters modal menu tracking.

When Application.DoEvents() retrieves a posted CodeBox key message, WinForms calls the thread-level message filters before control preprocessing and dispatch.

ToolStripManager.ModalMenuFilter.PreFilterMessage contains this logic:

if (!activeToolStrip.ContainsFocus)
{
    m.HWnd = activeToolStrip.Handle;
}

Because the real focus is now on the CodeBox, activeToolStrip.ContainsFocus is false. The filter changes the message HWND to the ToolStrip HWND.

ModalMenuFilter implements IMessageModifyAndFilter. Therefore, even though PreFilterMessage returns false, Application.ThreadContext.ProcessFilters copies the modified HWND back into the native message.

Why .NET 8 Is Not Affected

The WiseTech net8.0_legacy branch and upstream release/8.0 only call SnapFocus when a ToolStrip receives WM_SETFOCUS:

if (m.MsgInternal == PInvoke.WM_SETFOCUS)
{
    SnapFocus((HWND)(nint)m.WParamInternal);
}

The problematic behavior was introduced by upstream commit:

That commit is part of the current .NET 10 baseline but is not part of the .NET 8 legacy baseline.

Consequently, under .NET 8, the basher can focus the internal ToolStrip without registering it as the active modal-menu ToolStrip. Subsequent CodeBox keys continue to target the CodeBox.

Fix

The correct fix is to backport the following upstream WinForms commits in order.

1. Restrict and clear ordinary ToolStrip menu tracking

This change:

  • Activates ModalMenuFilter for an ordinary ToolStrip only when focus transfers from another ToolStrip or one of its child controls.
  • Avoids activating modal menu tracking for generic or programmatic focus.
  • Handles WM_KILLFOCUS and removes the active ToolStrip when focus moves outside the ToolStrip context.
  • Exits menu mode when no active ToolStrip remains.

This commit directly addresses the WarehouseEntryForm failure.

2. Preserve tracking for real ToolStripDropDown scenarios

The first fix correctly handles ordinary ToolStrips but can be too restrictive for ToolStripDropDown controls used by dropdowns and designer SmartTag panels.

This follow-up change:

  • Keeps ToolStripDropDown controls participating in modal menu tracking when they receive focus.
  • Prevents ordinary ToolStrip cleanup rules from incorrectly terminating a visible dropdown's menu tracking.
  • Preserves the original dropdown and SmartTag focus behavior while retaining the ordinary ToolStrip fix.

Both commits should be applied together and in this order.

While it lacks the fix commits:
dotnet@9341877
dotnet@e0bbecd

Cherry-pick the commits instead of sync the fork to avoid unknown issues.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant