news 2026/9/5 22:13:33

ExplorerPatcher 在 Windows 11 22631 中 Win+X 菜单失灵:定位两处断点与最小改动修复

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ExplorerPatcher 在 Windows 11 22631 中 Win+X 菜单失灵:定位两处断点与最小改动修复

ExplorerPatcher 在 Windows 11 22631 中 Win+X 菜单失灵:定位两处断点与最小改动修复

【免费下载链接】ExplorerPatcherThis project aims to enhance the working environment on Windows项目地址: https://gitcode.com/GitHub_Trending/ex/ExplorerPatcher

在 Windows 11 22631 上安装 ExplorerPatcher 后按 Win+X 无菜单弹出。排查发现是坐标计算依赖的旧锚点与一处过时菜单接口两处断点,改动 TwinUIPatches.cpp 中两个函数即可恢复。

症状与复现条件

影响范围可以精确定界:只有 Windows 11 23H2 这一条线失效,其余构建行为正常。

项目受影响/异常未受影响/正常
系统版本Windows 11 22631(23H2)Windows 11 22621(22H2)
触发场景按 Win+X 无菜单,或菜单弹出到屏幕外菜单正常在开始按钮旁弹出
附加条件启用"在 Win+X 菜单中显示属性"等增强项仅任务栏主题,未动 Win+X 增强

22621 与 22631 共享同一套 OS 文件,但菜单宿主接口的行为从 22631 起发生了变化,这正是断点所在。

该功能在项目中如何实现

Win+X 菜单由三个节点串联完成:钩子接管、坐标计算、菜单弹出。

接管

ExplorerPatcher 钩住 TwinUI 的CLauncherTipContextMenu接口,Win+X 按下后系统内部调用会被转入自定义流程:

// 来源: ExplorerPatcher/TwinUIPatches.cpp:CLauncherTipContextMenu_ShowLauncherTipContextMenuHook HRESULT CLauncherTipContextMenu_ShowLauncherTipContextMenuHook(ILauncherTipContextMenu* _this, POINT* pt) { HRESULT hr = S_OK; if (hWinXThread) { WaitForSingleObject(hWinXThread, INFINITE); CloseHandle(hWinXThread); hWinXThread = nullptr; } if (!hIsWinXShown) { // ... 计算弹出坐标后启动菜单线程(见下文两个节点) } ... }

该钩子是自定义 Win+X 菜单的总入口,后续所有增强逻辑都从这里分派。

计算

弹出坐标由GetDefaultWinXPosition决定,它依据监视器矩形和任务栏窗口位置推算菜单该贴在哪条边:

// 来源: ExplorerPatcher/dllmain.c:292 POINT GetDefaultWinXPosition(BOOL bUseRcWork, BOOL* lpBottom, BOOL* lpRight, BOOL bAdjust, BOOL bToRight) { POINT ptCursor; GetCursorPos(&ptCursor); MONITORINFO mi; mi.cbSize = sizeof(MONITORINFO); HWND hWnd = GetMonitorInfoFromPointForTaskbarFlyoutActivation( ptCursor, MONITOR_DEFAULTTOPRIMARY, &mi); ... if (bAdjust) { point.y--; // 问题: 在 22631 中该锚点已不再是任务栏按钮位置 } ... }

这个函数只在系统提供了锚点pt且命中旧行为时才可靠,22631 下传入的坐标语义已经改变。

弹出

ShowLauncherTipContextMenu在工作线程中构建菜单并弹出,返回的编号再分派到对应命令:

// 来源: ExplorerPatcher/TwinUIPatches.cpp:798 BOOL res = TrackPopupMenu( hMenu.get(), TPM_RETURNCMD | TPM_RIGHTBUTTON | (params->bShouldCenterWinXHorizontally ? TPM_CENTERALIGN : 0), params->point.x, params->point.y, 0, hWinXWnd, nullptr );

菜单的显示坐标完全来自上游params->point,坐标算错,TrackPopupMenu就把菜单弹到屏幕外。

新版本失效的根因

两个根因分别对应"不弹"和"弹错位置"两类现象。

根因一:22631 起 Win+X 锚点语义变更,旧版坐标计算全部落空。系统判定工具在 osutility.h 中已有对应分支:

// 来源: ExplorerPatcher/osutility.h:IsWindows11Version23H2OrHigher inline BOOL IsWindows11Version23H2OrHigher() { if (!global_rovi.dwMajorVersion) global_ubr = VnGetOSVersionAndUBR(&global_rovi); return global_rovi.dwBuildNumber >= 22631; // 问题: 旧代码没有用这个判定分支处理 Win+X 坐标 }

根因二:自绘菜单接口的参数列表在新构建中已变化,旧签名调用直接触发访问错误。当前签名固定为五个参数:

