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

📄 mfc13.php

📁 php网页版的mfc教程 不是十分详细 但是很精练 我是新手不是十分会欣赏
💻 PHP
📖 第 1 页 / 共 5 页
字号:
      <P align=justify>//基于layout.rect表示的客户尺寸计算出窗口尺寸</P>
      <P align=justify>pLeftOver-&gt;CalcWindowRect(&amp;layout.rect);</P>
      <P align=justify>//导致函数::DeferWindowPos的调用</P>
      <P align=justify>AfxRepositionWindow(&amp;layout, hWndLeftOver, 
      &amp;layout.rect);</P>
      <P align=justify>}</P>
      <P align=justify></P>
      <P align=justify>//给所有的窗口设置尺寸、位置(size and layout)</P>
      <P align=justify>if (layout.hDWP == NULL || 
      !::EndDeferWindowPos(layout.hDWP))</P>
      <P align=justify>TRACE0("Warning: DeferWindowPos failed - low system 
      resources.\n");</P>
      <P align=justify>}</P>
      <P align=justify>RepositionBars用来改变客户窗口中控制条的尺寸大小或者位置,其中:</P>
      <P align=justify>参数1和参数2定义了需要重新放置的子窗口ID的范围,一般是0到0xFFFF。</P>
      <P 
      align=justify>参数3指定了一个子窗口ID,它拥有客户窗口剩下的空间,一般是AFX_IDW_PANE_FIRST,表示视的窗口ID。</P>
      <P 
      align=justify>参数4指定了操作类型,缺省是CWnd::ReposDefault,表示执行窗口放置操作,参数5不会用到;若取值CWnd::ReposQuery,则表示尝试进行窗口放置(Layout) 
      ,但最后不执行这个操作,只是把参数5初始化成客户区的尺寸大小;若取值CWnd::ReposExtra,则把参数5的值加到参数2表示的子窗口的客户区域,并执行窗口放置操作。</P>
      <P align=justify>参数6表示传递给函数的可用窗口客户区的尺寸,如果空则使用窗口客户区尺寸。</P>
      <P align=justify>如果执行layout操作的话,该函数的核心处理就是:</P>
      <P 
      align=justify>首先,调用::BeginDeferWindowPos初始化一个Windows内部的多窗口位置结构(Multiple-window 
      - position structure)hDWP;</P>
      <P 
      align=justify>然后,让各个子窗口逐个调用::DeferWindowPos,更新hDWP。在调用::DeferWindowPos之前,要作一个确定子窗口大小的工作。这些工作通过给各个控制子窗口发送消息WM_SIZEPARENT来完成。</P>
      <P 
      align=justify>控制子窗口通过函数OnSizeParent响应WM_SIZEPARENT消息,先确定自己的尺寸,然后,如果需要进行窗口布置(WM_SIZEPARENT消息参数lParam包含了一个非空的HDWP结构(lpLayout-&gt;hDWP)),则OnSizeParent将调用AfxRepositionWindow函数计算本控制窗口的位置,结果保存到hDWP中。</P>
      <P 
      align=justify>在所有的控制窗口尺寸确定之后,剩下的留给窗口hWndLeftOver(如果存在的话)。确定了hWndLeftOver的大小之后,调用AfxRepositionWindow函数计算其位置,结果保存到hDWP中。</P>
      <P align=justify>上面提到的函数AfxRepositionWindow间接调用了::DeferWindowPos。</P>
      <P align=justify>最后,::EndDeferWindowPos,使用hDWP安排所有子窗口的位置和大小。</P>
      <P align=justify></P>
      <P 
      align=justify>至于其他函数,如OnSizeparent、OnWindowPosChanging、CalcWindowRect,这里不作进一步的分析。</P>
      <P align=justify></P>
      <LI><A name=_Toc452641012></A><A 
      name=_Toc457299146></A><B>工具条、状态栏和边框窗口的接口</B> 
      <P></P>
      <OL>
        <P align=justify>
        <LI><B><A name=_Toc457299147></A>应用程序在状态栏中显示信息</B> 
        <P></P></LI></OL></LI></OL></OL></OL>
