|
Are you setting styles for double buffering and all painting in wmpaint?
|
|
|
|
|
Mike, Thanks for your reply!
I am setting all controls that go on the form to this.DoubleBuffering = true.
How do I set all painting to wmpaint? I'm not familiar with this property.
Tom
|
|
|
|
|
SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
|
|
|
|
|
Mike,
Thanks again, I'm using something similar. On all forms and controls I envoke...
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint |
ControlStyles.OptimizedDoubleBuffer, true);
Still Ugly Black Flicker occurs!
Tom
|
|
|
|
|
Cubzfan wrote: On all forms and controls I envoke
No. In your custom control. FaderControl is your own custom control right? That's what is flickering yes?
|
|
|
|
|
Mike,
No, the form the control is changing the Opacity flickers black when the control is initially taken from the default full opaque setting to any decrease setting. The control works fine after that. If you increase or decrease the parent forms opacity with the child control it changes as it should unless the control is once again set all the way to the right (max setting the parent form to full opaqe) and you decrease again the black flicker happens again.
Hope this helps clear things up???
I really appreciate the help!!
|
|
|
|
|
So you are working on a Custom Control, you are changing the opacity of a .NET Form. Yeah I have no idea what might help with that. See Dustin Metzgar's post maybe it will help.
|
|
|
|
|
Which OS are you using? I noticed having flicker problems in Win 2000, but everything was fine in XP.
Logifusion[^]
|
|
|
|
|
Dustin,
Thanx for the reply! I am using XP.
|
|
|
|
|
Damn. Thought maybe it was an easy solution. In one of the projects I worked on, the help->about dialog box would fade in using the opacity control. In 2000, it often had problems and would sometimes appear black until it got to an opacity of 1.00. The only thing I can really suggest is that you try setting the opacity in the Form's thread. It looks like you have a separate dialog box that you use to set the main form's opacity. I think that means there is one thread for your dialog and one for your main form. Maybe you can try using Invoke and a delegate to set the opacity in the main form's thread.
I'm not sure if it works or not. We ended up just saying "Eh, good enough."
Logifusion[^]
|
|
|
|
|
Dustin,
This gets better! I disabled the opacity control and tried setting the forms opacity to 0.50 when the form is initialised. When the form pops up, same thing black flicker then form and new opacity are what they are suppose to be.
Very frustrating, but I will prevail!!
Thanx again,
Tom
|
|
|
|
|
Tom,
I was glancing several times at this thread today, and something about the "black flicker" was sounding familiar. Anyway, I think I've figured out a solution, so I'll take a crack at it.
Slight disclaimer: I've only done one test with this, and I think it works, but I cannot be sure. Please let me know if it doesn't work.
Basically the solution is this: don't use the OptimizedDoubleBuffer and AllPaintingInWmPaint styles for the form which you are making more or less opaque. I was reading a short article on another site about Transparent Windows Forms Controls (you can look at it here[^] - some of the images are broken, but the article text is all that matters). On that page, the author notes that, when making truly transparent controls, you cannot use double buffering, because "The memory bitmap which is provided to your code has an opaque background and does not allow the carefully retained parent pixels to show through". This makes sense when you think about how double-buffering is done: basically, you are drawing to a buffer which is never displayed, and so I would imagine there is no previously drawn pixels on that buffer (which is necessary for transparency, because you need your pixels to be blended with the pixels which are behind them).
Give that a try on your Form, and see what happens. That is, in your Form's constructor (the one whose opacity you are changing) take out the two styles OptimizedDoubleBuffer and AllPaintingInWmPaint . I'm not sure why AllPaintingInWmPaint does not work properly, but in my test it gave a black flicker when it was set, even without the double-bufferring. I suspect it has to do with OnPaintBackground not being called when that style is set, and therefore the proper blending does not occur with the form background.
As a side note, I can make the background flicker black when I minimize and then restore my form. You did not mention this before, but I thought it might help to mention it so that you can check if your code produces the same effects as I have been throughout.
Hope that helps!
Sincerely,
Alexander Wiseman
|
|
|
|
|
Alexander,
Thanx for your reply! I tried taking both the OptimizedDoubleBuffer and AllPaintingInWmPaint from the form I am changing opacity on... no luck. Just for grins I then commented out all code for all controls disabling those methods and still the same ugly black flash.
Thanks,
Tom
|
|
|
|
|
Tom,
I tried a few more things, and did a few more Google searches, and here is what I came across (which, I may add, makes much more sense than the double-buffer issue that I related in my previous post). This is on a CP article message board (you can see the article here[^]):
The question
"I like this control alot but when I close my form, all controls on it flicker for a blink of an eye to black and then the fade begins. any suggestions to fix it?"
That looks like your problem exactly. Here is the response:
The response (from the article author)
"Short version:
Check if you are using a transparency key. If not, try and set one. Pick a color that won’t affect your program such as lime green, or some other ugly color that is not used by anything on your form.
Long version:
If it’s the same flicker as one I have seen before, than it has to do with a bug in WinForms and how it deals with transparent windows. WinForms is in fact just a wrapper to the Windows API. When dealing with opacity, WinForms will use a Windows API to convert your form to what is know as a layered window.
“Using a layered window can significantly improve performance and visual effects for a window that has a complex shape, animates its shape, or wishes to use alpha blending effects.” – MSDN
However, WinForms does not make a window a layered window until it feels it is necessary. The flicker you are seeing is WinForms trying to convert a non layered window into a layered one.
The reason why setting a transparency key works is because WinForms will force any window with a transparency key to be of the type layered. Set the transparency key at design time and at runtime the window will always be a layered window. With no need to convert, the flicker goes away.
-Mike."
It seems from his response that the black flicker you see is the changing of the window from a normal window to a layered window. His suggested solution is to set the transparency key (to some color you do not use on the form) which will force the window to be created as a layered window. This should fix the flicker when you first change the opacity.
I gave this a try and it worked well to remove the black flicker on using the sliding control first and on minimize and maximize. However the black background appears when you first load the form, and it looks like a slight flicker to me. This, I think, you probably will not be able to get rid of, it's just that on faster systems you might not see it at all.
FYI, I tried setting double-buffering on with this solution and it didn't seem to make a difference one way or another, so you can probably use it anyway.
Give this a try and let me know the outcome, I'm very interested in this problem!
Sincerely,
Alexander Wiseman
|
|
|
|
|
Alexander,
Once agin thanx! I am now at home and will check in the morning (8:00 am CST). I really appreciate your effort. I have been trying to google the problem all day! I am only checking now at home because I think I have some kind of obcessive compulsive disorder when it comes to troubleshooting!
I'll keep you in the loop tomorrow!
Thanx again,
Tom
|
|
|
|
|
Alexander,
Tried setting the trans key to lime green with no luck. It did help a little because now it only does the black flicker when the opacity is initially changed. It also appears more resources are being used (slower). I'm going to continue the search.
Thanx,
Tom
|
|
|
|
|
Tom,
Seeing what Alexander posted, I decided I might as well try this for myself. My system only shows the black part for a small fraction of a second. It's barely noticeable, but it's still there. Once it's done, then I don't see it again. So, I decided I'd cheat a bit. Here's what I did and this seems to work for me. I put this in my form's constructor:
public Form1()
{
InitializeComponent();
this.Opacity = 0.50D;
this.Opacity = 1.00D;
}
AFAIK, the window is not shown when it's constructed. But the opacity still takes effect. Can you try this and tell us if it fixes your problem?
Logifusion[^]
|
|
|
|
|
Dustin,
Thanks again for helping me fight the good fight! I had already tried this method (tried it again). All this does is move the flicker problem to when the form is first created. It does eliminate the black flicker when the control is used but still the ugly black flicker even when the form is created is not going to work.
Thanks Anyway!
I'm trying to find an article I saw a few days ago which had a long drawn out solution. At the time I thought the guy was crazy to go through that much work to get rid of the black flicker. He must have went through this long search for the "easy" answer. The premise of his solution involved setting and painting everything programatically. BACK TO THE SEARCH!!
I WILL PREVAIL!!!
|
|
|
|
|
Humor me for a second and try:
this.WindowState = FormWindowState.Minimized;
this.Opacity = 0.50D;
this.Opacity = 1.00D;
this.WindowState = FormWindowState.Normal;
Logifusion[^]
|
|
|
|
|
Dustin,
I tried a couple of things along these lines as well. I didn't try Minimized but I did try hiding and showing the form and I still got the initial black flicker. I think it must have something to do with the way layered windows work. Aside from complete custom paint handling, etc, I can't think of anything else currently.
Sincerely,
Alexander Wiseman
|
|
|
|
|
Then, I guess the solution for Tom is: Get a faster computer!
Really, when I change the opacity of the form in the constructor I never see a black flicker. So, in Tom's case it might work fine on some computers, but not on others.
Oh! Another thing we could try is a splash screen. Put the splash screen up in front of the app window when the flickering is going on so that the user doesn't see it.
Logifusion[^]
|
|
|
|
|
I just tried that!
It didn't work. It helped a little bit, but still there was a black flicker when the form was hidden. I made the splash screen a child form of the main form, so maybe if you had the splash screen be a top-level form something different would happen, but I don't think so.
Sincerely,
Alexander Wiseman
|
|
|
|
|
Dustin,
No humor needed! You're helping me and I'm willing to try anything at this point. It didn't work. I like the idea though. I'm trying to figure a way to delay displaying the form for a second after ShowDialog() is called.
Thanx again for helping!
I WILL PREVAIL!!
TIS MEERLY A FLESH WOUND!!
Tom
|
|
|
|
|
Well, while we're on the subject of crazy ideas. How about this:
Your form comes up initially and it's the one you want to change the opacity on. We'll call it Form A. Now create another form that is an exact duplicate of Form A (same position and everything) and call it Form B. Form B comes up in front of Form A. Change the opacity of form A and set it back to whatever default you want. Then get rid of Form B. If it goes fast, the user won't know a thing!
I think I'm having too much fun with this. Maybe I should get back to work.
Logifusion[^]
|
|
|
|
|
Don't know if you've already tried this but here's another idea:
this.SetDesktopLocation(this.Location.X + 10000, this.Location.Y);
this.Opacity = 0.50D;
this.Opacity = 1.00D;
this.SetDesktopLocation(this.Location.X - 10000, this.Location.Y);
I figure if it's going to show the black flicker, it could do it off screen.
Logifusion[^]
|
|
|
|