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

📄 lion-tutorial03.htm

📁 内有一些代码
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<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 3: A Simple Window</p>
<hr size="1">
In this tutorial, we will build a Windows program that displays a fully functional 
window on the desktop. <br>
Download the example file <a href="files/tut03.zip">here</a> 
<h3> Theory:</h3>
Windows programs rely heavily on API functions for their GUI. This approach benefits 
both users and programmers. For users, they don't have to learn how to navigate 
the GUI of each new programs, the GUI of Windows programs are alike. For programmers, 
the GUI codes are already there,tested, and ready for use. The downside for programmers 
is the increased complexity involved. In order to create or manipulate any GUI 
objects such as windows, menu or icons, programmers must follow a strict recipe. 
But that can be overcome by modular programming or OOP paradigm. <br>
I'll outline the steps required to create a window on the desktop below: 
<ol>
  <li> Get the instance handle of your program (required)</li>
  <li> Get the command line (not required unless your program wants to process 
    a command line)</li>
  <li> Register window class (required ,unless you use predefined window types, 
    eg. MessageBox or a dialog box)</li>
  <li> Create the window (required)</li>
  <li> Show the window on the desktop (required unless you don't want to show 
    the window immediately)</li>
  <li> Refresh the client area of the window</li>
  <li> Enter an infinite loop, checking for messages from Windows</li>
  <li> If messages arrive, they are processed by a specialized function that is 
    responsible for the window</li>
  <li> Quit program if the user closes the window</li>
</ol>
As you can see, the structure of a Windows program is rather complex compared 
to a DOS program. But the world of Windows is drastically different from the world 
of DOS. Windows programs must be able to coexist peacefully with each other. They 
must follow stricter rules. You, as a programmer, must also be more strict with 
your programming style and habit. 
<h3> Content:</h3>
Below is the source code of our simple window program. Before jumping into the 
gory details of Win32 ASM programming, I'll point out some fine points which will 
ease your programming. 
<ul>
  <li> You should put all Windows constants, structures and function prototypes 
    in an include file and include it at the beginning of your .asm file. It'll 
    save you a lot of effort and typo. Currently, the most complete include file 
    for MASM is hutch's windows.inc which you can download from his page or my 
    page. You can also define your own constants &amp; structure definitions but 
    you should put them into a separate include file.</li>
  <li> Use includelib directive to specify the import library used in your program. 
    For example, if your program calls MessageBox, you should put the line:</li>
  <ul>
    includelib user32.lib 
  </ul>
  at the beginning of your .asm file. This directive tells MASM that your program 
  will make uses of functions in that import library. If your program calls functions 
  in more than one library, just add an includelib for each library you use. Using 
  IncludeLib directive, you don't have to worry about import libraries at link 
  time. You can use /LIBPATH linker switch to tell Link where all the libs are. 
  <li> When declaring API function prototypes, structures, or constants in your 
    include file, try to stick to the original names used in Windows include files, 
    including case. This will save you a lot of headache when looking up some 
    item in Win32 API reference.</li>
  <li> Use makefile to automate your assembling process. This will save you a 
    lot of typing.</li>
</ul>
<b>.386</b> <br>
<b>.model flat,stdcall</b> <br>
<b>option casemap:none</b> <br>
<b>include \masm32\include\windows.inc</b> <br>
<b>include \masm32\include\user32.inc</b> <br>
<b>includelib \masm32\lib\user32.lib&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
; calls to functions in user32.lib and kernel32.lib</b> <br>
<b>include \masm32\include\kernel32.inc</b> <br>
<b>includelib \masm32\lib\kernel32.lib</b> 
<p><b>WinMain proto :DWORD,:DWORD,:DWORD,:DWORD</b> 
<p><b>.DATA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; initialized data</b> <br>
  <b>ClassName db "SimpleWinClass",0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; the name of our window class</b> <br>
  <b>AppName db "Our First Window",0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; the name of our window</b> 
<p><b>.DATA?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; Uninitialized data</b> <br>
  <b>hInstance HINSTANCE ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; Instance 
  handle of our program</b> <br>
  <b>CommandLine LPSTR ?</b> <br>
  <b>.CODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; Here begins our code</b> <br>
  <b>start:</b> <br>
  <b>invoke GetModuleHandle, NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; get the instance handle of our program.</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; Under Win32, hmodule==hinstance mov hInstance,eax</b> <br>
  <b>mov hInstance,eax</b> <br>
  <b>invoke GetCommandLine&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; get the command line. You don't have to call this function IF</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; your program doesn't process the command line.</b> <br>
  <b>mov CommandLine,eax</b> <br>
  <b>invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; call the main function</b> <br>
  <b>invoke ExitProcess, eax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; quit our program. The exit code is returned in eax from WinMain.</b> 
<p><b>WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL wc:WNDCLASSEX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; create local variables on stack</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL msg:MSG</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL hwnd:HWND</b> 
<p><b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbSize,SIZEOF WNDCLASSEX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; fill values in members of wc</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; hInstance</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&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; register our window class</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke CreateWindowEx,NULL,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ADDR ClassName,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ADDR AppName,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  WS_OVERLAPPEDWINDOW,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  CW_USEDEFAULT,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  CW_USEDEFAULT,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  CW_USEDEFAULT,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  CW_USEDEFAULT,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  NULL,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  NULL,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  hInst,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; hwnd,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke ShowWindow, hwnd,CmdShow&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; display our window on desktop</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke UpdateWindow, hwnd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; refresh the client area</b> 
<p><b>&nbsp;&nbsp;&nbsp; .WHILE TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; Enter message loop</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 TranslateMessage, ADDR msg</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; .ENDW</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp; eax,msg.wParam&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; return exit code in eax</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; .IF uMsg==WM_DESTROY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; if the user closes our window</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke PostQuitMessage,NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; quit our application</b> <br>
  <b>&nbsp;&nbsp;&nbsp; .ELSE</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke DefWindowProc,hWnd,uMsg,wParam,lParam&nbsp;&nbsp;&nbsp;&nbsp; 
  ; Default message processing</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 eax,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; ret</b> <br>
  <b>WndProc endp</b> 
<p><b>end start</b> 
<h3> Analysis:</h3>
You may be taken aback that a simple Windows program requires so much coding. 
But most of those codes are just *template* codes that you can copy from one source 
code file to another. Or if you prefer, you could assemble some of these codes 
into a library to be used as prologue and epilogue codes. You can write only the 
codes in WinMain function. In fact, this is what&nbsp; C compilers do. They let 
you write WinMain codes without worrying about other housekeeping chores. The 
only catch is that you must have a function named WinMain else C compilers will 
not be able to combine your codes with the prologue and epilogue. You do not have 
such restriction with assembly language. You can use any function name instead 
of WinMain or no function at all. <br>
Prepare yourself. This's going to be a long, long tutorial. Let's analyze this 

⌨️ 快捷键说明

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