⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lion-tutorial07.htm

📁 内有一些代码
💻 HTM
字号:
<html>

<head>
<link rel="stylesheet" href="../../asm.css">

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Iczelion's win32 asm tutorial</title>
</head>

<body bgcolor="#FFFFFF" background="../../images/back01.jpg">
<p align="center">Tutorial 7: Mouse Input</p>
<hr size="1">
We will learn how to receive and respond to mouse input in our window procedure. 
The example program will wait for left mouse clicks and display a text string 
at the exact clicked spot in the client area. 
<p>Download the example <a href="files/tut07.zip">here</a>. 
<h3> Theory:</h3>
As with keyboard input, Windows detects and sends notifications about mouse activities 
that are relevant to each window. Those activities include left and right clicks, 
mouse cursor movement over window, double clicks. Unlike keyboard input which 
is directed to the window that has input focus, mouse messages are sent to any 
window that the mouse cursor is over, active or not. In addition, there are mouse 
messages about the non-client area too. But most of the time, we can blissfully 
ignore them. We can focus on those relating to the client area. <br>
There are two messages for each mouse button: WM_LBUTTONDOWN,WM_RBUTTONDOWN and 
WM_LBUTTONUP, WM_RBUTTONUP messages. For a mouse with three buttons, there are 
also WM_MBUTTONDOWN and WM_MBUTTONUP. When the mouse cursor moves over the client 
area, Windows sends WM_MOUSEMOVE messages to the window under the cursor. <br>
A window can receive double click messages, WM_LBUTTONDBCLK or WM_RBUTTONDBCLK, 
<b><i>if and only if</i></b> its window class has CS_DBLCLKS style flag, else 
the window will receive only a series of mouse button up and down messages. <br>
For all these messages, the value of lParam contains the position of the mouse. 
The low word is the x-coordinate, and the high word is the y-coordinate relative 
to upper left corner of the client area of the window. wParam indicates the state 
of the mouse buttons and Shift and Ctrl keys. <br>
&nbsp; 
<h3> Example:</h3>
<b>.386</b> <br>
<b>.model flat,stdcall</b> <br>
<b>option casemap:none</b> 
<p><b>WinMain proto :DWORD,:DWORD,:DWORD,:DWORD</b> 
<p><b>include \masm32\include\windows.inc</b> <br>
  <b>include \masm32\include\user32.inc</b> <br>
  <b>include \masm32\include\kernel32.inc</b> <br>
  <b>include \masm32\include\gdi32.inc</b> <br>
  <b>includelib \masm32\lib\user32.lib</b> <br>
  <b>includelib \masm32\lib\kernel32.lib</b> <br>
  <b>includelib \masm32\lib\gdi32.lib</b> 
<p><b>.data</b> <br>
  <b>ClassName db "SimpleWinClass",0</b> <br>
  <b>AppName&nbsp; db "Our First Window",0</b> <br>
  <b>MouseClick db 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 0=no click 
  yet</b> 
<p><b>.data?</b> <br>
  <b>hInstance HINSTANCE ?</b> <br>
  <b>CommandLine LPSTR ?</b> <br>
  <b>hitpoint POINT &lt;></b> 
<p><b>.code</b> <br>
  <b>start:</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke GetModuleHandle, NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp; hInstance,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke GetCommandLine<br>
  &nbsp;&nbsp;&nbsp;&nbsp;mov CommandLine,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; invoke ExitProcess,eax</b> 
<p><b>WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL wc:WNDCLASSEX</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL msg:MSG</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL hwnd:HWND</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbSize,SIZEOF WNDCLASSEX</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.style, CS_HREDRAW or CS_VREDRAW</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.lpfnWndProc, OFFSET WndProc</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbClsExtra,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbWndExtra,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; push&nbsp; hInst</b> <br>
  <b>&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; wc.hInstance</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hbrBackground,COLOR_WINDOW+1</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.lpszMenuName,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.lpszClassName,OFFSET ClassName</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; invoke LoadIcon,NULL,IDI_APPLICATION</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hIcon,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hIconSm,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke LoadCursor,NULL,IDC_ARROW</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hCursor,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke RegisterClassEx, addr wc</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hInst,NULL</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; hwnd,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke ShowWindow, hwnd,SW_SHOWNORMAL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke UpdateWindow, hwnd</b> <br>
  <b>&nbsp;&nbsp;&nbsp; .WHILE TRUE</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  invoke GetMessage, ADDR msg,NULL,0,0</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  .BREAK .IF (!eax)</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  invoke DispatchMessage, ADDR msg</b> <br>
  <b>&nbsp;&nbsp;&nbsp; .ENDW</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp; eax,msg.wParam</b> <br>
  <b>&nbsp;&nbsp;&nbsp; ret</b> <br>
  <b>WinMain endp</b> 
