Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 如何在Win32中从NM_CUSTOMDRAW消息中提取颜色?_Winapi_Windows Messages - Fatal编程技术网

Winapi 如何在Win32中从NM_CUSTOMDRAW消息中提取颜色?

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

我从x86程序(MSVS 2017)中获得了一个带有WH_CALLWNDPROC的挂钩dll。守则如下:

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++中的结果相同:

  • 奇怪的是,hdr->code是UINT,NM_CUSTOMDRAW=-12,所以我必须转换为(int),但结果与Spy++的输出相匹配

  • 起初我认为我可以做到这一点:

  • 但是pnm->lParam始终为零;pCWP->wParam也为零

  • 如何访问LPNMLISTVIEW和LPNMLVCUSTOMDRAW结构
  • 编辑:

    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);