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

📄 chap2_4.htm

📁 vc教程,真正的程序员用Visual C++。如果你想当程序员
💻 HTM
📖 第 1 页 / 共 3 页
字号:
    <p><span style="font-size: 9pt">};</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">成员函数OnCreate,OnEditCopy,OnClose分别用来处理消息WM_CREATE、ID_EDIT_COPY和WM_CLOSE。其中,WM_CREATE和WM_CLOSE是系统预定义消息,包含在Windows.h中。而ID_EDIT_COPY是菜单Edit-&gt;Copy的标识,也就是用户选择Edit-&gt;Copy菜单项时产生的消息,一般在资源文件头文件中定义。在类的实现部分给出这三个成员函数的定义,以及特殊的消息映射宏。上面的例子的消息映射宏定义如下:</span></p>
    <p><span style="font-size: 9pt">BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)</span></p>
    <p><span style="font-size: 9pt">ON_WM_CREATE()</span></p>
    <p><span style="font-size: 9pt">ON_COMMAND(ID_EDIT_COPY, OnEditCopy)</span></p>
    <p><span style="font-size: 9pt">ON_WM_CLOSE()</span></p>
    <p><span style="font-size: 9pt">END_MESSAGE_MAP()</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">消息映射宏由BEGIN_MESSAGE_MAP() 
    和END_MESSAGE_MAP()。其中,BEGIN_MESSAGE_MAP宏包含两个参数CMainFrame类和CFrameWnd,分别代表当前定义的类和它的父类。在BEGIN_MESSAGE_MAP()和END_MESSAGE_MAP()之间,包含了主窗口要处理的各个Windows消息的入口。在本例中,包含三个消息。其中ON_ 
    WM_CREATE被用来指定缺省的成员函数OnCreate与WM_CREATE相对应。在MFC中,包含了大量的预定义消息映射宏,用来指定各种成员函数与各种形如WM_XXXX消息相对应。如ON_WM_CLOSE宏指定了WM_CLOSE消息的处理成员函数为OnClose。这时侯,只需要写出要处理的消息就够了,不必再写出处理函数。消息映射宏ON_COMMAND则被用来将菜单项和用户自定义的命令同它们的处理成员函数联系起来。在上例中,用户选择Edit-&gt;Copy菜单项时,系统执行OnEditCopy()函数。ON_COMMAND宏的一般定义形式如下:</span></p>
    <p><span style="font-size: 9pt">ON_COMMAND(command,command_function)</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">其中,command为菜单消息或用户自定义消息,command_function为消息处理函数。MFC允许用户自定义消息,常量WM_USER和第一个消息值相对应,用户必须为自己的消息定义相对于WM_USER的偏移值,偏移范围在0~0x3FFF之间,这对绝大多数程序来说都是够用的。用户可以利用#define语句直接定义自己的消息:</span></p>
    <p ALIGN="JUSTIFY"> </p>
    <p><span style="font-size: 9pt">#define WM_USER1 (WM_USER+0)</span></p>
    <p><span style="font-size: 9pt">#define WM_USER2 (WM_USER+1)</span></p>
    <p><span style="font-size: 9pt">#define WM_USER3 (WM_USER+2)</span></p>
    <p><span style="font-size: 9pt">下表列出了Windows95中Windows消息值的范围。</span></p>
    <table BORDER="1" CELLSPACING="2" BORDERCOLOR="#7f7f7f" CELLPADDING="1" WIDTH="400">
      <tr>
        <td WIDTH="19%"><span style="font-size: 9pt">常 量</span></td>
        <td WIDTH="13%"><span style="font-size: 9pt">值</span></td>
        <td WIDTH="26%"><span style="font-size: 9pt">消息值范围</span></td>
        <td WIDTH="41%"><span style="font-size: 9pt">意 义</span></td>
      </tr>
      <tr>
        <td WIDTH="19%"><span style="font-size: 9pt">WM_USER</span></td>
        <td WIDTH="13%"><span style="font-size: 9pt">0x0400</span></td>
        <td WIDTH="26%"><span style="font-size: 9pt">0x0000-0x03FF</span></td>
        <td WIDTH="41%"><span style="font-size: 9pt">Windows消息</span></td>
      </tr>
      <tr>
        <td WIDTH="19%"> </td>
        <td WIDTH="13%"> </td>
        <td WIDTH="26%"><span style="font-size: 9pt">0x0400-0x7FFF</span></td>
        <td WIDTH="41%"><span style="font-size: 9pt">用户自定义的消息</span></td>
      </tr>
      <tr>
        <td WIDTH="19%"> </td>
        <td WIDTH="13%"> </td>
        <td WIDTH="26%"><span style="font-size: 9pt">0x8000-0xBFFF</span></td>
        <td WIDTH="41%"><span style="font-size: 9pt">Windows保留值</span></td>
      </tr>
      <tr>
        <td WIDTH="19%"> </td>
        <td WIDTH="13%"> </td>
        <td WIDTH="26%"><span style="font-size: 9pt">0xC000-0xFFFF</span></td>
        <td WIDTH="41%"><span style="font-size: 9pt">供应用使用的字符串消息</span></td>
      </tr>
    </table>
    <p> </p>
    <p><span style="font-size: 9pt">为了说明如何使用用户自定义消息,我们看一个例子,见程序清单2.4:</span><b></p>
    <p><span style="font-size: 9pt">清单2.4 使用用户自定义消息</span></b></p>
    <p><span style="font-size: 9pt">#include&lt;afxwin.h&gt;</span></p>
    <p><span style="font-size: 9pt">#define CM_APPLE (WM_USER+0)</span></p>
    <p><span style="font-size: 9pt">#define CM_ORANGE (WM_USER+1)</span></p>
    <p><span style="font-size: 9pt">class CMainFrame:CFrameWnd{</span></p>
    <p><span style="font-size: 9pt">public:</span></p>
    <p><span style="font-size: 9pt">CMainFrame();</span></p>
    <p><span style="font-size: 9pt">protected:</span></p>
    <p><span style="font-size: 9pt">afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);</span></p>
    <p><span style="font-size: 9pt">afx_msg void OnClose();</span></p>
    <p><span style="font-size: 9pt">//handle user select apple</span></p>
    <p><span style="font-size: 9pt">afx_msg LRESULT CMApple(WPARAM wParam, LPARAM lParam);</span></p>
    <p><span style="font-size: 9pt">//handle user select orange</span></p>
    <p><span style="font-size: 9pt">afx_msg LRESULT CMOrange(WPARAM wParam, LPARAM lParam);</span></p>
    <p><span style="font-size: 9pt">DECLARE_MESSAGE_MAP()</span></p>
    <p><span style="font-size: 9pt">};</span></p>
    <p><span style="font-size: 9pt">相应的消息映射如下:</span></p>
    <p><span style="font-size: 9pt">BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)</span></p>
    <p><span style="font-size: 9pt">ON_WM_CREATE()</span></p>
    <p><span style="font-size: 9pt">ON_MESSAGE(CM_APPLE, CMApple)</span></p>
    <p><span style="font-size: 9pt">ON_MESSAGE(CM_ORANGE,CMOrange)</span></p>
    <p><span style="font-size: 9pt">ON_WM_CLOSE()</span></p>
    <p><span style="font-size: 9pt">END_MESSAGE_MAP()</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">第一个ON_MESSAGE宏用于指定 
    CM_APPLE 命令消息的处理成员函数为CMApple ,而第二个ON_MESSAGE宏用于指定CM_ORANGE命令消息的处理函数为CMOrange。</span><b></p>
    <p><span style="font-size: 9pt">消息的发送</span></b></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">Windows应用程序允许应用程序向自己发送消息、向其他应用程序发送消息,甚至可以向Windows操作系统本身发送消息(比如要求关闭操作系统或重新启动操作系统)。Windows提供了三个API函数用于发送消息,这三个函数是:SendMessage、PostMessage和SendDlgItemMessage。</span></p>
    <p><span style="font-size: 9pt">SendMessage用于向窗口发送消息,该函数说明如下:</span></p>
    <blockquote>
      <p><span style="font-size: 9pt">LRESULT SendMessage(</span></p>
    </blockquote>
    <p><span style="font-size: 9pt">HWND hWnd, //消息要发往的窗口的句柄</span></p>
    <p><span style="font-size: 9pt">UINT Msg, //要发送的消息</span></p>
    <p><span style="font-size: 9pt">WPARAM wParam, //消息的第一个参数</span></p>
    <p><span style="font-size: 9pt">LPARAM lParam //消息的第二个参数</span></p>
    <p><span style="font-size: 9pt">);</span></p>
    <p><span style="font-size: 9pt">其中,hWnd为接收消息窗口的句柄,参数Msg指定发送的消息,参数wParam和lParam依赖于消息Msg。该函数调用目标窗口的窗口函数,直到目标窗口处理完该消息才返回。</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">PostMessage函数同SendMessage类似,它把消息放在指定窗口创建的线程的消息队列中,然后不等消息处理完就返回,而不象SendMessage那样必须等到消息处理完毕才返回。目标窗口通过GetMessage或PeekMessage从消息队列中取出并处理。PostMessage函数说明如下:</span></p>
    <p ALIGN="JUSTIFY"> </p>
    <blockquote>
      <p><span style="font-size: 9pt">BOOL PostMessage(</span></p>
    </blockquote>
    <p><span style="font-size: 9pt">HWND hWnd, //消息发往的窗口</span></p>
    <p><span style="font-size: 9pt">UINT Ms<i>g</i>, //要发送的消息</span></p>
    <p><span style="font-size: 9pt">WPARAM wParam, //消息的第一个参数</span></p>
    <p><span style="font-size: 9pt">LPARAM lParam //消息的第二个参数</span></p>
    <p><span style="font-size: 9pt">);</span></p>
    <p> </p>
    <p><span style="font-size: 9pt">其中,参数hWnd为接收消息的窗口的句柄,参数Msg指定所发送的消息,参数wParam和lParam依赖于消息Msg。</span></p>
    <p><span style="font-size: 9pt">SendDlgItemMessage函数用于向对话框的某个控制发送消息,函数声明如下:</span></p>
    <blockquote>
      <b><p></b><span style="font-size: 9pt">LONG SendDlgItemMessage(</span></p>
    </blockquote>
    <p><span style="font-size: 9pt">HWND hDlg, //对话框句柄</span></p>
    <p><span style="font-size: 9pt">int nIDDlgItem, //对话框控件的ID</span></p>
    <p><span style="font-size: 9pt">UINT Msg, //要发送的消息</span></p>
    <p><span style="font-size: 9pt">WPARAM wParam, //消息的第一个参数</span></p>
    <p><span style="font-size: 9pt">LPARAM lParam //消息的第二个参数</span></p>
    <p><span style="font-size: 9pt">); </span></p>
    <p><span style="font-size: 9pt">其中,hDlg为包含目标控制的对话框的窗口句柄,参数nIDDlgItem为接收消息的对话框控制的整数标识符,参数Msg指定了所发送的消息,参数wParam和lParam提供附加的特定消息的信息。</span></p>
    <p><span style="font-size: 9pt">MFC将这三个函数封装为CWnd类的成员函数,隐藏了窗口句柄和对话框句柄。这三个成员函数用于向本窗口发送消息,函数的说明如下:</span></p>
    <blockquote>
      <blockquote>
        <b><p></b><span style="font-size: 9pt">LRESULT SendMessage( UINT message, WPARAM wParam = 
        0, LPARAM lParam = 0 );</span></p>
        <b><p></b><span style="font-size: 9pt">BOOL PostMessage( UINT message, WPARAM wParam = 0, 
        LPARAM lParam = 0 );</span></p>
        <p><span style="font-size: 9pt">LRESULT SendDlgItemMessage( int nID, UINT message, WPARAM 
        wParam = 0, LPARAM lParam = 0 );</span></p>
      </blockquote>
    </blockquote>
    <b><p></b><span style="font-size: 9pt"><font color="#3973DE">2.4.5学习MFC的方法</font></span></p>
    <p><span style="font-size: 9pt">首先要对Windows API有一定的了解,否则无法深入学习MFC。至少要知道Windows对程序员来说意味着什么,它能完成什么工作,它的一些常用数据结构等。</span></p>
    <p><span style="font-size: 9pt">另一点是不要过分依赖于Wizards。Wizards能做许多工作,但同时掩饰了太多的细节。应当看看AppWizard和ClassWizard为你所做的工作。在mainfrm.cpp中运行调试器来观察一下MFC运行的流程。除非你理解了生成的代码的含义,否则无法了解程序是如何运行。</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">还有很重要的一点就是要学会抽象的把握问题,不求甚解。许多人一开始学习Visual 
    C++就试图了解整个MFC类库,实际上那几乎是不可能的。一般的学习方法是,先大体上对MFC有个了解,知道它的概念、组成、基本约定等。从最简单的类入手,由浅入深,循序渐进、日积月累的学习。一开始使用MFC提供的类时,只需要知道它的一些常用的方法、外部接口,不必要去了解它的细节和内部实现,把它当做一个模块或者说黑盒子来用,这就是一种抽象的学习方法。在学到一定程度时,再可以深入研究,采用继承的方法对原有的类的行为进行修改和扩充,派生出自己所需的类。</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">学习MFC,最重要的一点是理解和使用MFC类库,而不是记忆。</span><font
    FACE="Times New Roman" SIZE="3"><b></p>
    </b></font><div align="center"><center><table border="0" cellpadding="0" cellspacing="0"
    width="615">
      <tr>
        <td><a href="chap2_3.htm">上一页</a></td>
        <td><p align="right"><a href="chap2_5.htm">下一页</a></td>
      </tr>
    </table>
    </center></div><font SIZE="5"><hr noshade color="#3973DE" size="1">
    <p align="center"></font><font size="2" color="#000000">本教程由<a
    href="http://vcdynasty.yeah.net">Visual C++王朝(Where programmers come together)</a>协助制作<br>
    未经许可,请勿以任何形式复制</font></td>
    <b>
  </tr>
</table>
</center></div></b>
</body>
</html>

⌨️ 快捷键说明

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