GDI+在界面开发中遇到的问题汇总

UpdateLayeredWindow方式实现异型窗口 使用该种方法要注意几个问题: 1. 窗口属性必须是Top Window,子窗口(Win8之前的操作系统)不支持实现异形窗口 2. Layer Window没有WM_PAINT消息,需要自己调用OnPaint 3. 窗口属性可设置为 WS_POPUP | WS_VISIBLE, WS_EX_TOOLWINDOW | WS_EX_LAYERED 实现代码: CDC 阅读详情

字体相关

一、利用UpdateLayeredWindow,在GDI+绘制字体时,FontStyleRegular样式的字体会变成透明,而其它的样式都可以正常显示;

问题的原因是:
层窗口(WS_EX_LAYERED),用UpdateLayeredWindow输出的文字(用常规方法输出的:TextOut、DrawText、DrawString...),并且设置了AC_SRC_ALPHA和ULW_ALPHA,就会存在这种错误。
解决办法:

[cpp]  view plain copy
  1. void CGDIPlus_TextTestDlg::Redraw()  
  2. {  
  3.   CRect rect;  
  4.   GetClientRect(&rect);  
  5.   SolidBrush brush(Color(200,255,0,0));  
  6.   m_pGraphics->FillRectangle(&brush,0,0,rect.Width(),rect.Height());  
  7.   
  8.   CFont *pFont=GetFont();  
  9.   LOGFONT lf;  
  10.   pFont->GetLogFont(&lf);  
  11.   CComBSTR wszFN(lf.lfFaceName);  
  12.   int nHeight=-lf.lfHeight;  
  13.   FontFamily ff(wszFN,NULL);  
  14.   int nStyle=FontStyleRegular;  
  15.   Font font(&ff,nHeight,nStyle,UnitPixel);  
  16.   StringFormat format;  
  17.   format.SetAlignment(StringAlignmentNear);  
  18.   SolidBrush brush2(Color(255,0,0,0));  
  19.   int nStyle2=FontStyleBold;  
  20.   Font font2(&ff,nHeight,nStyle2,UnitPixel);  
  21.   
  22.   
  23.   //-----直接写字,变得穿透了  
  24.   CComBSTR wsz("文字Test: 直接写字,变得穿透了");  
  25.   m_pGraphics->DrawString(wsz,wsz.Length(),&font,PointF(50,50),&format,&brush2);  
  26.   
  27.   //-----文字加粗  
  28.   wsz="文字Test: 文字加粗";  
  29.   m_pGraphics->DrawString(wsz,wsz.Length(),&font2,PointF(50,70),&format,&brush2);  
  30.   
  31.   //-----SetTextRenderingHint(TextRenderingHintAntiAlias)  
  32.   wsz="文字Test: SetTextRenderingHint(TextRenderingHintAntiAlias)";  
  33.   GraphicsContainer gc=m_pGraphics->BeginContainer();  
  34.   m_pGraphics->SetTextRenderingHint(TextRenderingHintAntiAlias);  
  35.   m_pGraphics->DrawString(wsz,wsz.Length(),&font,PointF(50,90),&format,&brush2);  
  36.   m_pGraphics->EndContainer(gc);  
  37.   
  38.   //-----GraphicsPath  
  39.   wsz="文字Test: GraphicsPath";  
  40.   gc=m_pGraphics->BeginContainer();  
  41.   m_pGraphics->SetSmoothingMode(SmoothingModeHighQuality);  
  42.   GraphicsPath path(FillModeAlternate);  
  43.   path.AddString(wsz,wsz.Length(),&ff,nStyle,nHeight,PointF(50,110),&format);  
  44.   m_pGraphics->FillPath(&brush2,&path);  
  45.   m_pGraphics->EndContainer(gc);  
  46.   
  47.   SIZE sizeWindow = rect.Size();  
  48.   POINT ptSrc = { 0, 0 };  
  49.   BLENDFUNCTION blend;  
  50.   blend.BlendOp = AC_SRC_OVER;  
  51.   blend.BlendFlags = 0;  
  52.   blend.AlphaFormat = AC_SRC_ALPHA;  
  53.   blend.SourceConstantAlpha = 255;  
  54.   UpdateLayeredWindow(m_hWnd, hdcHWND, NULL, &sizeWindow, hdcHBMP, &ptSrc, 0, &blend, ULW_ALPHA);  
  55. }  
