CBT_CREATEWND 结构的名称无效
Posted
技术标签:
【中文标题】CBT_CREATEWND 结构的名称无效【英文标题】:CBT_CREATEWND structure has invalid name 【发布时间】:2013-12-14 12:48:50 【问题描述】:这是我的挂钩程序,当我尝试读取存储在 CBTHOOKCREATE->lpcs->lpszName
中的名称时,它会遇到垃圾值,例如:
79 77A064700 Created!~
0 00F915BC0 Created!~
68 000DF5BC0 Created!~
0 00F915BC0 Created!~
0 00F915BC0 Created!~
67 7630D8200 Created!~
77 000DEF340 Created!~
79 77A064700 Created!~
同样的事情也适用于lpszClass
。
关于取消引用 lparam 有什么我应该做的,但还没有做的事情!?
这是有问题的功能:
LRESULT CALLBACK HookProcedure(int nCode, WPARAM wparam, LPARAM lparam)
if (nCode < 0) return CallNextHookEx(hookID, nCode, wparam, lparam);
std::ofstream outfile;
CBT_CREATEWND *CBTHOOKCREATE;
RECT *CBTRECTPTR;
RECT CBTRECT;
wstring Message;
CBTHOOKCREATE = (CBT_CREATEWND*) lparam;
LPWSTR str = L" ";
outfile.open(("d:\\test.txt"), std::ios_base::app);
if (nCode >= 0)
switch (nCode)
case HCBT_CREATEWND:
outfile << *(CBTHOOKCREATE->lpcs->lpszName) << " " << CBTHOOKCREATE->lpcs->lpszName << " Created!~ " << endl;
//cout << "Created!~" << endl;
break;
case HCBT_DESTROYWND:
outfile << "Destroied!~" << endl;
//cout << "Destroied!~" << endl;
break;
default:
//cout << "sth else" << endl;
break;
outfile.close();
return 0;
【问题讨论】:
【参考方案1】:*强文本*尝试将IsWindowUnicode 与wParam
中的窗口句柄一起使用。
如果 Window 是 Unicode 的,lpcs
指向一个 CREATESTRUCTW
结构,lpszName
指向一个宽字符串,您将不得不对其进行转换。
将以下代码添加到 DLL CPP 文件的顶部。
std::string wc2s( const wchar_t * pw )
int length = (int)wcslen( pw ) + 1;
int newlen = WideCharToMultiByte( CP_ACP, 0, pw, length, 0, 0, 0, 0 );
std::string r( newlen , '\0' );
WideCharToMultiByte( CP_ACP, 0, pw, length, &r[0], newlen, 0, 0 );
return r;
对传递给 CreateWindow 的文本使用以下代码
case HCBT_CREATEWND:
CBT_CREATEWND * pCBT_CW = (CBT_CREATEWND *)lParam;
std::string strCreatText;
if ( pCBT_CW->lpcs->lpszName != NULL )
if ( IsWindowUnicode( (HWND)wParam ) )
strCreatText = wc2s( pCBT_CW->lpcs->lpszName );
else
strCreatText = (char*)pCBT_CW->lpcs->lpszName;
outfile << strCreatText << " Created!~ " << endl;
break;
PS:未经测试
更新:根据 IInspectable 评论。非侵入式 CBT_HOOK 必须遵循 hooks 的一般规则:返回 CallNextHookEx 返回的内容。
LRESULT CALLBACK HookProcedure(int nCode, [...]
if ( nCode >= 0 )
[...]
return CallNextHookEx(NULL, nCode, wparam, lparam);
【讨论】:
我尝试了您的解决方案,但这不起作用!除此之外,这使我的 explorer.exe 每次安装挂钩时都会崩溃:这是代码:pastebin.com/X63H7zX8 它崩溃是因为您将 lparam 转换为 CREATESTRUCTW*。等待更新的答案。 另外两点需要用原始代码(不是你的)修复:1
HookProcedure
应该总是调用CallNextHookEx
- return 0;
语句会破坏其他代码。 2
lpszClass
不一定是指向字符串的指针;它也可以是ATOM
的类,需要检查。
@IInspectable 对于您的第一点,我认为 CBT_HOOK 是“特价商品”。见msdn.microsoft.com/en-us/library/windows/desktop/…第二点,他想记录lpszName,而不是lpszClass
CBT 钩子并不特别。 SetWindowsHookEx
中关于链接的规则仍然有效。 CBTProc
的返回值规则仅适用于您想积极参与窗口创建的情况。对于非侵入式监控,您应该始终调用CallNextHookEx
。以上是关于CBT_CREATEWND 结构的名称无效的主要内容,如果未能解决你的问题,请参考以下文章
收到无效的 JSON 有效负载。未知名称 click_action