• 笔记: c开发gui程序 (WM_CREATE, WS_CLIPCHILDREN , SetWindowPos)


    过去两年,用c写的gui程序我一般使用的套路是:

    在 winMain()中, 先创建一个主窗口, 紧接着就是在下面创建子窗口(子控件).

    可能是因为写这方面的程序较少,所以也没遇到什么大问题,之前就是想枚举主窗口所有子窗口,然后设置所有子窗口的字体时使用:EnumChildWindows()会意外的抛内存访问错误,记得当时就是把EnumChildWindows()在winMain()中向前或向后移了一下位置,就没有报内存访问错误了。

    我还以为只需要移动一下EnumChildWindows()在winMain()中的执行位置(顺序),这个问题就解决了。

    但今天在修改以前一个程序的时候,无意间发现一个奇怪现象:

    在winMain()中定义的一个局部变量的值竟然被意外的修改,这个局部变量初始化后,在接下来的代码是并没有显式的去修改这个变量的值,但为什么执行了几行代码后,再次输出这个变量的值时,发现这个变量的值已经被修改了?

    经过几十分钟的一行一行的排查,首先找到有关的执行代码又是:EnumChildWindows()

    可在EnumChildWindows()中并没有任何地方会修改这个局部变量的值,如果我注销掉EnumChildWindows()这一行,那么这个局部变量的值就不会被修改,当时是百思不得其解!因为这个问题,差不多花了2个小时左右的时间不断的测试,最后也不知怎么想到把 初始化子窗口和设置子窗口的字体的代码移到 WM_CREATE中执行的,但没想到把代码移到WM_CREATE中执行后,那个局部变量的值就没有再被修改了。

    其实之前我在网上看到一些代码中,基本上都是在 case WM_CREATE: 中添加子窗口(初始化主窗口里所有控件).

    我当时还不是太明白,为什么要在WM_CREATE中初始化子窗口呢?我一般都是在winMain()中初始化的。

    经过这一次问题后,以后再写新的代码,把子窗口的初始化也放到 case WM_CREATE: 中执行吧

    ---------------------------------------------------------------------------------------------------------------------------------------

    今天还遇到另一个问题,就是刷新一个子窗口时,窗口出现闪烁问题。

    情况是这样的,在一个子窗口A里又有20个子窗口,并且拉动子窗口A的垂直滚动条,里面的20个子窗口会同时移动,移动后就需要刷新才能显示最新的位置,但刷新的时间会出现闪烁。

    为了解决这个问题,试了各种办法,由于我在纯C(SDK)模式下进行开发,网上相关资料也不是很多。

    后来无意发现一篇文章提到:WS_CLIPCHILDREN,说把窗口样式设置为WS_CLIPCHILDREN,就可以解决刷新闪烁的问题。

    一开始,我把主窗口设置为WS_CLIPCHILDREN,测试发现果然有效果,刷新时基本上很肉眼看不出闪烁,但是同时出现2个新的问题:

    1. 有些滚动条在经典模式下,用鼠标点击向上或向下按钮时,没有显示为按下去的效果,但在xp模式下又能看出来效果

    2. 在ListView控件中,拖动鼠标选择多个item时,那个选择虚线框闪一下就自动消失了,这个情况有点麻烦了。

    原以为找到了解决办法,没想到原来的问题是解决了,现在又出现新的问题。

    后来我又试了一下,主窗口不设置为WS_CLIPCHILDREN,单独为那个子窗口A设置为WS_CLIPCHILDREN:

    CreateWindowEx(WS_CLIPCHILDREN, "CodeBlocksWindowsApp", "panel", //注意: WS_CLIPCHILDREN
                                    WS_CHILD | WS_VISIBLE | SS_BITMAP | WS_VSCROLL, // | SS_NOTIFY | WS_BORDER
                                    650, 56, 260, 600,
                                    hwnd_frame, (HMENU)id_panel, g_hInstance, NULL);

    这样就有点类似于Java中的JPanel。

    通过测试发现,把子窗口A设置为WS_CLIPCHILDREN后,子窗口A的滚动条效果上还是有一点问题,不过 listview在选择的时候,选择虚线框不会闪一下就自动消失了。同时也解决了刷新闪烁的问题。

    目前,也只能这样了。

    另外一个意外发现,当将窗口样式设置为:WS_CLIPCHILDREN,使用 SetWindowPos(...HWND_TOP) 调整子窗口的 z-order才有效果。 

    2013-05-10

  • 相关阅读:
    架构设计
    Asp.net MVC突然变慢,缓存消失的一种原因
    B2C电子商务系统研发——商品SKU分析和设计(二)
    ASP.NET MVC下基于异常处理的完整解决方案
    【C#.NET】利用FastDFS打造分布式文件系统
    C#
    50个必备的实用jQuery代码段
    可视化组件库(The Visual Component Library)
    TortoiseHg 2.2.2
    企业信息开发平台
  • 原文地址:https://www.cnblogs.com/personnel/p/4584890.html
Copyright © 2020-2023  润新知