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

📄 ch03.htm

📁 Learning language of Visual C++6
💻 HTM
📖 第 1 页 / 共 3 页
字号:
		<TD ALIGN="LEFT">Control Panel application		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">DBT		</TD>
		<TD ALIGN="LEFT">Any application (device change message)		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">DL		</TD>
		<TD ALIGN="LEFT">Drag list box		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">DM		</TD>
		<TD ALIGN="LEFT">Dialog box		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">EM, EN		</TD>
		<TD ALIGN="LEFT">Edit box		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">FM, FMEVENT		</TD>
		<TD ALIGN="LEFT">File Manager		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">HDM, HDN		</TD>
		<TD ALIGN="LEFT">Header control		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">HKM		</TD>
		<TD ALIGN="LEFT">HotKey control		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">IMC, IMN		</TD>
		<TD ALIGN="LEFT">IME window		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">LB, LBN		</TD>
		<TD ALIGN="LEFT">List box		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">LVM, LVN		</TD>
		<TD ALIGN="LEFT">List view		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">NM		</TD>
		<TD ALIGN="LEFT">Any parent window (notification message)		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">PBM		</TD>
		<TD ALIGN="LEFT">Progress bar		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">PBT		</TD>
		<TD ALIGN="LEFT">Any application (battery power broadcast)		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">PSM, PSN		</TD>
		<TD ALIGN="LEFT">Property sheet		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">SB		</TD>
		<TD ALIGN="LEFT">Status bar		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">SBM		</TD>
		<TD ALIGN="LEFT">Scrollbar		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">STM, STN		</TD>
		<TD ALIGN="LEFT">Static control		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">TB, TBN		</TD>
		<TD ALIGN="LEFT">Toolbar		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">TBM		</TD>
		<TD ALIGN="LEFT">Track bar		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">TCM, TCN		</TD>
		<TD ALIGN="LEFT">Tab control		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">TTM, TTN		</TD>
		<TD ALIGN="LEFT">ToolTip		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">TVM, TVN		</TD>
		<TD ALIGN="LEFT">Tree view		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">UDM		</TD>
		<TD ALIGN="LEFT">Up Down control		</TD>
	</TR>
	<TR ALIGN="LEFT" VALIGN="TOP">
		<TD ALIGN="LEFT">WM		</TD>
		<TD ALIGN="LEFT">Generic window		</TD>
	</TR>
