文章收藏-FAQ 位置:电脑学习网

Windows 精解:窗口类释疑

    从如何进行Windows SDK编程开始,我希望可以借此补充一下Windows编程的一些背景知识。之所以这样,是因为在我前面介绍“SW系统的窗口类”时,假设了读者对Windows界面编程已经有一定的了解。上一篇主要从介绍“如何用”的角度阐述Windows编程。但是我个人习惯“打破沙锅问到底”,很多东西是靠“悟”,而不是“记”。所以这一篇我们聊聊Windows SDK为何会是如今这个样子的。

    对于一个经典的WinMain函数,通常包含三步:

    注册窗口类(RegisterClass)。
    创建并显示窗口(CreateWindow and ShowWindow)。
    消息循环(MessageLoop)。即:取得消息 -〉 分派消息 -〉 处理消息。
    窗口程序需要“创建并显示窗口”,这显而易见。关于“消息循环”也容易理解,并且我们在“SW系统简介”中描述已经得非常详细。

    我相信最令人迷惑的是:“窗口类”是什么概念?为什么需要RegisterClass?

    有人回答:“窗口类”是同类窗口的公共属性,是这一类窗口的共享数据。
    有人回答:“窗口类”是同类窗口的默认数据(属性)。

    回答窗口类数据是共享数据的,错误。因为我们知道每一个窗口都有自己独立的菜单、图标、窗口过程(WindowProc,这个最重要了)等等。它们并不存在共享关系。回答是默认数据(属性)的,正确,但没有回答为什么需要默认属性,更没涉及到更为重要的原因。

    我们先来看看CreateWindow与CreateDialog的原型:

    HWND CreateWindow(
        LPCTSTR lpClassName,
        LPCTSTR lpWindowName,
        DWORD dwStyle,
        int x,
        int y,
        int nWidth,
        int nHeight,
        HWND hWndParent,
        HMENU hMenu,
        HINSTANCE hInstance,
        LPVOID lpParam
    );HWND CreateDialog(
        HINSTANCE hInstance,
        LPCTSTR lpTemplate,
        HWND hWndParent,
        DLGPROC lpDialogFunc
    );
    为什么普通窗口(Window)的创建不是象对话框(Dialog)一样,直接把窗口过程(WindowProc)传进去,甚至把其他窗口类相关的数据全部直接在CreateWindow时传入?也许有人回答说,这是为了减少CreateWindow的参数个数。——呵呵,我还真不知道怎么去证明这种说法是错的。但是我固执的认为我下面给出的理由要充分些。

    听说过序列化(Searialize)技术吗?有读者马上回答:知道,这是MFC中把对象写入磁盘和从磁盘中读入并还原出这些对象的技术。这个回答我给它4分(满分5分)。是的,序列化(Searialize)是对象持久化和还原的技术。但这不是MFC才开始有,而是DOS下Turbo Vision就已经有的一个技术。

    对话框是什么?对话框其实是支持了序列化(Searialize)技术的特殊窗口,它在初始化的时候,从资源中还原(创建)出它的各个子窗口。只是,与普通序列化(Searialize)不太一样的是,对象持久化过程不是对话框做,而是对话框编辑器负责的。

    无疑,基于对话框进行可视化编程是相当友好的。那么,从支持这种可视化编程的角度来看,我们需要支持序列化(Searialize),需要从磁盘中创建窗口。我们再回头看看CreateWindow函数的原型,你将发现,这些参数是“可序列化(可存盘)”的。而且,你立刻意识到,窗口过程(WindowProc)是不可序列化的。

    我们知道,序列化技术需要RuntimeClass技术进行对象的动态创建。而所谓的RuntimeClass技术,无非是建立了类唯一标识(如类名、GUID等)到类创建函数(其他的附属数据是比较次要的)的映射而已。

    现在到了关键:为了支持从磁盘还原窗口对象,Windows需要引入窗口类名,并建立它与窗口过程(WindowProc)的映射。——这正是RegisterClass存在的意义。而RegisterClass中其他的窗口类属性是次要的,并且也许前面说得没错,这些属性的存在,只是为了减少CreateWindow函数的参数个数。

    补充:点击这里了解RuntimeClass与Searialize的实现机理。

    补充:“绅士亦花心”提到了GDI资源的共享问题。应当承认,我前面说“窗口类数据是共享数据”这种说法错误,是比较武断的说法。是的,Windows必须面对GDI资源的共享问题,不同窗口亦存在资源共享的事实。更为合理的说法是:每一个窗口可以独立设置自己的菜单、图标、窗口过程,但菜单/图标等GDI资源是可以共享的。因为我们知道,Windows对GDI资源的共享策略是,窗口不拥有GDI资源(菜单/图标等)的所有权,用户必须为GDI资源的生命周期负责。换句话说,窗口只拥有菜单/图标句柄。

     [文章来源:“十万个为什么”电脑学习网]
     [网络地址:http://why100000.com]
     [版权声明:除本站部分特别声明禁止转载的专稿外,其他的文章可以自由转载,但请务必注明出处和原始作者。本站文章版权归文章原作者所有。如果本站转载的文章有版权问题请联系本站,我们会尽快予以更正。]
 

【字体:[大] [中] [小] 【加入收藏】 【发表评论】 【关闭本窗口】

Copyright © “十万个为什么”电脑学习网 2000-2007 陕ICP备06007929号
站务联系:MSN & Email:zhangking2008@gmail.com  QQ:9365822