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

📄 lion-tutorial10.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 10: Dialog Box as Main Window</p>
<hr size="1">
Now comes the really interesting part about GUI, the dialog box. In this tutorial 
(and the next), we will learn how to use a dialog box as our main window. 
<p>Download the first example <a href="files/tut10-1.zip">here</a>, the second 
  example <a href="files/tut10-2.zip">here</a>. 
<h3> Theory:</h3>
If you play with the examples in the previous tutorial long enough, you 'll find 
out that you cannot change input focus from one child window control to another 
with Tab key. The only way you can do that is by clicking the control you want 
it to gain input focus. This situation is rather cumbersome. Another thing you 
might notice is that I changed the background color of the parent window to gray 
instead of normal white as in previous examples. This is done so that the color 
of the child window controls can blend seamlessly with the color of the client 
area of the parent window. There is a way to get around this problem but it's 
not easy. You have to subclass all child window controls in your parent window. 
<br>
The reason why such inconvenience exists is that child window controls are originally 
designed to work with a dialog box, not a normal window. The default color of 
child window controls such as a button is gray because the client area of a dialog 
box is normally gray so they blend into each other without any sweat on the programmer's 
part. <br>
Before we get deep into the detail, we should know first what a dialog box is. 
A dialog box is nothing more than a normal window which is designed to work with 
child window controls. Windows also provides internal "dialog box manager" which 
is responsible for most of the keyboard logic such as shifting input focus when 
the user presses Tab, pressing the default pushbutton if Enter key is pressed, 
etc so programmers can deal with higher level tasks. Dialog boxes are primarily 
used as input/output devices. As such a dialog box can be considered as an input/output 
"black box" meaning that you don't have to know how a dialog box works internally 
in order to be able to use it, you only have to know how to interact with it. 
That's a principle of object oriented programming (OOP) called information hiding. 
If the black box is *perfectly* designed, the user can make use of it without 
any knowledge on how it operates. The catch is that the black box must be perfect, 
that's hard to achieve in the real world. Win32 API is also designed as a black 
box too. <br>
Well, it seems we stray from our path. Let's get back to our subject. Dialog boxes 
are designed to reduce workload of a programmer. Normally if you put child window 
controls on a normal window, you have to subclass them and write keyboard logic 
yourself. But if you put them on a dialog box, it will handle the logic for you. 
You only have to know how to get the user input from the dialog box or how to 
send commands to it. <br>
A dialog box is defined as a resource much the same way as a menu. You write a 
dialog box template describing the characteristics of the dialog box and its controls 
and then compile the resource script with a resource editor. <br>
Note that all resources are put together in the same resource script file. You 
can use any text editor to write a dialog box template but I don't recommend it. 
You should use a resource editor to do the job visually since arranging child 
window controls on a dialog box is hard to do manually. Several excellent resource 
editors are available. Most of the major compiler suites include their own resource 
editors. You can use them to create a resource script for your program and then 
cut out irrelevant lines such as those related to MFC. <br>
There are two main types of dialog box: modal and modeless. A modeless dialog 
box lets you change input focus to other window. The example is the Find dialog 
of MS Word. There are two subtypes of modal dialog box: application modal and 
system modal. An application modal dialog box doesn't let you change input focus 
to other window in the same application but you can change the input focus to 
the window of <b>OTHER</b> application. A system modal dialog box doesn't allow 
you to change input focus to any other window until you respond to it first. <br>
A modeless dialog box is created by calling CreateDialogParam API function. A 
modal dialog box is created by calling DialogBoxParam. The only distinction between 
an application modal dialog box and a system modal one is the DS_SYSMODAL style. 
If you include DS_SYSMODAL style in a dialog box template, that dialog box will 
be a system modal one. <br>
You can communicate with any child window control on a dialog box by using SendDlgItemMessage 
function. Its syntax is like this: <br>
&nbsp; 
<blockquote><b>SendDlgItemMessage proto hwndDlg:DWORD,\</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; 
  idControl:DWORD,\</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; 
  uMsg:DWORD,\</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; 
  wParam:DWORD,\</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; 
  lParam:DWORD</b></blockquote>
This API call is immensely useful for interacting with a child window control. 
For example, if you want to get the text from an edit control, you can do this: 
<blockquote><b>call SendDlgItemMessage, hDlg, ID_EDITBOX, WM_GETTEXT, 256, ADDR 
  text_buffer</b></blockquote>