</TABLE>
</P>
<P>What's the difference between, say, a BM message and a BN message? A BM message
is a message to a button, such as &quot;act as though you were just clicked.&quot;
A BN message is a notification from a button to the window that owns it, such as
&quot;I was clicked.&quot; The same pattern holds for all the prefixes that end with
M or N in the preceding table.</P>
<P>Sometimes the message prefix does not end with M; for example CB is the prefix
for a message to a combo box, whereas CBN is the prefix for a notification from a
combo box to the window that owns it. Another example is CB_SETCURSEL, a message
to a combo box directing it to select one of its strings, whereas CBN_SELCHANGE is
a message sent from a combo box, notifying its parent that the user has changed which
string is selected.</P>
<P>
<H2><A NAME="Heading12"></A>Understanding Commands</H2>
<P>What is a command? It is a special type of message. Windows generates a command
whenever a user chooses a menu item, clicks a button, or otherwise tells the system
to do something. In older versions of Windows, both menu choices and button clicks
generated a WM_COMMAND message; these days you receive a WM_COMMAND for a menu choice
and a WM_NOTIFY for a control notification such as button clicking or list box selecting.
Commands and notifications are passed around by the operating system just like any
other message, until they get into the top of OnWndMsg(). At that point, Windows
message passing stops and MFC command routing starts.</P>
<P>Command messages all have, as their first parameter, the resource ID of the menu
item that was chosen or the button that was clicked. These resource IDs are assigned
according to a standard pattern--for example, the menu item File, Save has the resource
ID ID_FILE_SAVE.</P>
<P>Command routing is the mechanism OnWndMsg() uses to send the command (or notification)
to objects that can't receive messages. Only objects that inherit from CWnd can receive
messages, but all objects that inherit from CCmdTarget, including CWnd and CDocument,
can receive commands and notifications. That means a class that inherits from CDocument
can have a message map. There won't be any entries in it for messages, only for commands
and notifications, but it's still a message map.</P>
<P>How do the commands and notifications get to the class, though? By command routing.
(This becomes messy, so if you don't want the inner details, skip this paragraph
and the next.) OnWndMsg() calls CWnd::OnCommand() or CWnd::OnNotify(). OnCommand()
checks all sorts of petty stuff (such as whether this menu item was grayed after
the user selected it but before this piece of code started to execute) and then calls
OnCmdMsg(). OnNotify() checks different conditions and then it, too, calls OnCmdMsg().
OnCmdMsg() is virtual, which means that different command targets have different
implementations. The implementation for a frame window sends the command to the views
and documents it contains.</P>
<P>This is how something that started out as a message can end up being handled by
a member function of an object that isn't a window and therefore can't really catch
messages.</P>
<P>Should you care about this? Even if you don't care how it all happens, you should
care that you can arrange for the right class to handle whatever happens within your
application. If the user resizes the window, a WM_SIZE message is sent, and you may
have to rescale an image or do some other work inside your view. If the user chooses
a menu item, a command is generated, and that means your document can handle it if
that's more appropriate. You see examples of these decisions at work in Chapter 4.</P>
<P>
<H2><A NAME="Heading13"></A>Understanding Command Updates</H2>
<P>This under-the-hood tour of how MFC connects user actions such as window resizing
or menu choices to your code is almost finished. All that's left is to handle the
graying of menus and buttons, a process called <I>command updating</I>.</P>
<P>Imagine you are designing an operating system, and you know it's a good idea to
have some menu items grayed to show they can't be used right now. There are two ways
you can go about implementing this.</P>
<P>One is to have a huge table with one entry for every menu item and a flag to indicate
whether it's available. Whenever you have to display the menu, you can quickly check
the table. Whenever the program does anything that makes the item available or unavailable,
it updates the table. This is called the <I>continuous-update approach</I>.</P>
<P>The other way is not to have a table but to check all the conditions just before
your program displays the menu. This is called the <I>update-on-demand approach</I>
and is the approach taken in Windows. In the old C way of doing things--to check
whether each menu option should be grayed--the system sent a WM_INITMENUPOPUP message,
which means &quot;I'm about to display a menu.&quot; The giant switch in the WindProc
caught that message and quickly enabled or disabled each menu item. This wasn't very
object-oriented though. In an object-oriented program, different pieces of information
are stored in different objects and aren't generally made available to the entire
program.</P>
<P>When it comes to updating menus, different objects know whether each item should
be grayed. For example, the document knows whether it has been modified since it
was last saved, so it can decide whether File, Save should be grayed. However, only
the view knows whether some text is currently highlighted; therefore, it can decide
if Edit, Cut and Edit, Copy should be grayed. This means that the job of updating
these menus should be parcelled out to various objects within the application rather
than handled within the WindProc.</P>
<P>The MFC approach is to use a little object called a CCmdUI, a command user interface,
and give this object to whoever catches a CN_UPDATE_COMMAND_UI message. You catch
those messages by adding (or getting ClassWizard to add) an ON_UPDATE_COMMAND_UI
macro in your message map. If you want to know what's going on behind the scenes,
it's this: The operating system still sends WM_INITMENUPOPUP; then the MFC base classes
such as CFrameWnd take over. They make a CCmdUI, set its member variables to correspond
to the first menu item, and call one of that object's own member functions, DoUpdate().
Then, DoUpdate() sends out the CN_COMMAND_UPDATE_UI message with a pointer to itself
as the CCmdUI object the handlers use. The same CCmdUI object is then reset to correspond
to the second menu item, and so on, until the entire menu is ready to be displayed.
The CCmdUI object is also used to gray and ungray buttons and other controls in a
slightly different context.</P>
<P>CCmdUI has the following member functions:</P>
<P>

<UL>
	<LI>Enable()--Takes a TRUE or FALSE (defaults to TRUE). This grays the user interface
	item if FALSE and makes it available if TRUE.
	<P>
	<LI>SetCheck()--Checks or unchecks the item.
	<P>
	<LI>SetRadio()--Checks or unchecks the item as part of a group of radio buttons,
	only one of which can be set at any time.
	<P>
	<LI>SetText()--Sets the menu text or button text, if this is a button.
	<P>
	<LI>DoUpdate()--Generates the message.
</UL>

