按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
能的窗口使用了哪些窗口类别:
// in WINCORE。CPP
BOOL CWnd::PreCreateWindow(CREATESTRUCT& cs)
{
{
AfxDeferRegisterClass(AFX_WND_REG);
。。。
cs。lpszClass = _afxWnd; (这表示CWnd 使用的窗口类别是_afxWnd)
}
return TRUE;
}
// in WINFRM。CPP
BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
if (cs。lpszClass == NULL)
{
AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG);
。。。
cs。lpszClass = _afxWndFrameOrView; (这表示CFrameWnd 使用的窗口
}
类别是_afxWndFrameOrView)
。。。
}
// in WINMDI。CPP
BOOL CMDIFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
385
…………………………………………………………Page 448……………………………………………………………
第篇 湷觥 FC 程式設計
{
if (cs。lpszClass == NULL)
{
AfxDeferRegisterClass(AFX_WNDMDIFRAME_REG);
。。。
cs。lpszClass = _afxWndMDIFrame; (这表示CMDIFrameWnd 使用的窗口
类别是_afxWndMDIFrame)
}
return TRUE;
}
// in WINMDI。CPP
BOOL CMDIChildWnd::PreCreateWindow(CREATESTRUCT& cs)
{
。。。
return CFrameWnd::PreCreateWindow(cs); (这表示CMDIChildWnd 使用的窗口
类别是 类别是 类别是_afxWndFrameOrView)
}
// in VIEWCORE。CPP
BOOL CView::PreCreateWindow(CREATESTRUCT & cs)
{
if (cs。lpszClass == NULL)
{
AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG);
。。。
cs。lpszClass = _afxWndFrameOrView; (这表示CView 使用的窗口
} 类别是_afxWndFrameOrView)
。。。
}
题外话:「Create 是一个比较粗糙的函数,不提供我们对图标(icon )或鼠标光标的设定,
所以在Create 函数中我们看不到相关参数」。这样的说法对吗?虽然「不能够让我们指
定窗口图标以及鼠标光标」是事实,但这本来就与Create 无关。回忆SDK 程序,指定
图标和光标形状实为RegisterClass 的责任而非CreateWindow 的责任!
MFC 程序的RegisterClass 动作并非由程序员自己来做,因此似乎难以改变图标。不过,
MFC 还是开放了一个窗口,我们可以在HELLO。RC 这么设定图标:
AFX_IDI_STD_FRAME ICON DISCARDABLE 〃HELLO。ICO〃
你可以从AfxEndDeferRegisterClass 的第55 行看出,当它调用RegisterWithIcon 时,指
定的icon 正是AFX_IDI_STD_FRAME。
386
…………………………………………………………Page 449……………………………………………………………
第6章 MFC 程式的生死因果
鼠标光标的设定就比较麻烦了。要改变光标形状,我们必须调用AfxRegisterWndClass (其
中有! ¨ Cursor! ¨ 参数)注册自己的窗口类别;然后再将其传回值(一个字符串)做为Create
的第一个参数。
奇怪的窗口类别名称 Afx:b:14ae:6:3e8f
当应用程序调用CFrameWnd::Create (或CMDIFrameWnd::LoadFrame,第7章)准备产
生窗口时,MFC 才会在Create 或LoadFrame 内部所调用的PreCreateWindow 虚拟函
式中为你产生适当的窗口类别。你已经在上一节看到了,这些窗口类别的名称分别是(假
设在Win95 中使用MFC 4。2 动态联结版和除错版):
〃AfxWnd42d〃
〃AfxControlBar42d〃
〃AfxMDIFrame42d〃
〃AfxFrameOrView42d〃
〃AfxOleControl42d〃
然而,当我们以Spy++ (VC++ 所附的一个工具)观察窗口类别的名称,却发现:
窗口类别名称怎么会变成像Afx:b:14ae:6:3e8f 这副奇怪模样呢?原来是Application
Framework 玩了一些把戏,它把这些窗口类别名称转换为Afx:x:y:z:w 的型式,成为独一
无二的窗口类别名称:
387
…………………………………………………………Page 450……………………………………………………………
第篇 湷觥 FC 程式設計
x: 窗口风格(window style )的hex
y: 窗口鼠标光标的hex 值 值
z: 窗口背景颜色的hex 值
w: 窗口图标(icon )的hex 值
如果你要使用原来的(MFC 预设的)那些个窗口类别,但又希望拥有自己定义的一个有
意义的类别名称,你可以改写PreCreateWindow 虚拟函数(因为Create 和LoadFrame
的内部都会调用它),在其中先利用API 函数GetClassInfo 获得该类别的一个副本,
更改其类别结构中的lpszClassName 字段( 甚至更改其hIcon 字段),再以
AfxRegisterClass 重新注册之,例如:
#0000 #define MY_CLASSNAME 〃MyClassName〃
#0001
#0002 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
#0003 {
#0004 static LPCSTR className = NULL;
#0005
#0006 if (!CFrameWnd::PreCreateWindow(cs))
#0007 return FALSE;
#0008
#0009 if (className==NULL) {
#0010 // One…time class registration
#0011 // The only purpose is to make the class name something
#0012 // meaningful instead of 〃Afx:0x4d:27:32:hup1hup:hike!〃
#0013 //
#0014 WNDCLASS wndcls;
#0015 ::GetClassInfo(AfxGetInstanceHandle(); cs。lpszClass; &wndcls);
#0016 wndcls。lpszClassName = MY_CLASSNAME;
#0017 wndcls。hIcon = AfxGetApp()…》LoadIcon(IDR_MAINFRAME);
#0018 VERIFY(AfxRegisterClass(&wndcls));
#0019 className=TRACEWND_CLASSNAME;
#0020 }
#0021 cs。lpszClass = className;
#0022
#0023 return TRUE;
#0024 }
本书附录D「以MFC 重建Debug Window (DBWIN )」会运用到这个技巧。
388
…………………………………………………………Page 451……………………………………………………………
第6章 MFC 程式的生死因果
窗口显示与更新
HELLO。CPP
1 CMyWinApp theApp; // application object
BOOL CMyWinApp::InitInstance()
WINMAIN。CPP
{
5
int AFXAPI AfxWinMain (。。。) m_pMainWnd = new CMyFrameWnd();
{ m_pMainWnd…》ShowWindow(m_nCmdShow);
7
CWinApp*