<P 
align=justify>MFC内部通过给边框窗口发送消息WM_SETMESSAGESTRING、WM_POPMESSAGESTRING的方式在状态栏中显示信息。这两个消息在afxpriv.h里头定义。</P>
<P 
align=justify>WM_SETMESSAGESTRING消息表示在状态栏中显示和某个ID对应的字符串信息或者指定的字符串信息,消息参数wParam指定了字符串资源ID,消息参数lParam指定了字符串指针,两个消息参数只有一个有用。一般,一个命令ID对应了一个字符串ID,对应的字符串是命令ID的说明。</P>
<P align=justify>消息WM_POPMESSAGESTRING用来重新设置状态栏。</P>
<P 
align=justify>这两个消息对应的消息处理函数分别是OnSetMessageString和OnPopMessageString,OnSetMessageString和OnPopMessageString分别实现如下:</P>
<OL>
  <P align=justify>
  <LI>OnSetMessageString 
  <P></P>
  <P align=justify>LRESULT CFrameWnd::OnSetMessageString(WPARAM wParam, LPARAM 
  lParam)</P>
  <P align=justify>{</P>
  <P align=justify>//最近一次被显示的消息字符串IDS(一个消息对应的字符串)</P>
  <P align=justify>UINT nIDLast = m_nIDLastMessage;</P>
  <P align=justify>m_nFlags &amp;= ~WF_NOPOPMSG;</P>
  <P align=justify></P>
  <P align=justify>//得到状态栏</P>
  <P align=justify>CWnd* pMessageBar = GetMessageBar();</P>
  <P align=justify>if (pMessageBar != NULL)</P>
  <P align=justify>{</P>
  <P align=justify>LPCTSTR lpsz = NULL;</P>
  <P align=justify>CString strMessage;</P>
  <P align=justify></P>
  <P align=justify>//设置状态栏文本</P>
  <P align=justify>if (lParam != 0) //指向一个字符串</P>
  <P align=justify>{</P>
  <P align=justify>ASSERT(wParam == 0); // can't have both an ID and a 
string</P>
  <P align=justify>lpsz = (LPCTSTR)lParam; // set an explicit string</P>
  <P align=justify>}</P>
  <P align=justify>else if (wParam != 0)//一个字符串资源IDS</P>
  <P align=justify>{</P>
  <P align=justify>//打印预览时映射SC_CLOSE成AFX_IDS_PREVIEW_CLOSE;</P>
  <P align=justify>if (wParam == AFX_IDS_SCCLOSE &amp;&amp; m_lpfnCloseProc != 
  NULL)</P>
  <P align=justify>wParam = AFX_IDS_PREVIEW_CLOSE;</P>
  <P align=justify></P>
  <P align=justify>//得到资源ID所标识的字符串</P>
  <P align=justify>GetMessageString(wParam, strMessage);</P>
  <P align=justify>lpsz = strMessage;</P>
  <P align=justify>}</P>
  <P align=justify>//在状态栏中显示文本</P>
  <P align=justify>pMessageBar-&gt;SetWindowText(lpsz);</P>
  <P align=justify></P>
  <P align=justify>// 根据最近一次选择的消息更新状态条所属窗口的有关记录</P>
  <P align=justify>CFrameWnd* pFrameWnd = pMessageBar-&gt;GetParentFrame();</P>
  <P align=justify>if (pFrameWnd != NULL)</P>
  <P align=justify>{</P>
  <P align=justify>//记录最近一次显示的消息字符串</P>
  <P align=justify>pFrameWnd-&gt;m_nIDLastMessage = (UINT)wParam;</P>
  <P align=justify>//记录最近一次Tracking的命令ID和字符串IDS</P>
  <P align=justify>pFrameWnd-&gt;m_nIDTracking = (UINT)wParam;</P>
  <P align=justify>}</P>
  <P align=justify>}</P>
  <P align=justify></P>
  <P align=justify>m_nIDLastMessage = (UINT)wParam; // new ID (or 0)</P>
  <P align=justify>m_nIDTracking = (UINT)wParam; // so F1 on toolbar buttons 
  work</P>
  <P align=justify>return nIDLast;</P>
  <P align=justify>}</P>
  <P 
  align=justify>OnSetMessageString函数直接或者从ID从字符串资源中得到字符串指针。如果是从ID得到字符串指针,则函数GetMessageString被调用。</P>
  <P 
  align=justify>和命令ID对应的字符串由两部分组成,前一部分用于在状态栏显示,后一部分用于Tooltip显示,分隔符号是“\n”。例如,字符串ID_APP_EXIT(对应“退出”菜单、按钮)是“Exit 
  Application\nExit”,当鼠标落在“退出”按钮上时,状态栏显示“Exit 
  Application”,Tooltip显示“Exit”。根据这种格式,GetMessageString分离出第一部分的文本信息。至于第二部分的用途将在讨论Tooltip的章节将用到。</P>
  <P 
  align=justify>得到了字符串之后,OnSetMessageString调用状态栏的SetWindowText函数。SetWindowText导致消息WM_SETTEXT消息发送给状态栏,状态栏的消息处理函数OnSetText被调用,实际上等于调用了SetPaneText(0, 
  lpsz),即在状态栏的第0格中显示字符串lpsz的信息。对于工具栏来说,SetWindowText可以认为是SetPaneText(0, 
  lpsz)的简化版本。</P>
  <P 
  align=justify>顺便指出,pMessageBar-&gt;GetParentFrame()返回主边框窗口,即使pMessageBar指向漂浮的工具条。关于泊位和漂浮,见后面13.2.5节的描述。</P>
  <P align=justify>关于OnSetText,其实现如下:</P>
  <P align=justify>LRESULT CStatusBar::OnSetText(WPARAM, LPARAM lParam)</P>
  <P align=justify>{</P>
  <P align=justify>ASSERT_VALID(this);</P>
  <P align=justify>ASSERT(::IsWindow(m_hWnd));</P>
  <P align=justify></P>
  <P align=justify>int nIndex = CommandToIndex(0); //返回0</P>
  <P align=justify>if (nIndex &lt; 0)</P>
  <P align=justify>return -1;</P>
  <P align=justify></P>
  <P align=justify>return SetPaneText(nIndex, (LPCTSTR)lParam) ? 0 : -1;</P>
  <P align=justify>}</P>
  <P align=justify></P>
  <LI>OnPopMessageString 
  <P></P></LI></OL>