<P>Determining which member function you want to use is usually clear-cut. Here is
a shortened version of the message map from an object called CWhoisView, a class
derived from CFormView that is showing information to a user. This form view contains
several edit boxes, and the user may want to paste text into one of them. The message
map contains an entry to catch the update for the ID_EDIT_PASTE command, like this:</P>
<P>
<PRE>BEGIN_MESSAGE_MAP(CWhoisView, CFormView)
     ...
     ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
     ...
END_MESSAGE_MAP()
</PRE>
<P>The function that catches the update, OnUpdateEditPaste(), looks like this:</P>
<P>
<PRE>void CWhoisView::OnUpdateEditPaste(CCmdUI* pCmdUI)
{
 pCmdUI-&gt;Enable(::IsClipboardFormatAvailable(CF_TEXT));
}
</PRE>
<P>This calls the API function ::IsClipboardFormatAvailable() to see whether there
is text in the Clipboard. Other applications may be able to paste in images or other
nontext Clipboard contents, but this application cannot and grays the menu item if
there is no text available to paste. Most command update functions look just like
this: They call Enable() with a parameter that is a call to a function that returns
TRUE or FALSE, or perhaps a simple logical expression. Command update handlers must
be fast because five to ten of them must run between the moment the user clicks to
display the menu and the moment before the menu is actually displayed.</P>
<P>
<H2><A NAME="Heading14"></A>Learning How ClassWizard Helps You Catch Commands and
Command Updates</H2>
<P>The ClassWizard dialog box shown in Figure 4.1 has the classname highlighted in
the box labeled Object IDs. Below that are resource IDs of every resource (menu,
toolbar, dialog box controls, and so on) that can generate a command or message when
this object (view, dialog, and so on) is on the screen. If you highlight one of those,
the list of messages associated with it is much smaller, as you see in Figure 3.4.</P>
<P>Only two messages are associated with each resource ID: COMMAND and UPDATE_COMMAND_UI.
The first enables you to add a function to handle the user selecting the menu option
or clicking the button--that is, to catch the command. The second enables you to
add a function to set the state of the menu item, button, or other control just as
the operating system is about to display it--that is, to update the command. (The
COMMAND choice is boldface in Figure 3.4 because this class already catches that
command.)</P>
<P><A HREF="javascript:popUp('03uvc04.gif')"><B>FIG. 3.4</B></A><B> </B><I>ClassWizard
enables you to catch or update commands.</I></P>

<P>Clicking Add Function to add a function that catches or updates a command involves
an extra step. ClassWizard gives you a chance to change the default function name,
as shown in Figure 3.5. This is almost never appropriate. There is a regular pattern
to the suggested names, and experienced MFC programmers come to count on function
names that follow that pattern. Command handler functions, like message handlers,
have names that start with On. Typically, the remainder of the function name is formed
by removing the ID and the underscores from the resource ID and capitalizing each
word. Command update handlers have names that start with OnUpdate and use the same
conventions for the remainder of the function name. For example, the function that
catches ID_APP_EXIT should be called OnAppExit(), and the function that updates ID_APP_EXIT
should be called OnUpdateAppExit().</P>
<P><A HREF="javascript:popUp('03uvc05.gif')"><B>FIG. 3.5</B></A><B> </B><I>It's possible,
but not wise, to change the name for your command handler or command update handler
from the name suggested by ClassWizard.</I></P>

<P>Not every command needs an update handler. The framework does some very nice work
graying and ungraying for you automatically. Say you have a menu item--Network, Send--whose
command is caught by the document. When there is no open document, this menu item
is grayed by the framework, without any coding on your part. For many commands, it's
enough that an object that can handle them exists, and no special updating is necessary.
For others, you may want to check that something is selected or highlighted or that
no errors are present before making certain commands available. That's when you use
command updating. If you'd like to see an example of command updating at work, there's
one in Chapter 8 in the &quot;Command Updating&quot; section.</P>
<H1></H1>
<CENTER>
<P>
<HR>
<A HREF="../ch02/ch02.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch04/ch04.htm"><IMG
SRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"
BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"
HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR>
<BR>
</P>

<P>&#169; <A HREF="../copy.htm">Copyright</A>, Macmillan Computer Publishing. All
rights reserved.
</CENTER>


</BODY>

</HTML>

⌨️ 快捷键说明

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