Win32汇编学习(7):鼠标输入消息
这次我们将学习如何在我们的窗口过程函数中处理鼠标按键消息。例子演示了如何等待鼠标左键按下消息,我们将在按下的位置显示一个字符串。
理论:
和处理键盘输入一样,WINDOWS将捕捉鼠标动作并把它们发送到相关窗口。这些活动包括左、右键按下、移动、双击、滚轮消息WM_WHEEL
等。WINDOWS并不像处理键盘输入那样把所有的鼠标消息都导向有输入焦点的窗口,任何鼠标经过的窗口都将接收到鼠标消息,无论有否输入焦点。另外,窗口还会接收到鼠标在非客户区移动的消息(WM_NCMOVE
),但大多数的情况下我们都会将其忽略掉。当鼠标在某窗口客户区移动时,该窗口将接收到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
.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位分别包括了y、x坐标所以我们做一些小处理,以便保存它们。
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
函数来计算的。
Win32汇编学习(7):鼠标输入消息的更多相关文章
- 【Visual C++】游戏编程学习笔记之八:鼠标输入消息(小demo)
本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder 微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...
- Win32汇编学习(4):绘制文本
这次,我们将学习如何在窗口的客户区"绘制"字符串.我们还将学习关于"设备环境"的概念. 理论: "绘制"字符串 Windows 中的文本是一 ...
- Win32汇编学习(5):绘制文本2
这次我们将学习有关文本的诸多属性如字体和颜色等. 理论: Windows 的颜色系统是用RGB值来表示的,R 代表红色,G 代表绿色,B 代表蓝色.如果您想指定一种颜色就必须给该颜色赋相关的 RGB ...
- Win32汇编学习(1):基本概念
背景知识 Windows 把每一个 Win32 应用程序放到分开的虚拟地址空间中去运行,也就是说每一个应用程序都拥有其相互独立的 4GB 地址空间,当然这倒不是说它们都拥有 4GB 的物理地址空间,而 ...
- Win32汇编学习(6):键盘输入消息
这次,我们将要学习WINDOWS程序是如何处理键盘消息的. 理论: 因为大多数的PC只有一个键盘,所以所有运行中的WINDOWS程序必须共用它.WINDOWS 将负责把击键消息送到具有输入焦点的那个应 ...
- win32 汇编学习(2):消息框
这一次,我们将用汇编语言写一个 Windows 程序,程序运行时将弹出一个消息框并显示"你好,我的第一个Win32汇编程序". 理论知识 Windows 为编写应用程序提供了大量的 ...
- Win32汇编学习(10):对话框(1)
现在我们开始学习一些有关GUI编程的有趣的部分:以对话框为主要界面的应用程序. 理论: 如果您仔细关注过前一个程序就会发现:您无法按TAB键从一个子窗口控件跳到另一个子窗口控件,要想转移的话只有 用鼠 ...
- Win32汇编学习(3):简单的窗口
这次我们将写一个 Windows 程序,它会在桌面显示一个标准的窗口,以此根据代码来学习如何创建一个简单的窗口. 理论: Windows 程序中,在写图形用户界面时需要调用大量的标准 Windows ...
- Win32汇编学习(11):对话框(2)
我们将进一步学习对话框,探讨如何把对话框当成输入设备.如果您看了前一篇文章,那就会发现这次的例子只有少量的改动,就是把我们的对话框窗口附属到主窗口上.另外,我们还要学习通用对话框的用法. 理论: 把对 ...
随机推荐
- Gym 101810
友情提示: 这篇题解并没有GJKL,因为我也不会,而且看别人代码也看不懂,而且问学长还不给我讲!hmc:这个题巨麻烦,我只能说balabala.我不学了我退役了啊! A:这傻逼题我从开头wa了四个小时 ...
- react+mobx 编写 withStoreHistory 装饰器
主要作用是向store里面注入一个history对象,方便story里面的函数调用 function withStoreHistory(storeName) { if (!storeName) ret ...
- react+mobx 编写 Async装饰器
使用 // indexStore.js import axios from "axios"; import { from } from "rxjs"; impo ...
- luke下载使用
网上内容太多,下载了却不管用,即使下载了,也不知道怎么用.(对我这种小白来说,大神就一笑而过吧) 下载地址:http://www.xdowns.com/app/253909.html(如若下载不到可以 ...
- hdu 4544——消灭兔子
游戏规则很简单,用箭杀死免子即可. 箭是一种消耗品,已知有M种不同类型的箭可以选择,并且每种箭都会对兔子造成伤害,对应的伤害值分别为Di(1 <= i <= M),每种箭需要一定的QQ币 ...
- layer loading层 的设置
/* shadeClose 类型:Boolean 默认:true,是否点击遮罩时关闭层 */ var tishi = layer.open({ shadeClose: false ,type: 2 , ...
- 班级作业:Java Web环境的搭建
Java Web环境的搭建 一.开发所需工具.(根据你的电脑以及系统选择合适的版本下载) 1.JDK .下载链接:https://www.oracle.com/technetwork/java/jav ...
- 可视化&地图__公司收集
原文地址:https://github.com/zhongcaiwei/Data-visualization-technology-sharing 一.数据可视化企业(部分) 数字冰雹 光启元-腾讯 ...
- 亿图图示 Edraw Max v9.2 完美破解版
主程序:http://www.edrawsoft.cn/2download/edrawmax-cn-9.2.exe破解补丁:https://www.lanzous.com/i1fjsyh 密码:52p ...
- Unable to convert MySQL date/time value to System.DateTime问题解决方案
原因:可能是该字段(date/datetime)的值默认缺省值为:0000-00-00/0000-00-00 00:00:00,这样的数据读出来转换成System.DateTime时就会有问题: 解决 ...