<P align=justify>LRESULT CFrameWnd::OnPopMessageString(WPARAM wParam, </P>
<DIR>
<DIR>
<P align=justify>LPARAM lParam)</P></DIR></DIR>
<P align=justify>{</P>
<P align=justify>//WF_NOPOPMSG表示边框窗口不处理WM_POPMESSAGESTRING</P>
<P align=justify>if (m_nFlags &amp; WF_NOPOPMSG)</P>
<DIR>
<P align=justify>return 0;</P>
<P align=justify></P></DIR>
<P align=justify>//调用OnSetMessageString</P>
<P align=justify>return SendMessage(WM_SETMESSAGESTRING, wParam, lParam);</P>
<P align=justify>}</P>
<P align=justify>一般,在清除状态栏消息时,发送WM_POPMESSAGESTRING,通过消息参数wParam指定一个字符串资源,其ID 
为AFX_IDS_IDLEMESSAGE,对应的字符串是“Ready”。</P>
<OL>
  <OL>
    <OL>
      <OL>
        <P align=justify>
        <LI><A name=_Toc457299148></A><B>状态栏显示菜单项的提示信息</B> 
        <P></P>
        <P 
        align=justify>状态栏的一个重要作用是显示菜单命令或者工具条按钮的提示信息。本节讨论如何显示菜单命令的提示信息,关于工具条按钮在这方面的讨论见后面13.2.4.4章节。</P>
        <P 
        align=justify>显示菜单命令的提示信息,就是每当一个菜单项被选中之后,在状态栏显示该菜单的功能、用法等信息。这些信息以字符串资源的形式保存,字符串ID对应于菜单项的命令ID。</P>
        <P 
        align=justify>所以,必须处理菜单选择消息WM_MENUSELECT。CFrameWnd实现了消息处理函数OnMenuSelect,其实现如下:</P>
        <P align=justify>void CFrameWnd::OnMenuSelect(UINT nItemID, </P>
        <P align=justify>UINT nFlags, HMENU /*hSysMenu*/)</P>
        <P align=justify>{</P>
        <P align=justify>CFrameWnd* pFrameWnd = GetTopLevelFrame();</P>
        <P align=justify>ASSERT_VALID(pFrameWnd);</P>
        <P align=justify></P>
        <P align=justify>//跟踪被选中的菜单项</P>
        <P align=justify>if (nFlags == 0xFFFF)</P>
        <P align=justify>{</P>
        <P align=justify>//取消菜单操作</P>
        <P align=justify>m_nFlags &amp;= ~WF_NOPOPMSG;</P>
        <P align=justify>if (!pFrameWnd-&gt;m_bHelpMode)</P>
        <P align=justify>m_nIDTracking = AFX_IDS_IDLEMESSAGE;</P>
        <P align=justify>else</P>
        <P align=justify>m_nIDTracking = AFX_IDS_HELPMODEMESSAGE;</P>
        <P align=justify>//在状态栏显示</P>
        <P align=justify>SendMessage(WM_SETMESSAGESTRING, 
        (WPARAM)m_nIDTracking);</P>
        <P align=justify>ASSERT(m_nIDTracking == m_nIDLastMessage);</P>
        <P align=justify></P>
        <P align=justify>// update right away</P>
        <P align=justify>CWnd* pWnd = GetMessageBar();</P>
        <P align=justify>if (pWnd != NULL)</P>
        <P align=justify>pWnd-&gt;UpdateWindow();</P>
        <P align=justify>}</P>
        <P align=justify>else</P>
        <P align=justify>{</P>
        <P align=justify>//选中分隔栏、Popup子菜单或者没有选中一个菜单项</P>
        <P align=justify>if (nItemID == 0 || nFlags &amp; 
        (MF_SEPARATOR|MF_POPUP))</P>
        <P align=justify>{</P>
        <P align=justify>// nothing should be displayed</P>
        <P align=justify>m_nIDTracking = 0;</P>
        <P align=justify>}</P>
        <P align=justify>else if (nItemID &gt;= 0xF000 &amp;&amp; nItemID &lt; 
        0xF1F0) // max of 31 SC_s</P>
        <P align=justify>{</P>
        <P align=justify>//系统菜单的菜单项被选中</P>
        <P align=justify>m_nIDTracking = ID_COMMAND_FROM_SC(nItemID);</P>

⌨️ 快捷键说明

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