I have a window, wich most of time is hidden. User shows it by global hotkey sometimes and he wants it to become visible very fast. But window has many controls and every hidden->visible transition calls full window repaint. On slow CPU it is very perceptible. I want to make this window always be painted even in hidden state. Then I think it will take quite short time to show it.
-
I want my window to appear superfast like if it was in background and I just call SetForegroundWindow. – tormozit Feb 28 '17 at 05:01
-
And one important thing is that I need to hide taskbar icon on window hide and show it on window show – tormozit Feb 28 '17 at 05:28
-
I made some complex tricky solution. I will describe it here soon. – tormozit Mar 02 '17 at 04:35
-
1. Handle system event "Active window change" to always know its handle. Let it be variable lastActiveWindow. 2. On FormClosing event – tormozit Mar 05 '17 at 21:52
-
I truly tried to keep my word and describe solution in previous comment. But difficult markup, 5 minute period for edition comment and max length was too hard to overcome. So very short solution is to move window outside screen instead of close and move it back on activate. It was hard to debug but it works really fast. Negative effect is that window need to be always shown in taskbar else it will repaint on with appearence of taskbar icon. You could find it in source code of Main form https://sourceforge.net/p/clip-angel/code/ – tormozit Mar 05 '17 at 22:16
2 Answers
Update
I'm not sure what you see. What I see and find annoying is that when ClipAngel's form is shown in a different place from the one it was hidden (according to your positioning logic) I can see a "blink" of the form at the old position. AFAIU this is done note by your application itself but by the DWM (Desktop Window Manager) and according to Raymond Chen you can disable it for you form using DwmSetWindowAttribute
and DWMWA_TRANSITIONS_FORCEDISABLED
private const int DWMWA_TRANSITIONS_FORCEDISABLED = 3;
private const int S_OK = 0;
[DllImport("dwmapi", PreserveSig = true)]
static extern int DwmSetWindowAttribute(IntPtr hWnd, int attr, ref int value, int attrLen);
private void ShowForPaste()
{
if (Environment.OSVersion.Version.Major >= 6)
{
int boolForceDisable = 1;
int hresult = DwmSetWindowAttribute(this.Handle, DWMWA_TRANSITIONS_FORCEDISABLED, ref boolForceDisable, Marshal.SizeOf(boolForceDisable));
if (S_OK != hresult)
{
// log somewhere?
}
}
...
Note also that when I tried this hack on a machine with 16-bit color configured it didn't help for some reason and DwmIsCompositionEnabled
always returned false.
Old Answer
Why do you have many "hidden->visible transitions"? Also I think double-buffer might help you, see Winforms Double Buffering
-
User presses global hot key in some situations. Usually before it the window is hidden, so Show() method is called and that's what I call "hidden->visible transition". "Winforms Double Buffering" I tried and got not painting window content forever after hide() show(). – tormozit Feb 27 '17 at 22:10
-
I understand where one "hidden->visible transition" comes from but you mentioned that the issue is that there are many of them and thus everything is slow. Also I'd like to mention that in the referenced answer `WS_EX_COMPOSITED` is used which is not directly accessible from WinForms so you might have not tried it yet. – SergGr Feb 27 '17 at 22:14
-
Each time the window is shown only one "hidden->visible transition" is happening and even on the fast CPU I can see a little delay and painting. About WS_EX_COMPOSITED. I added to my Form class protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED return cp; } } – tormozit Feb 27 '17 at 22:24
-
Then you probably you have to show us some code and create [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) . Maybe you just do something bad on your UI thread that takes too long. Or maybe your form is huge. Or maybe you are too observant. – SergGr Feb 27 '17 at 22:34
-
With source code https://sourceforge.net/p/clip-angel/code/ci/master/tree/ VS 2015 compile, run, while (not convinced) {close window, press ALT+V}. With exe https://sourceforge.net/projects/clip-angel/ run, while (not convinced) {close window, press ALT+V} – tormozit Feb 28 '17 at 04:32
-
-
Thanks for examining my code. The hack with DWMWA_TRANSITIONS_FORCEDISABLED helps a little but not much. I was hardly searching for the solution almost without rest =) And finally I made some complex tricky solution. I will describe it here soon. – tormozit Mar 02 '17 at 04:34
-
@tormozit, I'm not sure whether you have had enough time to put it together, but it would be interesting to find out what you came up with. – SergGr Mar 10 '17 at 01:52
-
@tormozit, No. And actually it is pretty legal to answer to your own question so I was expecting to see your solution as an answer rather than a comment. – SergGr Mar 10 '17 at 20:22
-
I made some complex tricky solution. In few words solution is to move window outside the screen (TOP=-10000) instead of close and minimize and move it back on activate. It works really fast. Negative effect is that window need to be always be shown/hidden in taskbar else window will repaint on every taskbar icon hidden->shown change. You could find it in source code of Main form http://sourceforge.net/p/clip-angel/code in methods Main.WndProc, Main_Closing, Main_Activated, Main_Deactivate, ShowForPaste, RestoreWindowIfMinimized

- 26
- 5