加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 改进WM_PAINT和WM_CTLCOLORSTATIC处理程序的代码

发布时间:2020-12-16 07:06:20 所属栏目:百科 来源:网络整理
导读:介绍及相关资料: 我已经实现了主窗口背景及其子静态控件的复杂绘制. 下图显示了它的外观. 静态控件具有SS_NOTIFY样式,这一点很重要,因为当用户点击它们时会发生某些事情. 此时,单击它们时激活的操作不相关. 主窗口和静态控件都具有渐变背景,这是通过使用Gra
介绍及相关资料:

我已经实现了主窗口背景及其子静态控件的复杂绘制.

下图显示了它的外观.

静态控件具有SS_NOTIFY样式,这一点很重要,因为当用户点击它们时会发生某些事情.

此时,单击它们时激活的操作不相关.

主窗口和静态控件都具有渐变背景,这是通过使用GradientFill(…)API实现的.

使用灰色画笔创建主窗口的顶部横幅,并使用LineTo(…)和MoveTo(…)API创建网格线.

在橙色静态控件上映射,左上角的徽标是EMF文件,右上角的徽标是PNG文件,其他图片是位图.

橙色静态控件有4个子静态控件,它们是所有者绘制的,并且还具有SS_NOTIFY样式.

这是我能想到的唯一方式,这使我能够按照我的要求绘制控件(如果我可以改进,请提出建议,我会接受任何合理的建议).

为了绘制橙色静态控件,我决定在WM_CTLCOLORSTATIC处理程序中绘制其背景,并在所有者中绘制子类过程中的子静态控件.

从子静态控件接收的通知也在橙色静态控件子类过程中处理,因为我不知道如何将它们转发到父窗口,但由于它们此时也无关紧要而被省略.

我决定提供演示项目的链接,而不是使用代码片段使这篇文章相当冗长.

我试图尽可能小而简单地提交演示应用程序.

我没有吝啬评论,所以我相信一切都很好,并在源代码中解释.

如果仍有问题,请发表评论,我会尽快回复(通常是立即,或至少在同一天).

以下是演示项目的链接:http://www.filedropper.com/geotermistgrafika_1

重要更新:

/ ================================================= ========= /

方括号中的文字是问题的原始部分,但现在省略了,因为项目有内存泄漏.上面的链接链接到改进的版本.

[更新以回应成员xMRi的评论:此链接应该没问题:http://www.filedropper.com/geotermistgrafika]

/ ================================================= ========= /

我在Windows XP上工作,使用MS Visual Studio C和纯Win32 API.

一个注意事项:由于VS的Express版本没有资源编辑器,因此使用ResEdit从这里创建资源文件和资源头:http://www.resedit.net/.

问题:

当我调整窗口大小时,静态控件会略微闪烁.

我努力解决问题:

我相信我的代码没有内存泄漏 – 因此我怀疑这是问题所在,但由于缺乏经验,如果我的假设可以某种方式得到确认,我将非常感激.

我认为我已经正确处理了WM_ERASEBKGND,并且我已经从我的窗口类中排除了CS_VREDRAW和CS_HREDRAW样式 – 因此不应该因此引起闪烁.

我忘了提一下,我的窗口有WS_CLIPCHILDREN样式,所以我现在提到这一点,以回应成员Roger Rowland的评论.

我为这两个处理程序实现了双缓冲,以避免闪烁.

问题:

>如何修改演示项目中的代码以消除闪烁?
>我需要有关如何优化WM_PAINT和WM_CTLCOLORSTATIC处理程序的建议,因此我的绘图代码变得更有效,更快.

第二个问题的小注:

我想通过在主窗口的背景上绘制整个图片来改进我的代码,并将透明的静态控件放在与静态控件背景相对应的图片部分的顶部.

这样,我只会在WM_CTLCOLORSTATIC处理程序中返回NULL_BRUSH,并在WM_PAINT中完成所有工作.

这个想法我在正确的轨道上吗?这可行吗?

谢谢.
问候.

解决方法

首先,你的应用程序漏洞了.没有找到泄漏,但大多数应该在WM_CTLCOLORSTATIC,因为你忘了删除HBITMAP(使用这个整洁的免费软件 http://www.nirsoft.net/utils/gdi_handles.html来寻找gdi泄漏).

其次,你的代码是大的.我注意到你没有使用函数,可能是因为你不知道它们的功能.例如,我会使用:

void DrawBackground(HDC &hDC,SOMEINFOSTRUCT GradientInfo,LPCTSTR Text);

简化你的代码很多.

无论如何,演讲,让我们回到你的问题.在WM_CTLCOLORSTATIC中你必须返回画笔,你想要用背景画.你现在正在做的是使用Bitblt()手动绘制背景,然后返回NULL画笔并在你已绘制的背景上绘制程序.而不是自己绘画,让刷子完成工作.
只是代替最后一个Bitblt()使用CreatePatternBrush(),但是你需要照顾这个画笔,这是你应该做的:

HBRUSH TempBrush = NULL; //Create global brush

//Some Code....

case WM_CTLCOLORSTATIC:
    {
        if (TempBrush != NULL)
        {
            DeleteObject(TempBrush);
            TempBrush = NULL;
        }

        //Let's skip to the end....
        GradientFill( MemDC,vertex3,3,&gTriangle,1,GRADIENT_FILL_TRIANGLE );

        TempBrush  = CreatePatternBrush(bmp);// these 3 line should be at the 
                                            //end of every if
        DeleteDC(MemDC);      // or put them once outside if's
        DeleteObject(bmp);  // also if you delete HDC first,you don't need to
                            //unselect hbitmap
        }
        return (LRESULT)TempBrush;
    }
    break;

case WM_CLOSE:
        {
            if (TempBrush != NULL)
            {
                DeleteObject(TempBrush);
                TempBrush = NULL;
            }
//.......

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读