资源文件中,我为List-View控件设置了Report风格,No Sort Header为TRUE
代码中,先使用LVM_SETEXTENDEDLISTVIEWSTYLE设置了LVS_EX_FULLROWSELECT扩展风格,然后插入了行与列,都没有问题
父窗口接收WM_NOTIFY消息,弹出右键菜单
这样没法判断用户右击的是表头还是首行,右击表头一样弹出了右键菜单
所以现在在我的软件中,用户右击表头,也弹出了右键菜单
LordPE中主窗口也用到了List-View控件,但没有这样的问题。
我用OD调试LordPE,发现它的代码和我一样,只是比我多设置了LVS_EX_FLATSB扩展风格,这只是将滚动条扁平化。
调试的时候发现,同样是右击表头,我的程序里父窗口接收到了NM_RCLICK,而LordPE中却没有。
代码:
也就是说,LordPE里,右击表头,父窗口没有收到NM_RCLICK,而我的程序却收到了。
用PE-Explorer看了LordPE的资源,List-View控件的设置和我的一样,Report风格,NoSortHeader为TRUE
这里是演示程序,右击List-View控件,如果父窗口接到NM_RCLICK,则弹框显示。右击表头,MsgBox还是弹出来了
代码:
代码中,先使用LVM_SETEXTENDEDLISTVIEWSTYLE设置了LVS_EX_FULLROWSELECT扩展风格,然后插入了行与列,都没有问题
父窗口接收WM_NOTIFY消息,弹出右键菜单
代码:
.ELSEIF uMsg == WM_NOTIFY
mov esi,lParam
cmp dword ptr [esi+8],NM_RCLICK;这里只需要比较NMHDR.code是否为NM_RCLICK即可,因为这个窗口内只有这个List-View控件,没别的子窗口能向父窗口发送这样的消息
jne RetDlg
invoke GetCursorPos,offset @LVHI.pt
push @LVHI.pt.x
push @LVHI.pt.y
invoke ScreenToClient,hWnd,offset @LVHI.pt
invoke SendMessageW,[esi],LVM_HITTEST,0,offset @LVHI
.IF eax != -1
invoke Dw2HexW,eax,offset Buffer
invoke MessageBoxW,hWnd,offset Buffer,0,0;这两句只是为了看到LVM_HITTEST的返回值,运行的时候以MsgBox弹出来
invoke CreatePopupMenu
mov esi,eax
invoke AppendMenuW,esi,MF_STRING,0,offset SecTblMenu1
invoke AppendMenuW,esi,MF_STRING,0,offset SecTblMenu2
pop eax
pop ebx
invoke TrackPopupMenuEx,esi,TPM_LEFTALIGN + TPM_TOPALIGN,ebx,eax,hWnd,0
.EndIF
现在的问题是,比如List-View控件有三行,用户右击第一行,用于测试的MsgBox弹出的结果是0,第二行结果是1,第三行结果是2,右击表头,结果也是0
这样没法判断用户右击的是表头还是首行,右击表头一样弹出了右键菜单
所以现在在我的软件中,用户右击表头,也弹出了右键菜单
LordPE中主窗口也用到了List-View控件,但没有这样的问题。
我用OD调试LordPE,发现它的代码和我一样,只是比我多设置了LVS_EX_FLATSB扩展风格,这只是将滚动条扁平化。
调试的时候发现,同样是右击表头,我的程序里父窗口接收到了NM_RCLICK,而LordPE中却没有。
代码:
/*404964*/ MOV ESI,DWORD PTR SS:[EBP+0x14] ;Case 4E (WM_NOTIFY) of switch 004047F9 ;这里处理WM_NOTIFY消息,esi指向NMHDR结构
/*404967*/ CMP DWORD PTR DS:[ESI+0x4],0x3ED ;NMHDR.idFrom
/*40496E*/ JNZ LordPE.00404A19
/*404974*/ MOV EAX,DWORD PTR DS:[ESI+0x8];NMHDR.code
/*404977*/ CMP EAX,-0x65
/*40497A*/ JE SHORT LordPE.004049E1
/*40497C*/ CMP EAX,-0x5 ;NM_RCLICK
/*40497F*/ JNZ LordPE.00404A19
/*404985*/ MOV ECX,DWORD PTR DS:[ESI];这里开始处理NM_RCLICK
/*404987*/ PUSH ECX
/*404988*/ CALL LordPE.00401A10
/*40498D*/ ADD ESP,0x4
/*404990*/ CMP EAX,-0x1
/*404993*/ JE LordPE.00404A19
/*404999*/ CALL LordPE.004059C0
/*40499E*/ LEA EDX,DWORD PTR SS:[EBP-0x20]
/*4049A1*/ PUSH EDX
/*4049A2*/ CALL DWORD PTR DS:[<&USER32.GetCursorPos>]
/*4049A8*/ PUSH 0x0
/*4049AA*/ MOV EAX,DWORD PTR SS:[EBP+0x8]
/*4049AD*/ PUSH EAX
/*4049AE*/ PUSH 0x0
/*4049B0*/ MOV ECX,DWORD PTR SS:[EBP-0x1C]
/*4049B3*/ ADD ECX,-0xA
/*4049B6*/ PUSH ECX
/*4049B7*/ MOV EDX,DWORD PTR SS:[EBP-0x20]
/*4049BA*/ PUSH EDX
/*4049BB*/ PUSH 0x4
/*4049BD*/ MOV EAX,DWORD PTR DS:[0x41E750]
/*4049C2*/ PUSH EAX
/*4049C3*/ CALL DWORD PTR DS:[<&USER32.TrackPopupMenu>]
在404985下断,右击表头,断点没触发。右击项目,断点触发。
也就是说,LordPE里,右击表头,父窗口没有收到NM_RCLICK,而我的程序却收到了。
用PE-Explorer看了LordPE的资源,List-View控件的设置和我的一样,Report风格,NoSortHeader为TRUE
这里是演示程序,右击List-View控件,如果父窗口接到NM_RCLICK,则弹框显示。右击表头,MsgBox还是弹出来了
代码:
.686p
.model flat,stdcall
option casemap:none
include Windows.inc
include Strings.mac
include User32.inc
include NTDLL.inc
includelib User32.lib
includelib NTDLL.lib
.data?
@LVC LV_COLUMN <>
.code
assume fs:nothing
DlgProc Proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.IF uMsg == WM_INITDIALOG
invoke GetDlgItem,hWnd,1
mov @LVC.imask,LVCF_TEXT + LVCF_WIDTH
mov @LVC.lx,90
invoke SendMessageW,eax,LVM_INSERTCOLUMNW,0,offset @LVC
.ELSEIF uMsg == WM_NOTIFY
mov esi,lParam
.IF dword ptr [esi+8] == NM_RCLICK
invoke MessageBoxW,hWnd,$CTW0('NM_RCLICK'),0,0
.EndIF
.ELSEIF uMsg == WM_CLOSE
Exit:
invoke NtTerminateProcess,-1,0
.ENDIF
xor eax,eax
ret
DlgProc endp
Start:
mov edi,dword ptr fs:[18h]
mov edi,dword ptr [edi+30h]
mov edi,dword ptr [edi+8h]
invoke DialogBoxParamW,edi,1,0,offset DlgProc,0
end Start