GDI+绘制透明属性窗口边框存在BUG?

花熊 2011-11-18 07:49:10
很简单的做了个测试:
OnInitDialog中加入:

DWORD stylex = GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
stylex |= WS_EX_LAYERED;
SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, stylex);
SetLayeredWindowAttributes( 0, 255, LWA_ALPHA);

响应WM_NCPAINT:

void CSimple1DemoDlg::OnNcPaint()
{
CRect rc;
GetWindowRect(&rc);
rc.OffsetRect(-rc.TopLeft());
CWindowDC dc(this);
Color clr(255, 255, 0, 0);
SolidBrush brush(clr);
Graphics g(dc.GetSafeHdc());
g.FillRectangle(&brush, rc.left, rc.top, rc.Width(), rc.Height());
}

结果是右边框和下边框未被绘出来,显示为黑色,

如果把代码改成:

void CSimple1DemoDlg::OnNcPaint()
{
CRect rc;
GetWindowRect(&rc);
rc.OffsetRect(-rc.TopLeft());
CWindowDC dc(this);
//Color clr(255, 255, 0, 0);
//SolidBrush brush(clr);
//Graphics g(dc.GetSafeHdc());
//g.FillRectangle(&brush, rc.left, rc.top, rc.Width(), rc.Height());
dc.FillSolidRect(&rc, RGB(255, 0, 0));

}

就OK了。
http://hi.csdn.net/attachment/201111/18/0_13216170568xJH.gif

现在必须使用GDI+绘制,求解决方法?
...全文
248 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
wozuiqiangdeaoyi 2011-11-19
  • 打赏
  • 举报
回复
http://www.cnblogs.com/jonnyyu/archive/2005/07/20/196502.html
要分
花熊 2011-11-19
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 wozuiqiangdeaoyi 的回复:]
http://www.cnblogs.com/jonnyyu/archive/2005/07/20/196502.html
要分
[/Quote]这是解决的方法吗,请详细说明,谢谢。
花熊 2011-11-18
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 redui 的回复:]
不妨多试验一下,比如把矩形设置得大一点,看看效果有何不同,然后在找找有没有什么调整方案。
[/Quote]谢谢,矩形设大我早试过了,新建一个对话框,加入上面的几行代码,你就会看到这种现象,我正在继续尝试解决,OK了,我会和大家分享的。
redui 2011-11-18
  • 打赏
  • 举报
回复
不妨多试验一下,比如把矩形设置得大一点,看看效果有何不同,然后在找找有没有什么调整方案。
花熊 2011-11-18
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 redui 的回复:]
你肯定在非透明方式下跟GDI完全一样?怎么我试验的结果还是有误差呢?

GDI+和GDI其实有很多差别,比如文字的大小、位置都会有误差,还有画矩形、画线、画曲线等等全有误差。至于原因,我不是很肯定,而是我猜测的(我的习惯喜欢猜测,只是很多猜测无法验证):
首先GDI+的矩形都是浮点数,这是误差的根源。
其次由于GDI+支持2D变换操作(缩放、旋转、平移等),它需要很多高精度的浮点运算,无论……
[/Quote]图片就在上面贴着,没有透明属性可以肯定用GDI+右下角是绘出来了,GDI+和GDI本来就有很多不同,我没说这个,我就说这个问题,至少GDI是不存在的。
redui 2011-11-18
  • 打赏
  • 举报
回复
你肯定在非透明方式下跟GDI完全一样?怎么我试验的结果还是有误差呢?

GDI+和GDI其实有很多差别,比如文字的大小、位置都会有误差,还有画矩形、画线、画曲线等等全有误差。至于原因,我不是很肯定,而是我猜测的(我的习惯喜欢猜测,只是很多猜测无法验证):
首先GDI+的矩形都是浮点数,这是误差的根源。
其次由于GDI+支持2D变换操作(缩放、旋转、平移等),它需要很多高精度的浮点运算,无论如何,浮点运算的次数越多,误差越大。当然如果用整数运算,误差只会更大,而且大得离谱。
最重要的是,从浮点的眼光来看像素填充,因为无法跟图片的像素一一对应,它只能采取插值填充,这种方式即使最终的大小跟要填充的大小一致,也会存在边缘无法对齐的后果。如果你了解3D的纹理贴图,就可以知道纹理素跟像素是如何错位对齐的。
最后,浮点矩形还要再次转换回整数以便绘制到屏幕上,还得产生点误差。

一家之言,欢迎拍砖。
用户 昵称 2011-11-18
  • 打赏
  • 举报