有三个方法避免,但是都不是真正的解决这个问题
第一个方法是字体加宽,把字体的Weight改成800就不会透
第二个方法是SetTextRenderingHint(TextRenderingHintAntiAlias)
第三个方法是把字串转换成GraphicsPath,然后用FillPath画出来,画之前SetSmoothingMode(SmoothingModeHighQuality)字会好看一点

不过,这三种方法都改变了字画出来的样子,第一种方法字被加粗了,第二三种方法字被抗锯齿了。找到一个简单的方法同时避免穿透和变形的问题,把Color的Alhpa值改成254就好了。使用DrawString + A->254 没问题。

二、直接在桌面写字,字体有阴影!

如下段代码,点(100,10)是在透明区,所以也就是直接将文字写在了桌面上:

[cpp]  view plain copy
  1. Graphics grpah(m_hDcBackground);  
  2. FontFamily ff(L"微软雅黑");  
  3. Font font(&ff,14,FontStyleBold ,UnitPixel);  
  4. StringFormat format;  
  5. format.SetAlignment(StringAlignmentCenter);  
  6. grpah.DrawString(L"不会出问题吧",-1,&font,PointF(100,10),&format,&SolidBrush(Color(254,0,255,0)));  
  7. grpah.ReleaseHDC(m_hDcBackground);  
效果:

看到啦,后面有黑色阴影;
解决办法:
加上一条语句:
[cpp]  view plain copy
  1. <span style="color:#000000;">grpah.SetTextRenderingHint(TextRenderingHintAntiAlias);</span>  
也就是说更改了原字体的绘制方式;
 这样就对了,但总感觉模糊了很多。

其它

2、HBITMAP与DC的关系?

DC与HBITMAP的关系就好比是叫一个人去某目的地进行演出,而HBITMAP就好比是为这个人演出提供的设备,搭建演出舞台供DC去演绎,展示,同时HBITMAP保存演绎的信息直到调用 DeleteObject(m_hBitmap)并将m_hBitmapBk = NULL;为止;

DC:表示演出目的地,在确定好舞台后才能演绎,展示。

HBITMAP:表示演出舞台,保存演绎的信息,直到调用DeleteObject(m_hBitmap)并将m_hBitmapBk = NULL才丢失原保留的信息。

关于GDI+产生OutOfMemory问题及GDI+用法概要 最近学校作业要处理图片,本来 阅读详情

相关推荐

使用GDI+进行开发的一些问题(1)

1.GDI+的前世今生 GDI+全称图形设备接口,Graphics Device Interface (GDI) ,他的爸爸叫做GDI, 用C写的。Windows XP出来以后用C++重新写了一下,变成了GDI+。从.NET Framework 1.0开始,GDI+就被正式封装在了.NET Framework里面,并被广泛地应用到了所有和图形图像相关的程序中。不幸的是,这个GDI+引入了微软有史

Hotcan的技术专栏 817

利用UpdateLayeredWindow函数制作透明窗口时BMP的Alpha通道的问题

