深入浅出MFC第2版(PDF格式)-第77部分
按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
WINMAIN。CPP BOOL CMyWinApp::InitInstance()
{
int AFXAPI AfxWinMain (。。。) m_pMainWnd = new CMyFrameWnd();
{ m_pMainWnd…》ShowWindow(m_nCmdShow);
CWinApp* pApp = AfxGetApp(); m_pMainWnd…》UpdateWindow();
return TRUE;
2 }
AfxWinInit(。。。);
3 CMyFrameWnd::CMyFrameWnd()
pApp…》InitApplication();
pApp…》InitInstance(); {
4
nReturnCode = pApp…》Run(); Create(NULL; 〃Hello MFC〃; 。。。;
〃MainMenu〃);
AfxWinTerm(); }
}
void CMyFrameWnd::OnPaint() { 。。。 }
void CMyFrameWnd::OnAbout() { 。。。 }
BEGIN_MESSAGE_MAP(CMyFrameWnd; CFrameWnd)
ON_MAND(IDM_ABOUT; OnAbout)
ON_WM_PAINT()
END_MESSAGE_MAP()
继InitApplication 之后,AfxWinMain 调用pApp …》InitInstance 。稍早我说过了,pApp 指向
CMyWinApp 对象(也就是本例的theApp ),所以,当程序调用:
pApp…》InitInstance();
相当于调用
CMyWinApp::InitInstance();
但是你要知道,CMyWinApp 继承自CWinApp,而InitInstance 又是CWinApp 的一个虚
拟函数。由于我们改写了它,所以上述动作的的确确就是调用我们自己(CMyWinApp)
的这个InitInstance 函数。我们将在该处展开我们的主窗口生命。
374
…………………………………………………………Page 437……………………………………………………………
第6章 MFC 程式的生死因果
APPCORE。CPP
base class virtual BOOL InitApplication();
virtual BOOL InitInstance();
CWinApp
virtual int Run();
virtual int ExitInstance();
HELLO。CPP overridden
virtual BOOL InitInstance();
CMyWinApp
derived class
般而言,CMyWinApp 只改寫
CWinApp 的 InitInstance ,通常
它不改寫 InitApplication 和 Run 。
注意:应用程序一定要改写虚拟函数InitInstance ,因为它在CWinApp 中只是个空函数,
没有任何内建(预设)动作。
375
…………………………………………………………Page 438……………………………………………………………
第篇 湷觥 FC 程式設計
CFrameWnd::Create 产生主窗口(并先注册窗口类别)
HELLO。CPP
1 CMyWinApp theApp; // application object
BOOL CMyWinApp::InitInstance()
WINMAIN。CPP
{
int AFXAPI AfxWinMain (。。。) 5 m_pMainWnd = new CMyFrameWnd();
{ m_pMainWnd…》ShowWindow(m_nCmdShow);
CWinApp* pApp = AfxGetApp(); m_pMainWnd…》UpdateWindow();
return TRUE;
2 }
AfxWinInit(。。。);
3 CMyFrameWnd::CMyFrameWnd()
pApp…》InitApplication();
pApp…》InitInstance(); {
4
6 Create(NULL; 〃Hello MFC〃; 。。。;
nReturnCode = pApp…》Run();
〃MainMenu〃);
AfxWinTerm(); }
}
void CMyFrameWnd::OnPaint() { 。。。 }
void CMyFrameWnd::OnAbout() { 。。。 }
BEGIN_MESSAGE_MAP(CMyFrameWnd; CFrameWnd)
ON_MAND(IDM_ABOUT; OnAbout)
ON_WM_PAINT()
END_MESSAGE_MAP()
CMyWinApp ::InitInstance 一开始new 了一个CMyFrameWnd 对象,准备用作主框窗口
的C++ 对象。new 会引发构造式:
CMyFrameWnd::CMyFrameWnd
{
Create(NULL; 〃Hello MFC〃; WS_OVERLAPPEDWINDOW; rectDefault; NULL;
〃MainMenu〃);
}
其中Create 是CFrameWnd 的成员函数,它将产生一个窗口。但,使用哪一个窗口类别
呢?
这里所谓的「窗口类别」是由RegisterClass 所注册的一份数据结构,不是C++ 类别。
根据CFrameWnd::Create 的规格:
376
…………………………………………………………Page 439……………………………………………………………
第6章 MFC 程式的生死因果
BOOL Create( LPCTSTR lpszClassName;
LPCTSTR lpszWindowName;
DWORD dwStyle = WS_OVERLAPPEDWINDOW;
const RECT& rect = rectDefault;
CWnd* pParentWnd = NULL;
LPCTSTR lpszMenuName = NULL;
DWORD dwExStyle = 0;
CCreateContext* pContext = NULL );
八个参数中的后六个参数都有默认值,只有前两个参数必须指定。第一个参数
lpszClassName 指定WNDCLASS 窗口类别,我们放置NULL 究竟代表什么意思?意思
是要以MFC 内建的窗口类别产生一个标准的外框窗口。但,此时此刻Hello 程序中根
本不存在任何窗口类别呀!噢,Create 函数在产生窗口之前会引发窗口类别的注册动
作,稍后再解释。
第二个参数 lpszWindowName 指定窗口标题,本例指定〃Hello MFC〃。第三个参数
dwStyle 指定窗口风格,预设是WS_OVERLAPPEDWINDOW,也正是最常用的一种,它
被定义为(在WINDOWS。H 之中):
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION |
WS_SYSMENU | WS_THICKFRAME |
WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
因此如果你不想要窗口右上角的极大极小钮,就得这么做:
Create(NULL;
〃Hello MFC〃;
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
rectDefault;
NULL;
〃MainMenu〃);
如果你希望窗口有垂直滚动条,就得在第三个参数上再加增WS_ VSCROLL 风格。
除了上述标准的窗口风格,另有所谓的扩充风格,可以在Create 的第七个参数
dwExStyle 指定之。扩充风格唯有以::CreateWindowEx (而非::CreateWindow)函数才能
完成。事实上稍后你就会发现,CFrameWnd::Create 最终调用的正是::CreateWindowEx。
Windows 3。1 提供五种窗口扩充风格:
377
…………………………………………………………Page 440……………………………………………………………
第篇 湷觥 FC 程式設計
WS_EX_DLGMODALFRAME
WS_EX_NOPARENTNOTIFY
WS_EX_TOPMOST
WS_EX_ACCEPTFILES
WS_EX_TRANSPARENT
Windows 95 有更多选择,包括WS_EX_WINDOWEDGE 和WS_EX_CLIENTEDGE,让
窗口更具3D 立体感。Framework 已经自动为我们指定了这两个扩充风格。
Create 的第四个参数rect 指定窗口的位置与大小。默认值rectDefault 是CFrameWnd
的一个static 成员变量,告诉Windows 以预设方式指定窗口位置与大小,就好象在
SDK 程序中以CW_ USEDEFAULT 指定给CreateWindow 函数一样。如果你很有主见,
希望窗口在特定位置有特定大小,可以这么做:
Create(NULL;
〃Hello MFC〃;
WS_OVERLAPPEDWINDOW;
起始位置 ,寬 ,高 )
CRect(40; 60; 240; 460); // (40;60) 200 400
NULL;
〃MainMenu〃);
第五个参数pParentWnd 指定父窗口。对于一个top…level 窗口而言,此值应为NULL ,
表示没有父窗口(其实是有的,父窗口就是desktop 窗口)。
第六个参数lpszMenuName 指定菜单。本例使用一份在RC 中准备好的菜单
! § MainMenu! ¨ 。第八个