📄 c-c++ mfc.htm
字号:
lang=EN-US>Afx:b:14ae:6:3e8f</SPAN></FONT></P>
<P><FONT color=#000000><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用</SPAN><SPAN
lang=EN-US>Spy++</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">(</SPAN><SPAN
lang=EN-US>VC++</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所附的一个工具)观察窗口类的名称时,会发现窗口类名称变成像</SPAN><SPAN
lang=EN-US>Afx:b:14ae:6:3e8f</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这副奇怪的模样?</SPAN></FONT></P>
<P><FONT color=#000000><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">原来是</SPAN><SPAN
lang=EN-US>Application Framework </SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">把窗口类的名称转换为</SPAN><SPAN
lang=EN-US>Afx:</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:</SPAN>
<SPAN lang=EN-US>x </SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:</SPAN><SPAN
lang=EN-US>y </SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:</SPAN><SPAN
lang=EN-US>z </SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:</SPAN><SPAN
lang=EN-US>w</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的类型,成为独一无二的窗口类型名称:</SPAN></FONT></P>
<P><SPAN lang=EN-US><FONT color=#000000>x</FONT></SPAN><FONT
color=#000000><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:窗口风格的</SPAN><SPAN
lang=EN-US>hex</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值</SPAN></FONT></P>
<P><FONT color=#000000><SPAN lang=EN-US>y</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:窗口鼠标光标的</SPAN><SPAN
lang=EN-US>hex</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值</SPAN></FONT></P>
<P><FONT color=#000000><SPAN lang=EN-US>z</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:窗口后台颜色的</SPAN><SPAN
lang=EN-US>hex</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值</SPAN></FONT></P>
<P><FONT color=#000000><SPAN lang=EN-US>w</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:窗口图标的</SPAN><SPAN
lang=EN-US>hex</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值</SPAN></FONT></P>
<P><FONT color=#000000><SPAN lang=EN-US>7.<SPAN
style="FONT: 7pt 'Times New Roman'"> </SPAN>Serializable</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的必要条件</SPAN></FONT></P>
<P><FONT color=#000000><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"> 让一个对象有</SPAN><SPAN
lang=EN-US>Serializable</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">能力,它必须派生自一个</SPAN><SPAN
lang=EN-US>Serializable</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类,一个类要成为</SPAN><SPAN
lang=EN-US>Serializable</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,必须有下列五大条件:</SPAN></FONT></P>
<P><FONT color=#000000><SPAN lang=EN-US>(1)</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从</SPAN><SPAN
lang=EN-US>Cobject</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">派生下来,如此一来,可保有</SPAN><SPAN
lang=EN-US>RTTI</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、动态生成等机能</SPAN></FONT></P>
<P><FONT color=#000000>(2)<SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类的声明部分必须有</SPAN><SPAN
lang=EN-US>DECLARE_SERIAL</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏,此宏需要一个参数:类名称</SPAN></FONT></P>
<P><FONT color=#000000>(3)<SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类的实作部分必须有</SPAN><SPAN
lang=EN-US>IMPLEMENT_SERIAL</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏,此宏需要三个参数:一是类名称,二是基类名称,三是</SPAN>
<SPAN lang=EN-US>schema no.</SPAN></FONT></P>
<P><FONT color=#000000>(4)<SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">改写</SPAN><SPAN
lang=EN-US>Serialize</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">虚拟函数,使它能够适当地把类的成员变量写入档案中</SPAN></FONT></P>
<P><FONT color=#000000>(5)<SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为此类加上一个</SPAN><SPAN
lang=EN-US>default</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">构造函数(也就是无参数之构造函数),这个条件常为人所忽略,但它是必要的,因为若一个对象来自档案,</SPAN><SPAN
lang=EN-US>MFC</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">必须先动态生成它,而且在没有任何参数的情况下调用其构造函数,然后才从档案中读出对象数据。</SPAN></FONT></P>
<P><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT
color=#000000> 唉,好东东实在太多了,比如对</FONT></SPAN><FONT
color=#000000><SPAN lang=EN-US>MFC</SPAN><SPAN
style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">六大关键技术之仿真,三大宏的内部揭密等等(咦,我不是在推销这本书吧,呵呵)感兴趣的话请看看这本书吧,可以找我借哦,所谓“书非借不能读也”。呵呵</SPAN><SPAN
lang=EN-US>………</SPAN></FONT><FONT color=#000000><SPAN
lang=EN-US></SPAN></FONT></P></DIV></TD></TR></TBODY></TABLE><BR>
<TABLE height=1884 cellSpacing=1 cellPadding=1 width=758 align=center
bgColor=#000000 border=0>
<TBODY>
<TR bgColor=#5f7189>
<TD width="19%" background="C-C++ MFC.files/bg_bar.gif" bgColor=#ffffff
height=24><FONT color=#000000><STRONG>《深入浅出MFC》学习笔记之二</STRONG></FONT><FONT
color=#000000 size=4><STRONG><A id=VC3 name=VC3></A> </STRONG></FONT><FONT
color=#000000>(文章来源:龚建伟老师的技术主页http://www.gjwtech.com)</FONT><FONT
color=#000000 size=4> </FONT></TD></TR>
<TR bgColor=#5f7189>
<TD bgColor=#ffffff height=1861>
<P style="MARGIN-TOP: 1px"
align=justify> <BR>
MFC程序也是Windows程序,所以它也有一个WinMain,但是我们在程序中看不到它的踪影。实际上,在程序进入点之前,有一个(而且只有一个)全局对象(在Hello程序中名为theApp),这是所谓的application
object,当操作系统将程序加载并激活时,这个全局对象获得配置,其构造函数会先执行,比WinMain更早<SPAN lang=EN-US
style="FONT-SIZE: 12pt; COLOR: black"><O:P>。</O:P></SPAN></P>
<P
align=justify> 书中所举Hello程序,是一个简单的MFC程序,其主体在于WinMain和WndProc,而这两个部分其实都有相当程度的不变性。MFC就是把有着相当固定行为的WinMain内部操作封装在CWinApp中;把有着相当固定行为的WndProc内部操作封装在CFrameWnd中。也就是说,CWinApp代表程序本体,CFrameWnd代表一个主框窗口
</P>
<P
align=justify> 虽然WinMain和WndProc内部操作有相当程度的不变性,但面对不同应用程序也需有变化,所以必须以这两个类为基础,派生自己的类,并改写其中一部分成员函数。
</P>
<P align=justify>CWinApp----取代WinMain的地位 </P>
<P align=justify>传统上SDK程序的WinMain所完成的工作现由CWinApp的三个函数完成:<BR>virtual BOOL
InitApplication( );</P>
<P align=justify>virtual BOOL InitInstance( );</P>
<P align=justify>virtual BOOL Run( );</P>
<P align=justify>CFrameWnd-----取代WndProc的地位 </P>
<P align=justify>CFrameWnd主要用来掌握一个窗口</P>
<P align=justify>引爆器------Application object </P>
<P
align=justify> 当执行Hello程序时,这个全局对象产生,于是构造函数(见APPCORE.CPP)执行起来,CWinApp之中的成员变量将因为这个全局对象的诞生而获得配置与初值,配置完成后,WinMain(MFC早已准备好,并由链接器直接加到应用程序中去的)登场。
</P>
<P
align=justify> AfxWinInit:是继CWinApp构造函数之后的第一个操作;此后的操作是pApp->InitApplication(其中的pApp指向CMyWinApp对象,即本例中的theApp),因为CMyWinApp继承自CWinApp,而InitApplication又是CWinApp的一个虚拟函数,我们没有改写它(大部分情况下也不需要改它),所以上述操作相当于调用CWinApp::InitApplication。此程序的代码出现在APPCORE.CPP中;
</P>
<P
align=justify> 继InitApplication之后,AfxWinMain调用pApp->InitInstance,InitInstance是CWinApp的一个虚拟函数(应用程序一定要改写这个函数,因为它在CWinApp中是个空函数,没有任何默任操作),我们改写了它,所以上述操作就是调有我们自己的这个InitInstance函数,我们将在该处展开我们的主窗口生命。
</P>
<P
align=justify> CMyWinApp::InitInstance一开始new了一个CMyFrameWnd对象,new会引发构造函数CmyFrameWnd::CMyFrameWnd,其中调用了CFrameWnd的成员函数Create,它将产生一个窗口。
</P>
<P
align=justify> Create函数共八个参数,第一个,指定WNDCLASS窗口类,如果放置NULL,表示要以MFC内建的窗口类产生一个标准的外框窗口(Create函数在产生窗口之前会引发窗口类的注册操作,下一段讲述这一内容);第二个,指定窗口标题;第三个,指定窗口风格,默认是WS-OVERLAPPEDWINDOW,如果你不想要窗口右上角的极大极小钮,可以改成WS-OVERLAPPED|WS-CAPTION|WS-SYSMENU|WS-THICKFRAME|WS-MINIMIZEBOX|WS-MAXIMIZEBOX,如果希望有垂直滚动条,再加上WS-VSCROLL;第四个参数,指定窗口的位置与大小,默认值rectDefault
;第五个,指定父窗口,第六个指定菜单;第七个,为扩充风格,唯有以:CreateWindowEx(而非:CreateWindow)函数才能完成,事实上,CFrameWnd:Create最终调用的正是:CreateWindowEx;第八个,是一个指向CCreateContext结构的指针,framework利用它,在具备Document/View结构的程序中初始化外框窗口,默认值NULL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -