WIN32汇编: 7.处理鼠标输入消息

原创 2001年06月17日 20:16:00

第七课 处理鼠标输入消息


本课中我们将学习如何在我们的窗口过程函数中处理鼠标按键消息。示例程序演示了如何等待左键按下消息,我们将在按下的位置显示一个字符串。

理论:

和处理键盘输入一样,WINDOWS将捕捉鼠标动作并把它们发送到相关窗口。这些活动包括左、右键按下、移动、双击等(译者注:新式鼠标还包括滚轮消息WM_WHEEL)。WINDOWS并不像处理键盘输入那样把所有的鼠标消息都导向有输入焦点的窗口,任何鼠标经过的窗口都将接收到鼠标消息,无论有否输入焦点。另外,窗口还会接收到鼠标在非客户区移动的消息(WM_NCMOVE),但大多数的情况下我们都会将其忽略掉。 对鼠标的每一个按钮都有两个消息:WM_LBUTTONDOWN,WM_RBUTTONDOWN 。对于三键鼠标还会有WM_MBUTTONDOWN和WM_MBUTTONUP消息,当鼠标在某窗口客户区移动时,该窗口将接收到WM_MOUSEMOVE消息。一个窗口若想处理WM_LBUTTONDBCLK或 WM_RBUTTONDBCLK,那么它的窗口类必须有CS_DBLCLKS风格,否则它就会接受到一堆的按键起落(WM_XBUTTONDOWN或WM_XBUTTONUP)的消息。 对于所有的消息,窗口过程函数传入的参数lParam包含了鼠标的位置,其中底位为x坐标,高位为y坐标,这些坐标值都是相对于窗口客户区的左上角的值,wParam中则包含了鼠标按钮的状态。
 

例子:

.386
.model flat,stdcall
option casemap:none

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

include /masm32/include/windows.inc
include /masm32/include/user32.inc
include /masm32/include/kernel32.inc
include /masm32/include/gdi32.inc
includelib /masm32/lib/user32.lib
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/gdi32.lib

.data
ClassName db "SimpleWinClass",0
AppName  db "Our First Window",0
MouseClick db 0         ; 0=no click yet

.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hitpoint POINT <>

.code
start:
    invoke GetModuleHandle, NULL
    mov    hInstance,eax
    invoke GetCommandLine
    mov CommandLine,eax

    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
    invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hwnd:HWND
    mov   wc.cbSize,SIZEOF WNDCLASSEX
    mov   wc.style, CS_HREDRAW or CS_VREDRAW
    mov   wc.lpfnWndProc, OFFSET WndProc
    mov   wc.cbClsExtra,NULL
    mov   wc.cbWndExtra,NULL
    push  hInst
    pop   wc.hInstance
    mov   wc.hbrBackground,COLOR_WINDOW+1
    mov   wc.lpszMenuName,NULL
    mov   wc.lpszClassName,OFFSET ClassName
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov   wc.hIcon,eax
    mov   wc.hIconSm,eax
    invoke LoadCursor,NULL,IDC_ARROW
    mov   wc.hCursor,eax
    invoke RegisterClassEx, addr wc
    invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,/
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,/
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,/
           hInst,NULL
    mov   hwnd,eax
    invoke ShowWindow, hwnd,SW_SHOWNORMAL
    invoke UpdateWindow, hwnd
    .WHILE TRUE
                invoke GetMessage, ADDR msg,NULL,0,0
                .BREAK .IF (!eax)
                invoke DispatchMessage, ADDR msg
    .ENDW
    mov     eax,msg.wParam
    ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    LOCAL hdc:HDC
    LOCAL ps:PAINTSTRUCT

    .IF uMsg==WM_DESTROY
        invoke PostQuitMessage,NULL
    .ELSEIF uMsg==WM_LBUTTONDOWN
        mov eax,lParam
        and eax,0FFFFh
        mov hitpoint.x,eax
        mov eax,lParam
        shr eax,16
        mov hitpoint.y,eax
        mov MouseClick,TRUE
        invoke InvalidateRect,hWnd,NULL,TRUE
    .ELSEIF uMsg==WM_PAINT
        invoke BeginPaint,hWnd, ADDR ps
        mov    hdc,eax
        .IF MouseClick
            invoke lstrlen,ADDR AppName
            invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR AppName,eax
        .ENDIF
        invoke EndPaint,hWnd, ADDR ps
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .ENDIF
    xor    eax,eax
    ret
WndProc endp
end start
 

分析:

    .ELSEIF uMsg==WM_LBUTTONDOWN
        mov eax,lParam
        and eax,0FFFFh
        mov hitpoint.x,eax
        mov eax,lParam
        shr eax,16
        mov hitpoint.y,eax
        mov MouseClick,TRUE
        invoke InvalidateRect,hWnd,NULL,TRUE

窗口过程处理了WM_LBUTTONDOWN消息,当接收到该消息时,lParam中包含了相对于窗口客户区左上角的坐标,我们把它保存下来,放到一个结构体变量(POINT)中,该结构体变量的定义如下:

POINT STRUCT
    x   dd ?
    y   dd ?
POINT ENDS

