📄 tut10.html
字号:
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Iczelion">
<meta name="GENERATOR" content="Mozilla/4.51 [en] (Win95; I) [Netscape]">
<title>Iczelion's Win32 Assembly Tutorial 10: Dialog Box as Main Window</title>
</head>
<body text="#FFFFFF" bgcolor="#000000" link="#FFFF00" vlink="#C0C0C0" alink="#C0FFC0">
<center>
<h1>
<font face="Arial,Helvetica"><font color="#999900"><font size=+2>Tutorial
10: Dialog Box as Main Window</font></font></font></h1></center>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font 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.</font></font></font>
<p><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>Download
the first example <a href="files/tut10-1.zip">here</a>, the second example
<a href="files/tut10-2.zip">here</a>.</font></font></font>
<h3>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=+0>Theory:</font></font></font></h3>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>You
can communicate with any child window control on a dialog box by using
SendDlgItemMessage function. Its syntax is like this:</font></font></font>
<br>
<blockquote><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>SendDlgItemMessage
proto hwndDlg:DWORD,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
idControl:DWORD,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
uMsg:DWORD,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
wParam:DWORD,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
lParam:DWORD</font></font></font></b></blockquote>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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:</font></font></font>
<blockquote><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>call
SendDlgItemMessage, hDlg, ID_EDITBOX, WM_GETTEXT, 256, ADDR text_buffer</font></font></font></b></blockquote>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>In order
to know which message to send, you should consult your Win32 API reference.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>The
Windows dialog box manager sends some messages to a specialized callback
function called a dialog box procedure which has the following format:</font></font></font>
<blockquote><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>DlgProc
proto hDlg:DWORD ,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
iMsg:DWORD ,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
wParam:DWORD ,\</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
lParam:DWORD</font></font></font></b></blockquote>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>"Using
a dialog box as main window" can be interpreted in two different senses.</font></font></font>
<ol>
<li>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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.</font></font></font></li>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>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!</font></font></font></ol>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>This tutorial
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -