对WIN32中窗口的理解

写这篇文章记录下对win32编程窗口的理解。写这篇文章的时候我正在使用MFC编写一个适合我自己使用的任务清单软件。是的你没听错,就是十几年前你就已经听到的MFC,现在都老掉牙的MFC,新开发的程序已经没人用的MFC,还有一大堆基于其开发并且现在还需要维护的MFC。
以前一直不太理解窗口的概念,直白地认为是桌面上可见的窗口,包括程序的窗口,各种输入控件等。反正只要能用spy++捕捉到的东西,都叫窗口。直到后来有一次,想要用CWnd的派生类创建一个弹出窗口的时候,才有机会深入理解窗口创建的过程。
在这里还要扯一个MFC中窗口和窗口对象的概念。窗口是指向操作系统申请创建好的窗口对象(Windows API 中的CreateWindow),而CWnd对象是C++对象。而实例化一个C++对象并不意味着创建了一个窗口,而是在这个对象调用创建窗口的方法成功后Windows生成了一个窗口附加到这个CWnd对象(通过给m_hWnd赋值),让CWnd方便管理窗口。

我的需求是这样的:
在一个对话框程序的基础上,弹出若干具有POPUP属性的新窗口,要求窗口可以和主窗口之间切换,不能覆盖。(查资料发现,只要窗口具有owner或者parent,那么在显示的时候,永远都是子窗口覆盖父窗口、所有者窗口)。
然后我天真地这样做:

class CDerivedClass : public CWnd

CDerivedClass wnd;
wnd.create(NULL,NULL,WS_POPUP| WS_VISIBLE,CRect(),this,101010 );

这么做得出一个错误:CWnd::Create不能创建具有POPUP属性的窗口,并提示使用CreateEx
那么就
wnd. CreateEx(0, 0, NULL, WS_VISIBLE, 0,0 , 200, 200, 0, 0);
这样一来,上面那个提示没有了,但是窗口却没有注册成功,成员变量m_hWnd一直为NULL。查询输出发现有个GetLastError()为 0x578 (错误的窗口句柄)

原地抓狂一分钟。。。

查找了好些资料之后发现,原来是我没有指定窗口类(WNDCLASS)。那窗口类是个什么东西呢?百度百科之后发现原来创建窗口的过程需要注册一个窗口类型,这个窗口类型描述了这个窗口一些状态,比如窗口风格、标题、背景之类的。那为什么使用CWnd的Create又能生成窗口呢?原来CWnd的Create里面会检查如果没有指定窗口类就使用默认的预注册好的窗口类(可参考 AfxRegisterWndClass )。
好嘛,那就这样来咯:
wnd. CreateEx(AfxRegisterWndClass(NULL), 0, NULL, WS_VISIBLE, 0,0, 200, 200, 0, 0);
竟然成功了!!
然而就在我以为可以继续往下编写的时候发现创建出来的窗口在竟然会在任务栏下有按钮。。。

然而这已经不是主要问题了,隐藏窗口的任务栏按钮,只需要增加一个 WS _ EX _ TOOLW INDOW

好啦,总结一下:
其实MFC根本没有另外实现一套窗口的创建过程,只是巧妙地封装了windows api创建窗口的过程。
一般正常情况下,窗口的窗口的创建过程包括:
1.注册窗口类
2.根据所注册的窗口类生成一个窗口对象。 只有在创建窗口过程返回成功,才意味着一个窗口的真正创建

目前运行的效果如下:

任务栏上只有1个窗口,并且所有的窗口都可以相互重叠。完美。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值