然后我们把标志量MouseClick设为TRUE,这表明至少有一次在客户区的左键按下消息。

        mov eax,lParam
        and eax,0FFFFh
        mov hitpoint.x,eax

由于lParam是一个32位长的数,其中高、底16位分别包括了x、y坐标所以我们做一些小处理,以便保存它们。

        shr eax,16
        mov hitpoint.y,eax
保存完坐标后我们设标志MouseClick为TRUE,这是在处理WM_PAINT时用来判断是否有鼠标左键按下消息。然后我们调用InvalidateRect()函数迫使WINDOWS重新绘制客户区。

        .IF MouseClick
            invoke lstrlen,ADDR AppName
            invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR AppName,eax
        .ENDIF

绘制客户区的代码首先检测MouseClick标志位,再决定是否重绘。因为我们在首次显示窗口时还没有左键按下的消息,所以我们在初始时把该标志设为FALSE,告诉WINDOWS不要重绘客户区,当有左键按下的消息时,它会在鼠标按下的位置绘制字符串。注意在调用TextOut()函数时,其关于字符串长度的参数是调用lstrlen()函数来计算的。

OnMouseHover()和OnMouseLeave()(让窗口捕获并响应WM_MOUSEHOVER和WM_MOUSELEAVE消息)

当鼠标停留在程序窗口一定时间后,会产生一个WM_MOUSEHOVER消息;当鼠标离开程序窗口后,会产生一个WM_MOUSELEAVE消息。那如何才能使窗口响应这两个消息呢?按下面的步骤,即可让指定的窗...
  • qq125096885
  • qq125096885
  • 2015年04月08日 14:44
  • 532

WIN32学习——鼠标消息

1 基本鼠标消息     WM_LBUTTONDOWN - 鼠标左键按下     WM_LBUTTONUP - 鼠标左键抬起     WM_RBUTTONDOWN - 鼠标右键按下     W...
  • bimabushihaodongxi
  • bimabushihaodongxi
  • 2017年04月29日 00:47
  • 278

【旧资料整理】8086汇编 鼠标操作

资料时间:2009-12-02之前 分享时间:2009-12-02到百度空间,空间关闭,重新整理 以前做实验时,需要操作鼠标。在emu8086下,鼠标操作时会出现一个白色的方块,在dos下...
  • jlusuoya
  • jlusuoya
  • 2017年06月24日 12:20
  • 152

Win32汇编获取窗体的mousehover消息

默认情况下Windows窗体是不会响应WM_MOUSELEAVE和WM_MOUSEHOVER消息的,通过使用_TrackMouseEvent这个函数可以激活这两个消息。在调用这个函数后,当鼠标在指定窗...
  • lixiang19910909
  • lixiang19910909
  • 2015年09月11日 16:01
  • 525

WIN32汇编: 7.处理鼠标输入消息

第七课 处理鼠标输入消息本课中我们将学习如何在我们的窗口过程函数中处理鼠标按键消息。示例程序演示了如何等待左键按下消息,我们将在按下的位置显示一个字符串。 理论:和处理键盘输入一样,WINDOWS将捕...
  • GodDragon
  • GodDragon
  • 2001年06月17日 20:16
  • 919

Win32窗口鼠标消息

这一课,我们学习如何来处理鼠标消息。在Win32环境下,处理任何消息都很简单,消息循环会保证任何发生在进程内的消息都会送到消息处理回调函数中处理,我们只需在那个swtich 结构中case我们感兴趣的...
  • mousebaby808
  • mousebaby808
  • 2010年01月31日 16:27
  • 10120

[Win32]Win32 SDK编程系列文章——鼠标输入消息

理论 和处理键盘输入一样,WINDOWS将捕捉鼠标动作并把它们发送到相关窗口。这些活动包括左、右键按下、移动、双击新式鼠标还包括滚轮消息WM_WHEEL等。WINDOWS并不像处理键盘输入那样把...
  • ouyangshima
  • ouyangshima
  • 2013年06月05日 20:03
  • 1247

WM_MOUSELEAVE和WM_MOUSEHOVER消息

一个是鼠标离开窗口消息,一个是鼠标停在窗口上的消息; 使用TrackMouseEvent函数可为窗口设置消息,当一次WM_MOUSELEAVE或WM_MOUSEHOVER消息 触发事TrackMo...
  • luojianshu1
  • luojianshu1
  • 2015年03月11日 21:04
  • 189

关于MFC中WM_MOUSEHOVER和WM_MOUSELEAVE消息的使用

默认情况下,窗口是不响应WM_MOUSELEAVE和WM_MOUSEHOVER消息的,所以要使用_TrackMouseEvent函数来激活这两个消息。调用这个函数后,当鼠标在指定窗口上停留超过一定时间...
  • zjccsg
  • zjccsg
  • 2016年07月16日 20:01
  • 177

Win32学习笔记 - Windows 常用消息大全

表A-1  Windows消息分布 消息范围 说 明 0 ~ WM_USER – 1 系统消息 WM_...
  • u011471873
  • u011471873
  • 2016年03月07日 20:36
  • 1312
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WIN32汇编: 7.处理鼠标输入消息
举报原因:
原因补充:

(最多只允许输入30个字)