Winapi 如何在Win32中从NM_CUSTOMDRAW消息中提取颜色?
我从x86程序(MSVS 2017)中获得了一个带有WH_CALLWNDPROC的挂钩dll。守则如下:Winapi 如何在Win32中从NM_CUSTOMDRAW消息中提取颜色?,winapi,windows-messages,Winapi,Windows Messages,我从x86程序(MSVS 2017)中获得了一个带有WH_CALLWNDPROC的挂钩dll。守则如下: extern“C”\uuu declspec(dllexport)LRESULT SysMessageProc(int-nCode,WPARAM-WPARAM,LPARAM-LPARAM) { if(nCodeHWND; 字符wclass[256];wclass[0]=0; 如果(GetClassNameA(hWnd,wclass,255)!=0){ if(pCWP->message==WM
extern“C”\uuu declspec(dllexport)LRESULT SysMessageProc(int-nCode,WPARAM-WPARAM,LPARAM-LPARAM)
{
if(nCode<0)返回CallNextHookEx(NULL、nCode、wParam、lParam);
如果(nCode==HC\U动作){
CWPSTRUCT*pCWP=(CWPSTRUCT*)LPRAM;
HWND HWND=pCWP->HWND;
字符wclass[256];wclass[0]=0;
如果(GetClassNameA(hWnd,wclass,255)!=0){
if(pCWP->message==WM_NOTIFY&&(strcmp(wclass,“SysHeader32”)==0|strcmp(wclass,“SysListView32”)==0)){
//LPNMLISTVIEW pnm=(LPNMLISTVIEW)pCWP->LPRAM;
//pnm->lParam始终为0
NMHDR*hdr=(NMHDR*)pCWP->lParam;
如果((int)hdr->code==NM_CUSTOMDRAW){
字符输出[256];输出[0]=0;
斯普林特福斯(out,255,
“类:'%s',hWnd:%08X,消息:%08X,ptr:%08X,HDR[%08X,%i,%i]\n”,
wclass,(UINT)hWnd,pCWP->message,(UINT)pCWP->lParam,
(UINT)hdr->hwndFrom,hdr->idFrom,(int)hdr->code;
文件*流;
如果(fopen_s(&stream,“F:\\tmp\\\\u dll\\out.txt”,“a+”==0){
fprintf(流,输出);
fclose(流);
}
//如何获得
//LPNMLVCUSTOMDRAW lplvcd=???;
//lplvcd->clrFace,lplvcd->clrText,lplvcd->clrTextBk???
}
}
}
当我记录消息时,得到的结果与Spy++中的结果相同:
CWPSTRUCT*pCWP=(CWPSTRUCT*)lParam;
HWND HWND=pCWP->HWND;
UINT msg=pCWP->消息;
字符wclass[256];wclass[0]=0;
如果(RealGetWindowClassA(hWnd,wclass,255)!=0){
if(msg==WM_NOTIFY&(strcmp(wclass,“SysHeader32”)==0 | | strcmp(wclass,“SysListView32”)==0)){
NMHDR*hdr=(NMHDR*)pCWP->lParam;
如果(hdr->code==NM\U CUSTOMDRAW){
if(strcmp(wclass,“SysListView32”)==0){
LPNMLVCUSTOMDRAW lplvcd=(LPNMLVCUSTOMDRAW)pCWP->lpram;
中频(lplvcd){
RECT r=lplvcd->rcText;
字符输出[512];输出[0]=0;
斯普林特福斯(out,511,
类别:'%s',hWnd:%08X,消息:%08X,ptr:%08X\
绘图:%08X,矩形:(%i,%i)-(%i,%i),面:%08X,文本:%08X,txtBg:%08X\n“,
W类,(UINT)hWnd,msg,(UINT)lplvcd,
lplvcd->nmcd.dwDrawStage,右左,右上,右右下,
lplvcd->clrFace,lplvcd->clrText,lplvcd->clrTextBk);
文件*流;
如果(fopen_s(&stream,“F:\\tmp\\\\u dll\\out.txt”,“a+”==0){
fprintf(流,输出);
fclose(流);
}
}
}
示例输出:
类:“SysListView32”,hWnd:000A04F4,消息:0000004E,ptr:02E3F33C,
绘图:00000001,矩形:(0,1)-(-124144237948493508),面:FFB617B5,
txt:02E3F400,txtBg:6F010726
您正在从错误的
lParam
访问NMLVCUSTOMDRAW
在a中,wParam
始终为0,lParam
为a,但您将其转换为,这是错误的。在NM\u CUSTOMDRAW
中没有提供NMLISTVIEW
。即使有,NMLISTVIEW::lParam
字段也包含应用程序设置的ListView项的用户定义数据这不是你想要的
您需要将pCWP->lParam
直接强制转换为NMLVCUSTOMDRAW*
。并且仅适用于SysListView32
控件。SysHeader32
控件使用,例如:
if(pCWP->message==WM\u NOTIFY){
...
NMHDR*hdr=(NMHDR*)pCWP->lParam;
...
如果(hdr->code==NM\U CUSTOMDRAW){
if(strcmp(wclass,“SysListView32”)==0){
LPNMLVCUSTOMDRAW lplvcd=(LPNMLVCUSTOMDRAW)pCWP->lpram;
//根据需要使用lplvcd。。。
}
else if(strcmp(wclass,“SysHeader32”)==0){
LPNMCUSTOMDRAW lpcd=(LPNMCUSTOMDRAW)pCWP->LPRAM;
//根据需要使用lpcd。。。
}
...
}
}
通用的文档说明了哪种类型的自定义可绘制控件使用哪种结构。有5种可能:
您正在从错误的
lParam
访问NMLVCUSTOMDRAW
在a中,wParam
始终为0,lParam
为a,但您将其转换为,这是错误的。在NM\u CUSTOMDRAW
中没有提供NMLISTVIEW
。即使有,NMLISTVIEW::lParam
字段也包含应用程序设置的ListView项的用户定义数据这不是你想要的
您需要将pCWP->lParam
直接强制转换为NMLVCUSTOMDRAW*
。并且仅适用于SysListView32
控件。SysHeader32
控件使用,例如:
if(pCWP->message==WM\u NOTIFY){
...
NMHDR*hdr=(NMHDR*)pCWP->lParam;
...
如果(hdr->code==NM\U CUSTOMDRAW){
if(strcmp(wclass,“SysListView32”)==0){
LPNMLVCUSTOMDRAW lplvcd=(LPNMLVCUSTOMDRAW)pCWP->lpram;
LPNMLISTVIEW pnm = (LPNMLISTVIEW)pCWP->lParam;
...
LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)pnm->lParam;
...
print(lplvcd->clrFace, lplvcd->clrText, lplvcd->clrTextBk);