In order to know which message to send, you should consult your Win32 API reference. 
<br>
Windows also provides several control-specific API functions to get and set data 
quickly, for example, GetDlgItemText, CheckDlgButton etc. These control-specific 
functions are provided for programmer's convenience so he doesn't have to look 
up the meanings of wParam and lParam for each message. Normally, you should use 
control-specific API calls when they're available since they make source code 
maintenance easier. Resort to SendDlgItemMessage only if no control-specific API 
calls are available. <br>
The Windows dialog box manager sends some messages to a specialized callback function 
called a dialog box procedure which has the following format: 
<blockquote><b>DlgProc&nbsp; proto hDlg:DWORD ,\</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; 
  iMsg:DWORD ,\</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; 
  wParam:DWORD ,\</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; 
  lParam:DWORD</b></blockquote>
The dialog box procedure is very similar to a window procedure except for the 
type of return value which is TRUE/FALSE instead of LRESULT. The internal dialog 
box manager inside Windows <b>IS</b> the true window procedure for the dialog 
box. It calls our dialog box procedure with some messages that it received. So 
the general rule of thumb is that: if our dialog box procedure processes a message,it 
<b>MUST</b> return TRUE in eax and if it does not process the message, it must 
return FALSE in eax. Note that a dialog box procedure doesn't pass the messages 
it does not process to the DefWindowProc call since it's not a real window procedure. 
<br>
There are two distinct uses of a dialog box. You can use it as the main window 
of your application or use it as an input device. We 'll examine the first approach 
in this tutorial. <br>
"Using a dialog box as main window" can be interpreted in two different senses. 
<ol>
  <li> You can use the dialog box template as a class template which you register 
    with RegisterClassEx call. In this case, the dialog box behaves like a "normal" 
    window: it receives messages via a window procedure referred to by lpfnWndProc 
    member of the window class, not via a dialog box procedure. The benefit of 
    this approach is that you don't have to create child window controls yourself, 
    Windows creates them for you when the dialog box is created. Also Windows 
    handles the keyboard logic for you such as Tab order etc. Plus you can specify 
    the cursor and icon of your window in the window class structure.</li>
  <br>
  Your program just creates the dialog box without creating any parent window. 
  This approach makes a message loop unnecessary since the messages are sent directly 
  to the dialog box procedure. You don't even have to register a window class! 
</ol>
This tutorial is going to be a long one. I'll present the first approach followed 
by the second. 
<h3> Examples:</h3>
<hr width="100%">
<center>
  <b>dialog.asm</b> 
</center>
<hr width="100%">
<br>
<b>.386</b> <br>
<b>.model flat,stdcall</b> <br>
<b>option casemap:none</b> <br>
<b>WinMain proto :DWORD,:DWORD,:DWORD,:DWORD</b> <br>
<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>includelib \masm32\lib\user32.lib</b> <br>
<b>includelib \masm32\lib\kernel32.lib</b> 
<p><b>.data</b> <br>
  <b>ClassName db "DLGCLASS",0</b> <br>
  <b>MenuName db "MyMenu",0</b> <br>
  <b>DlgName db "MyDialog",0</b> <br>
  <b>AppName db "Our First Dialog Box",0</b> <br>
  <b>TestString db "Wow! I'm in an edit box now",0</b> 
<p><b>.data?</b> <br>
  <b>hInstance HINSTANCE ?</b> <br>
  <b>CommandLine LPSTR ?</b> <br>
  <b>buffer db 512 dup(?)</b> 
<p><b>.const</b> <br>
  <b>IDC_EDIT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; equ 3000</b> <br>
  <b>IDC_BUTTON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; equ 3001</b> <br>
  <b>IDC_EXIT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; equ 3002</b> <br>
  <b>IDM_GETTEXT&nbsp;&nbsp;&nbsp;&nbsp; equ 32000</b> <br>
  <b>IDM_CLEAR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; equ 32001</b> <br>
  <b>IDM_EXIT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; equ 32002</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 hDlg: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,DLGWINDOWEXTRA</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_BTNFACE+1</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.lpszMenuName,OFFSET MenuName</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 CreateDialogParam,hInstance,ADDR DlgName,NULL,NULL,NULL</b> 

⌨️ 快捷键说明

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