回复
把对话框弄成无边框的
花熊 2011-11-18
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 redui 的回复:]
GDI+的矩形跟GDI的矩形是不同的,计算有偏差
[/Quote]
请说说有什么偏差,我把WS_EX_LAYERED这个属性去掉,显示就和gdi一样了,所以肯定是透明属性影响的,请先实验下,如果用GDI+在透明属性下能贴出右下边框,立刻全分送上。
redui 2011-11-18
  • 打赏
  • 举报
回复
GDI+的矩形跟GDI的矩形是不同的,计算有偏差
花熊 2011-11-18
  • 打赏
  • 举报
回复
就算是直接把坐标输进去,也一样效果,不信可以自己试,如果你用GDI+在透明属性下能贴出右下边框,立刻全分送上。
花熊 2011-11-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 cometnet 的回复:]
楼主这行错了:
g.FillRectangle(&brush, rc.left, rc.top, rc.Width(), rc.Height());
改成:
g.FillRectangle(&brush, 0,0, rc.Width(), rc.Height());
[/Quote]
rc.OffsetRect(-rc.TopLeft());
rc.top和left就是0
,不信先自己试试,
邓学彬 2011-11-18
  • 打赏
  • 举报
回复
楼主这行错了:
g.FillRectangle(&brush, rc.left, rc.top, rc.Width(), rc.Height());
改成:
g.FillRectangle(&brush, 0,0, rc.Width(), rc.Height());







  • 打赏
  • 举报
回复
用GetClientRect(&rc);
花熊 2011-11-18
  • 打赏
  • 举报
回复
为什么GDI+就会这样呢,好诡异。
用过最好的换肤控件,使用简单,只要调用一个方法,所有以前打开的,后面打开的窗口都换成想要的皮肤,pb12.5也能使用,不过不能使用pb9版本的,而是pb11版本的,无需注册! SkinSharp是Windows环境下一款强大的通用换肤库。 SkinSharp作为通用换肤库,只需要在您的程序中添加一行代码,就能让您的界面焕然一新,并拥有多种主题风格和色调的动态切换功能以及Aero透明边框特效。 SkinSharp采用独特的软件界面开发技术,让原本复杂繁琐的界面编程变得轻松自如。SkinSharp换肤库目前支持所有流行的开发工具。SkinSharp可以在不修改客户程序的基础上,对在Windows上运行的任何程序进行随意换肤,完全实现了将程序界面与业务逻辑彻底分离,从而可以让您轻松地完成程序界面的完美升级。 SkinSharp优势 SkinSharp与同类产品相比有如下优势: 1. 超轻量级换肤,SkinSharp不依赖于任何第三方类库或模板库(STL,MFC,ATL等),仅仅使用到系统最基本的核心动态链接库。因此体积在同类产品上是最小的,仅不到200K,运行效率也是最高的,所有绘制和操作全部都是基于Win32 API的, 其他同类换肤库则十分臃肿。 2. SkinSharp 在滚动条和菜单换肤上,和其他同类换肤库有着明显的优势。在滚动条换肤上,SkinSharp做到了所有控件内置滚动条的换肤,并且不修改控件任何风格和属性,完美兼容各个控件。在菜单换肤上,SkinSharp采用独特的技术对所有菜单实行换肤,没错,是所有的菜单,包括IE控件内部菜单,系统菜单,滚动条菜单等等,只要是菜单就能换肤!并且支持所有菜单的透明! 3. SkinSharp 采用先进的皮肤格式,完美兼容各种不同形状外观的皮肤制作。SkinSharp皮肤采用超高压缩率,体积超小,最小的皮肤小于10K。载入效率极高,无任何延迟!设计的先进性使得SkinSharp的皮肤有着很好的版本兼容性,即使今后增加了皮肤属性项,也依然能够保持版本的兼容性。 SkinSharp的皮肤同时支持加密功能,保护您自己设计的皮肤不被其他人恶意使用。 4. SkinSharp 可以让你轻松拥有Aero透明边框以及阴影特效!SkinSharp仅用标准的GDI API就实现了Aero特效,并且效率极高! 其他换肤库则没有此特性或者使用了GDI+,这样在Windows 2000等系统中你就必须多带一个GDI+的动态链接库,并且效率会有所影响。另外,SkinSharp还支持边缘阴影,还可以调整阴影参数, 实现超炫效果! 5. SkinSharp 支持更改皮肤的色调,饱和度,亮度,窗体的透明度,菜单的透明度。仅一款皮肤,您就可以拥有不同的色调主题!做出类似QQ色调主题是一件轻而易举的事情! 6. SkinSharp 并非COM组件,仅以标准的动态或静态链接库的形式存在,SkinSharp无需进行系统注册,直接使用! 7. SkinSharp 完全支持Unicode,提供多种编码格式,支持静态库链接,与客户程序可以进行无缝整合!支持绝大多数第三方控件的完美换肤!界面与业务逻辑彻底分离!

16,467

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