八宝书库 > 文学其他电子书 > 深入浅出MFC第2版(PDF格式) >

第79部分

深入浅出MFC第2版(PDF格式)-第79部分

小说: 深入浅出MFC第2版(PDF格式) 字数: 每页4000字

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




#define AFX_WNDMCTLS_REG      (0x0010) 

#define AFX_WNDOLECONTROL_REG     (0x0020) 



出现在上述函数中的五个窗口类别名称,分别定义于WINCORE。CPP  中: 



const TCHAR _afxWnd'' = AFX_WND; 

const TCHAR _afxWndControlBar'' = AFX_WNDCONTROLBAR; 

const TCHAR _afxWndMDIFrame'' = AFX_WNDMDIFRAME; 

const TCHAR _afxWndFrameOrView'' = AFX_WNDFRAMEORVIEW; 

const TCHAR _afxWndOleControl'' = AFX_WNDOLECONTROL; 



而等号右手边的那些AFX_ 常数又定义于AFXIMPL。H  中: 



#ifndef _UNICODE 

#define _UNICODE_SUFFIX 

#else 

#define _UNICODE_SUFFIX _T(〃u〃) 

#endif 



#ifndef _DEBUG 

#define _DEBUG_SUFFIX 

#else 

#define _DEBUG_SUFFIX _T(〃d〃) 

#endif 



#ifdef _AFXDLL 

#define _STATIC_SUFFIX 

#else 

#define _STATIC_SUFFIX _T(〃s〃) 

#endif 



#define AFX_WNDCLASS(s)  

  _T(〃Afx〃) _T(s) _T(〃42〃) _STATIC_SUFFIX _UNICODE_SUFFIX _DEBUG_SUFFIX 



#define AFX_WND                   AFX_WNDCLASS(〃Wnd〃) 

#define AFX_WNDCONTROLBAR         AFX_WNDCLASS(〃ControlBar〃) 

#define AFX_WNDMDIFRAME           AFX_WNDCLASS(〃MDIFrame〃) 

#define AFX_WNDFRAMEORVIEW        AFX_WNDCLASS(〃FrameOrView〃) 

#define AFX_WNDOLECONTROL         AFX_WNDCLASS(〃OleControl〃) 



                                                                               383 


…………………………………………………………Page 446……………………………………………………………

                    第篇    湷觥 FC  程式設計 



                    所以,如果在Windows 95         (non…Unicode )中使用MFC 动态联结版和除错版,五个窗口 



                    类别的名称将是: 



                        〃AfxWnd42d〃 

                        〃AfxControlBar42d〃 

                        〃AfxMDIFrame42d〃 

                        〃AfxFrameOrView42d〃 

                        〃AfxOleControl42d〃 



                    如果在Windows NT      (Unicode 环境)中使用MFC 静态联结版和除错版,五个窗口类 



                    别的名称将是: 



                        〃AfxWnd42sud〃 

                        〃AfxControlBar42sud〃 

                        〃AfxMDIFrame42sud〃 

                        〃AfxFrameOrView42sud〃 

                        〃AfxOleControl42sud〃 



                    这五个窗口类别的使用时机为何?稍后再来一探究竟。 



                    让我们再回顾AfxEndDeferRegisterClass  的动作。它调用两个函数完成实际的窗口类别注 



                    册动作,一个是RegisterWithIcon ,一个是AfxRegisterClass : 



                    static BOOL AFXAPI RegisterWithIcon (WNDCLASS* pWndCls; 

                            LPCTSTR lpszClassName; UINT nIDIcon) 

                    { 

                        pWndCls…》lpszClassName = lpszClassName; 

                        HINSTANCE hInst = AfxFindResourceHandle( 

                                MAKEINTRESOURCE(nIDIcon); RT_GROUP_ICON); 

                        if ((pWndCls…》hIcon = ::LoadIcon(hInst; MAKEINTRESOURCE(nIDIcon))) == NULL) 

                        { 

                            // use default icon 

                            pWndCls…》hIcon = ::LoadIcon(NULL; IDI_APPLICATION); 

                        } 

                        return AfxRegisterClass (pWndCls); 

                    } 



                    BOOL AFXAPI AfxRegisterClass (WNDCLASS* lpWndClass) 

                    { 

                        WNDCLASS wndcls; 



384 


…………………………………………………………Page 447……………………………………………………………

                                                         第6章    MFC 程式的生死因果 



    if (GetClassInfo(lpWndClass…》hInstance; 

                         lpWndClass…》lpszClassName; &wndcls)) 

    { 

        // class already registered 

        return TRUE; 

    } 



    ::RegisterClass(lpWndClass); 

    。。。 

    return TRUE; 

} 



注意,不同类别的PreCreateWindow 成员函数都是在窗口产生之前一刻被调用,准备用 



来注册窗口类别。如果我们指定的窗口类别是NULL ,那么就使用系统预设类别。从CWnd 



及其各个衍生类别的PreCreateWindow 成员函数可以看出,整个Framework 针对不同功 



能的窗口使用了哪些窗口类别: 



// 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

返回目录 上一页 下一页 回到顶部 0 0

你可能喜欢的