Win32ASM使用List-View控件的问题

资源文件中,我为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风格,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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值