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

📄 ch04.htm

📁 VC使用大全。里面集合了VC使用的各种使用技巧。非常有用。
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<TD>

<pre><font color="#008000">TB</font>, <font color="#008000">TBN</font></pre>

<TD>

<P>Tool bar</P>

<TR>

<TD>

<pre><font color="#008000">TBM</font></pre>

<TD>

<P>Track bar</P>

<TR>

<TD>

<pre><font color="#008000">TCM</font>, <font color="#008000">TCN</font></pre>

<TD>

<P>Tab control</P>

<TR>

<TD>

<pre><font color="#008000">TTM</font>, <font color="#008000">TTN</font></pre>

<TD>

<P>ToolTip</P>

<TR>

<TD>

<pre><font color="#008000">TVM</font>, <font color="#008000">TVN</font></pre>

<TD>

<P>Tree view</P>

<TR>

<TD>

<pre><font color="#008000">UDM</font></pre>

<TD>

<P>Up Down control</P>

<TR>

<TD>

<pre><font color="#008000">WM</font></pre>

<TD>

<P>Generic window</P></TABLE>

<P>What&#146;s the difference between, say, a <font color="#008000">BM</font> message and a <font color="#008000">BN</font> message? A <font color="#008000">BM</font> message is a message to a button, such as &quot;act as though you were just 
clicked.&quot; A <font color="#008000">BN</font> 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 <font color="#008000">M</font> or <font 
color="#008000">N</font> in the preceding table.</P>

<P>Sometimes the &quot;message&quot; prefix does not end with M; for example <font color="#008000">CB</font> is the prefix for a message to a combo box while <font color="#008000">CBN</font> is the prefix for a notification from a combo box to the window 
that owns it. For example, <font color="#008000">CB_SETCURSEL</font> is a message to a combo box directing it to select one of its strings, while <font color="#008000">CBN_SELCHANGE</font> is a message sent from a combo box notifying its parent that the 
user has changed which string is selected.</P>

<H3><B>Commands</B></H3>

<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 <font color="#008000">WM_COMMAND</font> message; these days you get a <font color="#008000">WM_COMMAND</font> for a menu choice and a <font color="#008000">WM_NOTIFY</font> for a control notification like button clicking or list box selecting. 
Commands and notifications get passed around by the operating system just like any other message, until they get into the top of <font color="#008000">OnWndMsg()</font>. 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&#151;for example, the menu item File, Save has the 
resource ID <font color="#008000">ID_FILE_SAVE</font>.</P>

<P>Command routing is the mechanism <font color="#008000">OnWndMsg()</font> uses to send the command (or notification) to objects that can't receive messages. Only objects that inherit from <font color="#008000">CWnd</font> can receive messages, but all 
objects that inherit from <font color="#008000">CCmdTarget</font>, including <font color="#008000">CWnd</font> and <font color="#008000">CDocument</font>, can receive commands and notifications. That means a class that inherits from <font 
color="#008000">CDocument</font> can have a message map. There won&#146;t be any entries in it for messages, only for commands and notifications, but it&#146;s still called a message map.</P>

<P>How do the commands and notifications get to the class, though? By command routing. (This gets messy, so if you don't want the inner details, skip this paragraph and the next.) <font color="#008000">OnWndMsg()</font> calls <font 
color="#008000">CWnd::OnCommand()</font> or <font color="#008000">CWnd::OnNotify()</font>. <font color="#008000">OnCommand()</font> checks all sorts of petty stuff (like whether this menu item was grayed after the user selected it but before this piece of 
code started to execute) and then calls <font color="#008000">OnCmdMsg()</font>. <font color="#008000">OnNotify()</font> checks different conditions and then it, too, calls <font color="#008000">OnCmdMsg()</font>. <font color="#008000">OnCmdMsg()</font> 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 is not 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 <font color="#008000">WM_SIZE</font> 
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&#146;s more appropriate. You see examples of these 
decisions at work in the next chapter, &quot;Documents and Views.&quot;</P>

<H2><B>Command Updates</B></H2>

<P>This under-the-hood tour of just how MFC connects user actions like window resizing or menu choices to your code is almost complete. 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 or not. 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&#151;to check 
whether each menu option should be grayed or not&#151;the system sent a <font color="#008000">WM_INITMENUPOPUP</font> message, which means &quot;I'm about to display a menu.&quot; The giant switch in the <font color="#008000">WindProc</font> 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 are not generally made available to the entire program.</P>

<P>When it comes to updating menus, different objects &quot;know&quot; whether or not 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 or 
not; but, only the view knows whether or not 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 <font color="#008000">WindProc</font>.</P>

<P>The MFC approach is to use a little object called a <font color="#008000">CCmdUI</font>, a command user interface, and give this object to whomever catches a <font color="#008000">CN_UPDATE_COMMAND_UI</font> message. You catch those messages by adding 
(or getting ClassWizard to add) an <font color="#008000">ON_UPDATE_COMMAND_UI</font> 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 <font 
color="#008000">WM_INITMENUPOPUP</font>, then the MFC base classes like <font color="#008000">CFrameWnd</font> take over. They make a <font color="#008000">CCmdUI</font>, set its member variables to correspond to the first menu item, and call one of that 
object's own member functions, <font color="#008000">DoUpdate()</font>. Then, <font color="#008000">DoUpdate()</font> sends out the <font color="#008000">CN_COMMAND_UPDATE_UI</font> message with a pointer to itself as the <font 
color="#008000">CCmdUI</font> object the handlers use. Then the same <font color="#008000">CCmdUI</font> object is reset to correspond to the second menu item, and so on until the entire menu is ready to be displayed. The <font color="#008000">CCmdUI 
</font>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>

<ul>

<li> <font color="#008000">Enable()</font>&#151;Takes a True or False (defaults to True). Grays the user interface item if False; makes it available if True.</P>

<li> <font color="#008000">SetCheck()</font>&#151;Checks or unchecks the item.</P>

<li> <font color="#008000">SetRadio()</font>&#151;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> <font color="#008000">SetText()</font>&#151;Sets the menu text or button text, if this is a button.</P>

<li> <font color="#008000">DoUpdate()</font>&#151;Generates the message.</P>

</ul>

<P>It's usually pretty straightforward to determine which member function you want to use. Here is a shortened version of the message map from an object called <font color="#008000">CWhoisView</font>, a class derived from <font 
color="#008000">CFormView</font> that is showing information to a user. This form view contains several edit boxes and the user may wish to paste text into one of them. The message map contains an entry to catch the update for the <font 
color="#008000">ID_EDIT_PASTE</font> command, like this:</P>

<pre><font color="#008000">BEGIN_MESSAGE_MAP(CWhoisView, CFormView)</font></pre>

<pre><font color="#008000">     ...</font></pre>

<pre><font color="#008000">     ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)</font></pre>

