首页
社区
课程
招聘
[求助]Win32ASM使用List-View控件的问题
发表于: 2014-2-20 15:26 3061

[求助]Win32ASM使用List-View控件的问题

2014-2-20 15:26
3061
资源文件中,我为List-View控件设置了Report风格,No Sort Header为TRUE
代码中,先使用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风格,No Sort Header为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


Demo.zip


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//