用C#.NET 3.5的WinForms部分透明度? [英] Partial transparency with C# .NET 3.5 WinForms?
问题描述
我在做一个.NET 3.5的应用程序与绘制一个部分透明的黑色背景的一种形式。我重写OnPaintBackground做到这一点:
I'm making a .NET 3.5 app with a form that draws a partially transparent black background. I'm overriding OnPaintBackground to accomplish this:
protected override void OnPaintBackground( PaintEventArgs e )
{
using ( Brush brush = new SolidBrush( Color.FromArgb( 155, Color.Black ) ) )
{
e.Graphics.FillRectangle( brush, e.ClipRectangle );
}
}
它的工作原理,但偶尔的形式吸引了自身不清除屏幕,使得透明度暗比它应该是。我试着 Graphics.Flush()
和 Graphics.Clear()
玩,但它要么不帮助或完全消除透明度。有什么建议?
It works, but occasionally the form draws over itself without clearing the screen, making the transparency darker than it should be. I've tried playing with Graphics.Flush()
and Graphics.Clear()
, but it either doesn't help or completely removes transparency. Any suggestions?
编辑: 这里是什么样子,从左边的应用程序后,经过形式重绘自己几次(响应从一个控制tab键切换到另一个)右侧:
Here's what it looks like, after starting the app on the left, and after the form redraws itself a few times (in response to tabbing from one control to another) on the right:
编辑2: 我尝试了一些东西今天上午,发现当透明部分后面的桌面上改变,它实际上没有被重新绘制。举例来说,如果我打开任务管理器,并把它放在窗口后面,你看不到它刷新自己。这是有道理的什么我已经看到的透明度水平。是否有一个功能,让Windows重画你的窗口后面的区域?
Edit 2: I was trying a few things out this morning and noticed that when the desktop behind the transparent portions change, it's not actually being redrawn. For example, if I open Task Manager and put it behind the window, you don't see it refreshing itself. This makes sense with what I've been seeing with the transparency levels. Is there a function to make Windows redraw the area behind your window?
修改3: 我试着在表单上改变一些属性,但他们都结果的形式绘制非透明黑色:
Edit 3: I've tried changing a few properties on the form, but they all result in the form drawing non-transparent black:
this.AllowTransparency = true;
this.DoubleBuffered = true;
this.Opacity = .99;
我会尝试创建一个单独的窗口透明部分为overslacked提到的,但是任何其他的想法,仍然欢迎。
I'm going to try creating a separate window for the transparent portion as overslacked mentioned, but any other ideas are still welcome.
推荐答案
我想我会称这种预期的行为,其实。我会做的是使我的背景到一个内存位图,在绘制事件,复制到窗体(基本的双缓冲)。
I think I would call this expected behavior, actually. What I would do is render my background to an in-memory bitmap and, in the paint event, copy that to the form (basic double-buffering).
如果我是大错特错,你能张贴截图?我不知道,我想象你所描述正确的是什么。
If I'm way off base, could you post a screenshot? I don't know that I'm imagining what you're describing correctly.
编辑:
我想了解一下您使用OnPaintBackground ... pre-.NET的,如果你做双缓冲你会赶上并忽略WM_ERASKBKGND消息(以prevent闪烁),使您的图像屏幕外缓冲区,从缓冲区复制到WM_PAINT屏幕。因此,尝试从OnPaintBackground到的OnPaint改变。
I'm wondering about your use of OnPaintBackground... pre-.NET, if you were doing double-buffering you'd catch and ignore the WM_ERASKBKGND message (to prevent flicker), render your image to an offscreen buffer, and copy from the buffer to the screen on WM_PAINT. So, try changing from the OnPaintBackground to OnPaint.
我没有做太多这种在.NET中的事情,但我以前有一个pretty的手感好就可以了;我只是不知道这是否会转化得好不好!
I haven't done too much of this kind of thing in .NET, but I had a pretty good handle on it before; I just don't know if it'll translate well or not!
编辑2:
马克,我越觉得你想要做什么,更多的问题出现。我要建议建立专门捕捉屏幕,使得它黑暗的后台线程;然而,为了消除自己的表单,你不得不能见度设置为false,这会带来其他问题......
Marc, the more I think about what you're trying to do, the more problems appear. I was going to suggest creating a background thread dedicated to capturing the screen and rendering it darkened; however, in order to remove your own form you'd have to set the visibility to false which would create other problems....
如果你不愿意放弃,我会建议创建两个窗口和捆绑在一起。创建一个半透明的窗口(通过设置不透明度)对你的背景窗口,创建第二个正常窗口前台。使用在前景窗口SetWindowRgn到切掉背景和它们在彼此的顶部定位
If you're unwilling to give up, I would suggest creating two windows and "binding" them together. Create a semi-opaque window (by setting opacity) for your background window, and create a second "normal" window for the foreground. Use SetWindowRgn on the foreground window to cut away the background and position them on top of each other.
祝你好运!
这篇关于用C#.NET 3.5的WinForms部分透明度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!