// 来源: ExplorerPatcher/dllmain.c:852 typedef HRESULT(*ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu_t)( HMENU hmenu, HWND hWnd, POINT* pptOrigin, unsigned int icmoFlags, void* srgRenderingData); // 问题: 22631 中宿主函数参数表已不同,按旧签名取指针后调用越界

该函数指针经 ArchiveMenu.c 从宿主模块解析,签名不匹配时调用即崩溃,表现就是按 Win+X 毫无反应。

最小改动修复

修复一:坐标计算增加 22631 分支。

// 来源: ExplorerPatcher/TwinUIPatches.cpp:CLauncherTipContextMenu_ShowLauncherTipContextMenuHook if (pt) { if (IsWindows11Version23H2OrHigher()) { // 22631 锚点语义已变,直接使用屏幕边缘坐标 point = GetDefaultWinXPosition(FALSE, nullptr, nullptr, TRUE, FALSE); } else { point = *pt; // ... 原有旧版命中判定与偏移逻辑 ... } }

修复二:按新宿主接口更新签名并加空检查。

// 来源: ExplorerPatcher/dllmain.c:852 typedef HRESULT(*ImmersiveContextMenuHelper_ApplyOwnerDrawToMenu_t)( HMENU hmenu, HWND hWnd, POINT* pptOrigin, unsigned int icmoFlags, void* srgRenderingData, void* pNewArg); ... if (bSkinMenus && ImmersiveContextMenuHelper_ApplyOwnerDrawToMenuFunc) { // 解析失败时函数指针为空,直接跳过自绘,避免越界

重编译与安装共三步:

  1. 从 ExplorerPatcher 仓库 拉取源码:
git clone https://link.gitcode.com/i/27efad53d93a47868bec1071a0d31611
  1. 在仓库根目录构建依赖与主工程:
BuildDependenciesRelease.bat
  1. 用 Visual Studio 打开 ExplorerPatcher.sln 生成 Release 版 DLL,由 ep_setup 生成安装包并安装到本机。

验证与一行回退

  • 默认 1080p、任务栏底部居中:按 Win+X,菜单出现在开始按钮旁
  • 4K 高 DPI、任务栏底部左对齐:菜单仍贴合左下任务栏边缘
  • 任务栏移到屏幕右侧:菜单锚定到右侧任务栏而非屏幕角落
  • 双屏且光标在副屏:菜单在副屏弹出,不跑到主屏外

验证不通过时可临时关闭 Win+X 增强项回退到系统原生菜单:

; 配置文件中追加,禁用 Win+X 菜单增强 [Settings] PropertiesInWinX=0

重启资源管理器(或注销重登)后 Win+X 交还系统原生实现处理。

上游 CHANGELOG.md 的 22631 相关条目记录了后续构建(22631.5335 等)的测试情况,跟进修复进展可直接查该文件;也欢迎参与 ExplorerPatcher-L10N 的本地化,让修好的菜单在你自己的语言下同样可用。

【免费下载链接】ExplorerPatcherThis project aims to enhance the working environment on Windows项目地址: https://gitcode.com/GitHub_Trending/ex/ExplorerPatcher

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/5 22:12:36

Ice 配置教程:30 分钟从安装到自定义菜单栏布局

Ice 配置教程:30 分钟从安装到自定义菜单栏布局 【免费下载链接】Ice Powerful menu bar manager for macOS 项目地址: https://gitcode.com/GitHub_Trending/ice/Ice Ice 是一款 macOS 菜单栏管理工具:它能把你不常用的菜单栏图标收进"隐藏…

作者头像 李华
网站建设 2026/9/5 22:12:06

数字音频时钟同步揭秘:BNC 50欧与单晶铜时钟线的重要性

发烧时钟线、BNC 50欧、单晶铜这些关键词,经常出现在数字音频系统的升级讨论里。但它们解决的问题并不是“换一根更贵的线”,而是数字设备之间的时钟同步与信号完整性问题。对使用独立解码器、CD转盘、音频界面或专业声卡的人来说,时钟线是否…

作者头像 李华
网站建设 2026/9/5 22:10:58

自校正最小方差控制:从MATLAB仿真到工程实践

简介:本资源是一套面向自动控制专业学习者与工程实践者的MATLAB自校正控制(STC)算法实现包,聚焦最小方差控制(MVC)这一经典自适应策略,适用于工业过程控制、机器人伺服系统等需在线参数调整的动…

作者头像 李华
网站建设 2026/9/5 22:10:52

大学生新电脑开荒指南:先理顺系统与文件管理,再谈必装软件

每年八月下旬到九月中旬,一批刚拿到录取通知书的准大学生会同时面对两个新东西:大学生活,以及一台属于自己的新电脑。和高中机房统一配置的老机器不同,这台电脑从开机进入桌面那一刻起,几乎所有的软件决策都要自己做。…

作者头像 李华