<p><b>WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL hdc:HDC</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL ps:PAINTSTRUCT</b> 
<p><b>&nbsp;&nbsp;&nbsp; .IF uMsg==WM_DESTROY</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke PostQuitMessage,NULL</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; .ELSEIF uMsg==WM_LBUTTONDOWN</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov eax,lParam</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and eax,0FFFFh</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov hitpoint.x,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov eax,lParam</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shr eax,16</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov hitpoint.y,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov MouseClick,TRUE</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke InvalidateRect,hWnd,NULL,TRUE</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; .ELSEIF uMsg==WM_PAINT</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke BeginPaint,hWnd, ADDR ps</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp; hdc,eax</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .IF MouseClick</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
  lstrlen,ADDR AppName</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
  TextOut,hdc,hitpoint.x,hitpoint.y,ADDR AppName,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ENDIF</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke EndPaint,hWnd, ADDR ps</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; .ELSE</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke DefWindowProc,hWnd,uMsg,wParam,lParam</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret</b> <br>
  <b>&nbsp;&nbsp;&nbsp; .ENDIF</b> <br>
  <b>&nbsp;&nbsp;&nbsp; xor&nbsp;&nbsp;&nbsp; eax,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; ret</b> <br>
  <b>WndProc endp</b> <br>
  <b>end start</b> <br>
  &nbsp; 
<h3> Analysis:</h3>
<b>&nbsp;&nbsp;&nbsp; .ELSEIF uMsg==WM_LBUTTONDOWN</b> <br>
<b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov eax,lParam</b> <br>
<b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and eax,0FFFFh</b> <br>
<b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov hitpoint.x,eax</b> <br>
<b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov eax,lParam</b> <br>
<b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shr eax,16</b> <br>
<b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov hitpoint.y,eax</b> <br>
<b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov MouseClick,TRUE</b> <br>
<b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke InvalidateRect,hWnd,NULL,TRUE</b> 
<p>The window procedure waits for left mouse button click. When it receives WM_LBUTTONDOWN, 
  lParam contains the coordinate of the mouse cursor in the client area. It saves 
  the coordinate in a variable of type POINT which is defined as: 
<p><b>POINT STRUCT</b> <br>
  <b>&nbsp;&nbsp;&nbsp; x&nbsp;&nbsp; dd ?</b> <br>
  <b>&nbsp;&nbsp;&nbsp; y&nbsp;&nbsp; dd ?</b> <br>
  <b>POINT ENDS</b> 
<p>and sets the flag, MouseClick, to TRUE, meaning that there's at least a left 
  mouse button click in the client area. 
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov eax,lParam</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and eax,0FFFFh</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov hitpoint.x,eax</b> 
<p>Since x-coordinate is the low word of lParam and the members of POINT structure 
  are 32-bit in size, we have to zero out the high word of eax prior to storing 
  it in hitpoint.x. 
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shr eax,16</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov hitpoint.y,eax</b> 
<p>Because y-coordinate is the high word of lParam, we must put it in the low 
  word of eax prior to storing it in hitpoint.y. We do this by shifting eax 16 
  bits to the right. <br>
  After storing the mouse position, we set the flag, MouseClick, to TRUE in order 
  to let the painting code in WM_PAINT section know that there's at least a click 
  in the client area so it can draw the string at the mouse position. Next&nbsp; 
  we call InvalidateRect function to force the window to repaint its entire client 
  area. 
<p><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .IF MouseClick</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
  lstrlen,ADDR AppName</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
  TextOut,hdc,hitpoint.x,hitpoint.y,ADDR AppName,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ENDIF</b> 
<p>The painting code in WM_PAINT section must check if MouseClick is true, since 
  when the window was created, it received a WM_PAINT message which at that time, 
  no mouse click had occurred so it should not draw the string in the client area. 
  We initialize MouseClick to FALSE and change its value to TRUE when an actual 
  mouse click occurs. <br>
  If at least one mouse click has occurred, it draws the string in the client 
  area at the mouse position. Note that it calls lstrlen to get the length of 
  the string to display and sends the length as the last parameter of TextOut 
  function. 
<hr size="1">
<div align="center"> This article come from Iczelion's asm page, Welcom to <a href="http://asm.yeah.net">http://asm.yeah.net</a></div>

</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -