Partial transparency using C # .NET 3.5 WinForms?

I am building a .NET 3.5 application with a form that draws a partially transparent black background. I override 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 ); } } 

This works, but sometimes the shape is drawn by itself, without clearing the screen, making the transparency darker than it should be. I tried playing with Graphics.Flush() and Graphics.Clear() , but this either does not help or completely removes transparency. Any suggestions?

Edit: Here's what it looks like, after starting the application on the left, and after the form redraws itself several times (in response to a tab from one control to another) on the right:

Transparency Error http://www.quicksnapper.com/files/5085/17725729384A10347269148_m.png

Edit 2: I tried a few things this morning and noticed that when the desktop behind the transparent parts changes, it doesn't actually redraw. For example, if I open the task manager and put it outside the window, you will not see it updating. This makes sense with what I saw with transparency levels. Is there a feature that allows Windows to redraw the area outside the window?

Edit 3: I tried to change several properties in the form, but all of them lead to the fact that the trait of the form is opaque black:

 this.AllowTransparency = true; this.DoubleBuffered = true; this.Opacity = .99; 

I will try to create a separate window for the transparent part, as mentioned above, but any other ideas are still welcome.

+2
source share
2 answers

I think I would call this expected behavior. What I would do is make my background a bitmap in memory and copy it into a form in the drawing event (basic double buffering).

If I leave the base, can you post a screenshot? I do not know what I imagine that you are describing correctly.

EDIT:

I am wondering how you use OnPaintBackground ... pre -.NET, if you did double buffering that you caught and ignored the WM_ERASKBKGND message (to prevent flickering), render the image to the off-screen buffer, and copy it from the buffer to the screen in WM_PAINT. So try switching from OnPaintBackground to OnPaint.

I did not do too much of this in .NET, but I used to have a pretty good handle; I just don’t know if it will translate well or not!

EDIT 2:

Mark, the more I think about what you are trying to do, the more problems there are. I was going to propose creating a background thread dedicated to capturing the screen and darkening it; however, in order to remove your own form, you need to set the visibility to false, which will create other problems ....

If you do not want to give up, I would suggest creating two windows and β€œsnap” them together. Create a translucent window (by setting the opacity) for your background window and create a second β€œnormal” window for the foreground. Use SetWindowRgn in the foreground window to cut the background and place them on top of each other.

Good luck

+3
source

Is Graphics.CompositingMode installed on CompositingMode.SourceCopy ? This should lead to the fact that the image twice will be equivalent to drawing it once, since it will replace the existing alpha data, instead of composing it.

+1
source

Source: https://habr.com/ru/post/913345/


All Articles