• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

窗口类的诞生(注册自己的窗口类)2

发布: 2007-7-01 20:40 | 作者: admin | 来源: | 查看: 13次 | 进入软件测试论坛讨论

领测软件测试网

我们现在再来看看AfxDeferRegisterClass是什么样子的:

 #define AfxDeferRegisterClass(fClass) \

 ((afxRegisteredClasses & fClass) ? TRUE:AfxEndDeferRegisterClass(fClass)

 #define afxRegisteredClasses AfxGetModuleState()->m_fRegisteredClasses

 BOOL AFXAPI AfxEndDeferRegisterClass(short fClass)

 {

 WNDCLASS wndCls;

 wndCls.lpfnWndProc = DefWindowProc;

 if(fClass & AFX_WND_REG)

 {

 wndCls.lpszClassName=_afxWnd;

 AfxRegisterClass(&wndCls);

 }else if(fClass & AFX_WNDOLECONTROL_REG)

 {

 wndCls.lpszClassName=_afxWndOleControl;

 AfxRegisterClass(&wndCls);

 }else if(fClass & AFX_WNDCONTROLBAR_REG)
{

 wndCls.lpszClassName=_afxWndControlBar;

 AfxRegisterClass(&wndCls);

 }else if(fClass & AFX_WNDMDIFRAME_REG)

 {

 RegisterWithIcon(&wndCls,_afxWndMDIFrame,AFX_IDI_MDIFRAME);

 }else if(fClass & AFX_WNDFRAMEORVIEW_REG)

 {

 RegisterWithIcon(&wndCls,_afxWndFrameOrView,AFX_IDI_STD_FRAME);

 }else if(fClass & AFX_WNDCOMMCTLS_REG)

 {

 InitCommonControls();

 }

 }

 从上面的代码可以看出,AfxDeferRegisterClass函数首先判断该窗口类是否注册,如已注册则直接返回,否则调用AfxEndDeferRegisterClass进行注册,即注册要求的默认窗口类。其中RegisterWithIcon和InitCommonControls最终也是转化为调用AfxRegisterClass,而AfxRegisterClass函数调用RegisterClass进行注册,啊,终于看到SDK中的RegisterClass了,看到它总有一种亲切感!

 有了上面的知识,我们就可以很容易摸清MFC是怎样注册窗口类的了!我们知道Windows上所有看得见的东西,在MFC中都是继承于CWnd类的,而CWnd类创建窗口的成员函数是Create和CreateEx,由于Create最终是调用CreateEx,所以我们只需要看CreateEx函数就行了:
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCSTSTR lpszClassName,

 …… LPVOID lpParam)

 {

 CREATESTRUCT cs;

 cs.dwExStyle = dwExStyle;

 … …

 cs.lpCreateParams = lpParam;

 PreCreateWindow(cs);

 AfxHookWindowCreate(this);

 HWND hWnd=::CreateWindowEx(cs.dwStyle,cs.lpszClass,…,cs.lpCreateParams);

 ……

 }

 啊,一看到CreateWindowEx,亲切感又来了,这不是和SDK中的CreateWindow一样嘛,是创建窗口!既然这样,那么注册窗口肯定在该函数之前,会是谁呢?如果你做过一点MFC程序,你就会对将眼光停留PreCreateWindow上。对!就是它了。

 PreCreateWindow函数是CWnd类的一个虚拟函数,提供程序设置待创建窗口的属性(包括窗口类),这样继承于CWnd的类都可以按照自己的要求在PreCreateWindow中设置自己的属性了,而且我们看到MFC也是这样做的:

 BOOL CWnd::PreCreateWindow(CREATESTRUCT &cs)

 {

 if(cs.lpszClass = = NULL)
{

 AfxDeferRegisterClass(AFX_WND_REG);

 cs.lpszClass = _afxWnd;

 }

 return TRUE;

 }

 BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT &cs)

 {

 if(cs.lpszClass = = NULL)

 {

 AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG);

 cs.lpszClass = _afxWndFrameOrView;

 }

 return TRUE;

 }

 BOOL CMDIFrameWnd::PreCreateWindow(CREATESTRUCT &cs)

 {

 if(cs.lpszClass = = NULL)
{

 AfxDeferRegisterClass(AFX_WNDMDIFRAME_REG);

 cs.lpszClass = _afxWndMDIFrame;

 }

 }

 BOOL CMDIChildWnd::PreCreateWindow(CREATESTRUCT &cs)

 {

 return CFrameWnd::PreCreateWindow(cs);

 }

 BOOL CView::PreCreateWindow(CREATESTRUCT &cs)

 {

 if(cs.lpszClass = = NULL)

 {

 AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG);

 cs.lpszClass = _afxWndFrameOrView;

 }

 }

 就是通过继承的方法,MFC实现常用类的窗口注册(代码并不完全,是从MFC中抽取对我们有意义的一部分代码)。

 四.在MFC中注册自己的窗口类

 在MFC中创建一个窗口,就必须是继承于CWnd类的,这样你的CMyWnd类自然就有了PreCreateWindow方法。你想注册有自己个性的窗口类,那么就在该函数中进行吧。也就是在PreCreateWindow函数中注册自己的窗口类,然后将窗口类的类名以及待创建窗口的其它属性(见CREATESTRUCT结构)填写cs,然后返回系统,供系统创建你的窗口。

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网