Skip to content

Commit 08f1596

Browse files
authored
Merge pull request #43 from PWagner1/40-explorerbrowser-control-rewrites-translateaccelerator-of-whole-app-and-prevents-all-other-controls-from-processing-the-tab-key
* Version 8.0.15
2 parents 1b7072b + e48985b commit 08f1596

4 files changed

Lines changed: 72 additions & 7 deletions

File tree

‎Changelog.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
# Changelog
22

3-
xx/0x/2026
3+
01/04/2026
44

55
Version 8.0.15
6+
* Fixed [#40](https://github.com/PWagner1/Windows-API-CodePack-NET/issues/40), ExplorerBrowser control now only processes keyboard accelerators when it has focus, preventing Tab key interception for other controls
7+
* Updated `PreFilterMessage` to check message target and focus state before calling `TranslateAcceleratorIO`
8+
* Added `IsMessageForExplorerBrowser` helper method to verify message window ownership
9+
* Added `GetParent` Windows API function to `WindowNativeMethods` for window hierarchy traversal
610
* Implemented [#39](https://github.com/PWagner1/Windows-API-CodePack-NET/issues/39), Added Authenticode signing support for DLLs
711
* Added MSBuild properties for Authenticode signing configuration (`EnableAuthenticodeSigning`, `CodeSigningCertificatePath`, `CodeSigningCertificatePassword`, `CodeSigningCertificateThumbprint`)
812
* Integrated Authenticode signing into GitHub Actions release workflow

‎Source/Current/Windows API CodePack/Components/Shell/Common/IconReference.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public struct IconReference
1313

1414
private string? _moduleName;
1515
private string _referencePath;
16-
static private readonly char[] CommaSeparator = new char[] { ',' };
16+
private static readonly char[] CommaSeparator = new char[] { ',' };
1717

1818
#endregion
1919

‎Source/Current/Windows API CodePack/Components/Shell/Common/WindowNativeMethods.cs‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace Microsoft.WindowsAPICodePack.Shell;
1+
namespace Microsoft.WindowsAPICodePack.Shell;
22

33
internal static class WindowNativeMethods
44
{
@@ -21,6 +21,14 @@ internal static class WindowNativeMethods
2121
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
2222
[DllImport("user32.dll", CharSet = CharSet.Auto)]
2323
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int width, int height, SetWindowPosFlags flags);
24+
25+
/// <summary>
26+
/// Retrieves the handle to the parent window of the specified window.
27+
/// </summary>
28+
/// <param name="hWnd">A handle to the window whose parent window handle is to be retrieved.</param>
29+
/// <returns>If the window is a child window, the return value is a handle to the parent window. If the window is a top-level window, the return value is IntPtr.Zero.</returns>
30+
[DllImport("user32.dll", SetLastError = true)]
31+
public static extern IntPtr GetParent(IntPtr hWnd);
2432
}
2533

2634
internal enum WindowLongFlags

‎Source/Current/Windows API CodePack/Components/Shell/ExplorerBrowser/ExplorerBrowser.cs‎

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,13 +1217,66 @@ HResult ICommDlgBrowser3.OnPreViewCreated(IShellView ppshv)
12171217

12181218
bool IMessageFilter.PreFilterMessage(ref System.Windows.Forms.Message m)
12191219
{
1220-
HResult hr = HResult.False;
1220+
// Only process keyboard messages
1221+
if (m.Msg < (int)WindowMessage.KeyFirst || m.Msg > (int)WindowMessage.KeyLast)
1222+
{
1223+
return false;
1224+
}
1225+
1226+
// Check if the message is for this control or its child windows
1227+
if (!IsMessageForExplorerBrowser(m.HWnd))
1228+
{
1229+
return false;
1230+
}
1231+
1232+
// Only process if ExplorerBrowser has focus
12211233
if (ExplorerBrowserControl is IInputObject inputObject)
12221234
{
1223-
// translate keyboard input
1224-
hr = inputObject.TranslateAcceleratorIO(ref m);
1235+
// Check if ExplorerBrowser actually has focus before processing
1236+
HResult focusResult = inputObject.HasFocusIO();
1237+
if (focusResult != HResult.Ok)
1238+
{
1239+
return false;
1240+
}
1241+
1242+
// translate keyboard input only when ExplorerBrowser has focus
1243+
HResult hr = inputObject.TranslateAcceleratorIO(ref m);
1244+
return (hr == HResult.Ok);
1245+
}
1246+
1247+
return false;
1248+
}
1249+
1250+
/// <summary>
1251+
/// Checks if a window handle belongs to this ExplorerBrowser control or its child windows.
1252+
/// </summary>
1253+
/// <param name="hwnd">The window handle to check.</param>
1254+
/// <returns>True if the handle belongs to this control or its children; otherwise, false.</returns>
1255+
private bool IsMessageForExplorerBrowser(IntPtr hwnd)
1256+
{
1257+
if (hwnd == IntPtr.Zero)
1258+
{
1259+
return false;
1260+
}
1261+
1262+
// Check if the message is for this control
1263+
if (hwnd == Handle)
1264+
{
1265+
return true;
12251266
}
1226-
return (hr == HResult.Ok);
1267+
1268+
// Check if the message is for a child window of this control
1269+
IntPtr parent = WindowNativeMethods.GetParent(hwnd);
1270+
while (parent != IntPtr.Zero)
1271+
{
1272+
if (parent == Handle)
1273+
{
1274+
return true;
1275+
}
1276+
parent = WindowNativeMethods.GetParent(parent);
1277+
}
1278+
1279+
return false;
12271280
}
12281281

12291282
#endregion

0 commit comments

Comments
 (0)