void CDigitalClock::Update() { // Create the alpha blending bitmap BITMAPINFO bmi; // bitmap header ZeroMemory(&bmi, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFO...

weixin_34296641的博客 245

使用GDIView工具排查GDI对象泄漏导致程序UI界面绘制异常的问题

详细讲述如何使用GDIView工具排查GDI对象泄漏导致程序UI界面绘制异常的问题

dvlinker的技术专栏 1万+

GDI对象CFont

1. 字体的创建 (1)字体创建基本用法查看:http://www.jizhuomi.com/software/239.html (2)总结 CFont类封装了一个Windows图形设备接口(GDI)字体,并为操作字体提供了成员函数。创建字体时首先构造一个CFont对象,再通过调CreateFont、CreateFontIndirect、CreatePointFont或CreatePointFo...

qq_29187197的博客 466

使用GDI对象绘制UI时需要注意的若干细节问题总结

本文结合多年的项目实践,给大家分享几个使用GDI对象的细节,以供大家借鉴或参考。

dvlinker的技术专栏 1万+

使用GDIView排查GDI对象泄漏导致的程序UI界面绘制异常问题

使用GDIView工具排查GDI对象泄漏导致的程序UI界面绘制异常问题。

dvlinker的技术专栏 1万+

基于GDI的简单界面框架

在工作中经常需要为C++的对话框绘制界面,特别是按钮和背景等需要使用图片重新制成,而且这些绘制出来的“控件”都需要对点击等操作进行响应。为了方便大量的类似操作,自己动手写了一个简单的类,可实现对类似“控件”接近自动化的管理。 主要的想法如下: 1、实现对图片的自动管理,主要是销毁。 2、简化在对话框类中反复填写的代码工作量。 3、需要考虑常用的几种不同的控件及工作模式。 4、需要

cyfage的专栏 1960

易语言打造GDI仿迅雷界面完整教程

GDI(Graphics Device Interface)是Windows操作系统中用于实现设备无关性的图形输出接口。通过GDI,应用程序可以在各种显示设备上绘制图形和文本,而不必关心具体硬件的细节。GDI为应用程序提供了一整套丰富的绘图函数和数据类型,使得开发者能够实现复杂的图形处理和视觉效果。易语言,顾名思义,它被设计为一种易于学习和使用的编程语言。

weixin_35734408的博客 828

GDI绘制界面注意的几点

  GDI绘图和openGL等其他绘图方式都是将图片绘制在指定屏幕的像素点上,不同的是GDI没有也不需要3D硬件加速等功能!所以GDI理论上的速度只和硬件有关。GDI刷子等概念并没有显卡硬件加速功能,所以要使用双缓冲区的概念。GDI+在这方面有所改进但也不太乐观。所谓双缓冲简单的说就是把图片绘制完成处理后形成一张定格的图片后在输出到显卡。    当使用GDI绘制图片时(GDI本来就是绘制简单图

Sur的工作日子 3680

gdi+ 绘制半透明 窗口

gdi+ 绘制半透明 窗口,绘制png,非常有借鉴意义。欢迎交流

PCB工程师必看:别再搞错1078玻纤布的Dk了,手把手教你算等效介电常数

本文为PCB工程师提供了1078玻纤布等效介电常数(Dk)的详细计算指南,帮助解决高速设计中的信号完整性问题。通过解析玻纤布结构、混合介质理论和实战计算方法,指导工程师准确设置EDA工具参数,避免常见的Dk计算误区,提升设计精度和仿真准确性。

weixin_42546392的博客 399

【UI】GDI+绘制界面基本分析

一、基本步骤        {//MFC中使用GDI+ Graphics graphics(GetDC()->m_hDC)// 首先,给Graphics对象传一个hdc } //Winform使用GDI+ protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; //W

此博客不更新很多年了,博客作废............ 2976

Cursor Cloud Agent:云原生编程工作流的底层重构

编程工作流正从本地计算范式转向云原生执行范式。Cloud Agent 本质是将代码理解、生成、执行与调试等核心能力下沉至隔离、可控、按需分配的云端虚拟机,通过 Firecracker 微虚拟机实现亚秒级启动,并依托上下文快照、环境镜像化和内核级沙箱保障一致性、算力弹性与数据安全。这一范式突破了传统本地 AI 编程助手在环境依赖、调试能力与企业合规上的根本局限,使 IDE 从编辑工具升维为分布式开发指挥中心。本文深入解析其运行机制与工程落地实践。

weixin_34354173的博客 337

通过及时释放GDI资源避免MFC界面假死

某次编写了一个MFC程序,该程序每运行一段时间后,都会出现操作界面无反应的现象,更有甚者,拖动界面后还会导致界面崩溃。然而,调试代码是我发现:后台仍然在正常工作着。 没错!我遇到的就是MFC界面假死问题! 那么究竟是什么原因导致了界面假死呢? 在我的情景下,程序每次进入OnCtlColor()函数后,我都会使用CreateSolidBrush(RGB(0,0,0))来创建一个黑色画刷,将edit ctrl的背景刷成黑色。然而使用完这个画刷后我并没有及时释放,导致画刷数目随着程序运行不断增加。 当GD

qq_36570733的博客 1069

稳定性性能系列之十五——系统稳定性监控体系建设:从指标到预警的完整方案

深入探讨Android系统稳定性监控体系的设计与实现,涵盖指标体系设计、数据采集方案、异常检测算法、预警响应机制,并提供完整的监控平台搭建实践。

Cheson的专栏 1358

半桥LLC谐振变换器及同步整流MATLAB仿真(二)

接上文,半桥LLC谐振变换器及同步整流MATLAB仿真

qq_55203246的博客 4331

【GDI+编程】--汇总+实战

上篇博客说了些题外话,可能有人会疑惑为什么偏偏在这时候来讲解事件和委托。对于事件和委托是.NET程序猿必须掌握的一堂课,是程序猿踏入设计而不是编写的里程碑,了解了事件的形成就能够使用代码编写动态创建的事件,而学会了委托才能真正的踏入设计的阶段

航帆远洋 2815

有了网段为什么还要有VLAN???

近几日,在学习VLAN及VXLAN方面的知识,对于产生原因做一个总结及详解。 VLAN(Virtual Local Area Network,虚拟局域网),其主要用途是用来缩小广播域,即进行隔离。 先对广播域的一个概念做如下描绘:如下图,主机A、B、C、D均连接在交换机SW1上,其中A、C同网段为192.168.252网段,而B和D同网段,为192.168.250网段。 现,假如A与C第...

dandandean_96的博客 6887

GDI对象泄漏问题排查分析

GDI objectBitmapBrushDCCreateDCFontMemory DCDeleteDCMetafilePaletteRegion//...如果我们平时忘记调用的时候,就会造成GDI对象被泄漏。GDI对象作为一个Windows的内存资源,也占用其内存空间,并且需要用户自动管理和释放;为了降低GDI对象的资源泄漏,我们可以使用智能指针来管理GDI对象句柄。程序崩溃。UI资源显示异常。程序运行缓慢。

xsinlink的博客 2882

Labview_DQMH框架学习1--浅析

本文主要结合一个相对容易理解的例子,阐述 DQMH 框架的工作原理,希望对初学者有一定的帮助。

hrbeuxn的博客 3051

RK3568平台(内存篇)DDR定频修改

如果需要DDR定频,则还需要注释掉其他多余的DDR频率,保留一个即可,例如注释掉opp-528000000、opp-1068000000、opp-1560000000,保留opp-2750000000则是定频最大频率。如果回退必须将 dmc_opp_table节点 的其他频率打开,否则系统无法选择到其他频率运行。ddr频点不对,先把ddr变频关掉,关闭后系统就不会一直重启了,以下是修改DDR频点的。rk3588修改定频节点在rk3588s.dtsi 的 dmc: dmc。

weixin_49303682的博客 1622

GDI+开发包GDISDK使用说明:为开发者提供GDI+功能集成

GDI+开发包GDISDK使用说明:为开发者提供GDI+功能集成 去发现同类优质开源项目:https://gitcode.com/ GDI+开发包GDISDK是专为开发者设计的,帮助快速集成GDI+功能至应用程序的强大工具。 项目介绍 在现代软件开发领域,图形界面设计是至关重要的部分,而GDI+(Graphics Device Interface Plus)作为Windows操作系统的图形设备接口...

gitblog_06709的博客 956

B07:AI 时代怎么考核团队?我把 KPI 改了 5 版才找到答案

最后说一句掏心窝的话。绩效考核不是"管人"的工具,是"引导团队行为"的工具。你定什么指标,团队就会做什么行为。你定"AI 占比",团队就凑占比你定"效率提升",团队就挑软柿子你定"代码行数",团队就刷行数你定"工具使用率",团队就刷使用只有定"业务价值 + 工程质量 + 能力成长"三个维度的指标,团队才会真正关注长期价值。这套 KPI,我在我带的团队里跑了 6 个月,没有任何一个指标被"刷"出来。考核的是结果,不是过程。永远考核"创造了多少价值",永远不考核"用了多少 AI"。

刘一说的IT专栏 503

零基础小白如何自学GDI和GDI+

自学 GDI(Graphics Device Interface)和 GDI+ 是学习 Windows 图形编程的一个不错选择,尤其适合开发桌面应用程序时需要进行图形界面设计的开发者。GDI 和 GDI+ 是 Microsoft 提供的图形绘制接口,GDI 用于绘制基本图形元素,而 GDI+ 提供了更多的功能和现代化的图形处理能力。

小宝哥Code的专栏 1307

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

上一篇: GDI+ 双缓冲实现和局部刷新技术
下一篇: 关于WIN32 窗口信息的各种获取
htt9931
博客等级 码龄24年 43粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值