c++ - Windows 类型不允许我的回调访问局部变量,有什么解决方法吗?
问题描述
我正在尝试使用该EnumWindows
函数,该函数采用WNDENUMPROC
带有 lambda 的 as 回调来访问局部变量。不幸的是,如果我尝试使用[&]
编译器会告诉我类型不匹配。我正在尝试什么:
HWND get_wallpaper_window()
{
HWND progman = FindWindow(L"ProgMan", NULL);
SendMessageTimeout(progman, 0x052C, 0, 0, SMTO_NORMAL, 1000, nullptr);
HWND wallpaper_hwnd;
EnumWindows(
// Error here
[&](HWND hwnd, LPARAM lParam) -> BOOL CALLBACK
{
HWND p = FindWindowEx(hwnd, NULL, L"SHELLDLL_DefView", NULL);
if (p) { wallpaper_hwnd = FindWindowEx(NULL, hwnd, L"WorkerW", NULL); }
}
, NULL);
return wallpaper_hwnd;
}
我能想出的唯一解决方案是使 wallpaper_hwnd 全局并用 定义 lambda []
,但由于它仅在从该函数返回时才需要,而不是全局需要,我宁愿避免这种情况。
我比人们建议的更喜欢使用全局变量,但我只在全局变量与整个程序交互时才这样做,而事实并非如此。
我缺少任何更好的解决方案吗?
解决方案
捕获外部变量的 Lambda 函数不能用作 Win32 回调。它们不能转换为原始函数指针。
在您的情况下,解决方案是将指针作为 EnumWindows() 的 LPARAM 参数传递给回调,该参数将传递给回调。
class A {...};
A a;
EnumWindows([](HWND hwnd,LPARAM lParam) -> BOOL {
A* a = (A*)lParam;
...
},(LPARAM)&a);
大多数需要回调的 Windows 函数都支持传递用户定义的值,该值可以是指向结构的指针。编译器足够聪明,可以自动将非捕获 lambda 转换为 CALLBACK (=_stdcall) 调用约定。
推荐阅读
- wordpress - FAILED_DOCUMENT_REQUEST。时间到
- assembly - 使用 NASM 的 __?float?__ 宏
- swiftui - 当我一起使用 onTapGesture 时如何修复 DragGesture() 移动不顺畅
- triplestore - 如何解密 RDF4J 数据库的 Triplestore 文件?
- android - Camera2录制视频,按下录制按钮后屏幕冻结(仅在使用前置摄像头和某些设备时)
- linux - ldapsearch 获取特定 AD 组中的用户列表 (samAccountName)
- json - 如何在flutter中显示带有json数据的饼图
- c# - 保存到数据库的第一个函数完成后调用 Azure 函数
- git - Git 获取差异作为本地更改
- java - 我在这里的输入不需要区分大小写。我会告诉你我的代码请帮忙,我对如何做到这一点一无所知