<pre><font color="#008000">     ...</font></pre>

<pre><font color="#008000">END_MESSAGE_MAP()</font></pre>

<P>The function that catches the update, <font color="#008000">OnUpdateEditPaste()</font>, looks like this:</P>

<pre><font color="#008000">void CWhoisView::OnUpdateEditPaste(CCmdUI* pCmdUI)</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000"> pCmdUI-&gt;Enable(::IsClipboardFormatAvailable(CF_TEXT));</font></pre>

<pre><font color="#008000">}</font></pre>

<P>This calls the API function <font color="#008000">::IsClipboardFormatAvailable()</font> to see if there is text in the Clipboard. Other applications may be able to paste in images or other non-text 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 <font color="#008000">Enable()</font> 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 from the moment the user clicks to display the menu to before the menu is actually displayed.</P>

<H3><B>ClassWizard Helps You Catch Commands and Command Updates</B></H3>

<P>The ClassWizard dialog box shown in Figure 4.1 has the class name 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 4.4.</P>

<A HREF="Ffigs04.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch04/Ffigs04.gif"><b>Fig. 4.4</b></A>

<P><I>ClassWizard allows you to catch or update commands.</I></P>

<P>There are only two messages associated with each resource ID: <font color="#008000">COMMAND</font> and <font color="#008000">UPDATE_COMMAND_UI</font>. The first allows you to add a function to handle the user selecting the menu option or clicking the 
button&#151;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&#151;that is, to update the command. (The <font 
color="#008000">COMMAND</font> choice is boldface in Figure 4.4 because this class already catches that command.)</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 4.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 <font color="#008000">On</font>. 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 <font color="#008000">OnUpdate</font> and use the same conventions for the remainder of the 
function name. For example, the function that catches <font color="#008000">ID_APP_EXIT</font> should be called <font color="#008000">OnAppExit()</font>, and the function that updates <font color="#008000">ID_APP_EXIT</font> should be called <font 
color="#008000">OnUpdateAppExit()</font>.</P>

<A HREF="Ffigs05.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch04/Ffigs05.gif"><b>Fig. 4.5</b></A>

<P><I>It is possible, but not wise, to change the name for your command handler or command update handler from </I><I>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 <A HREF="index09.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index09.htm" target="text">Chapter 9</A>, &quot;Building a 
Complete Application: ShowString,&quot; in the &quot;Command Updating&quot; section.</P>

<H3><B>From Here...</B></H3>

<P>This chapter has provided the theory of message handling and command routing, and a behind-the-scenes look at the ways MFC implements these for you. To see this theory in action, check out the following chapters:</P>

<ul>

<li> <A HREF="index05.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index05.htm" target="text">Chapter 5</A>, &quot;Documents and Views,&quot; discusses views, documents, and frames, and the way in which they interact. Issues like which class should catch certain messages are explored in more detail 
here.</P>

<li> <A HREF="index06.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index06.htm" target="text">Chapter 6</A>, &quot;Drawing on the Screen,&quot; discusses what code, if any, you should write to handle messages like WM_PAINT and WM_SIZE that indicate your window needs to be redrawn.</P>

<li> <A HREF="index08.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index08.htm" target="text">Chapter 8</A>, &quot;Persistence and File I/O,&quot; discusses the way that documents get saved and loaded in more detail, explains why you need a Serialize() function, and illustrates the sort of code it typically 
contains.</P>

<li> <A HREF="index09.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index09.htm" target="text">Chapter 9</A>, &quot;Building A Complete Application: ShowString,&quot; shows how to build your own menus and dialog boxes and assign resource IDs to interface items. You see examples of ClassWizard in action, 
hooking interface items to code.</P>

<li> <A HREF="index10.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index10.htm" target="text">Chapter 10</A>, &quot;Status Bars and Toolbars,&quot; draws on what you have learned about menus to explain toolbars.</P>

</ul>

<p><hr></p>

<center>

<p><font size=-2>

&copy; 1997, QUE Corporation, an imprint of Macmillan Publishing USA, a

Simon and Schuster Company.</font></p>

</center>

</BODY></HTML>

⌨️ 快捷键说明

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