C#如何让隐藏的窗口不断重新绘制并准备好快速显示?

C#如何让隐藏的窗口不断重新绘制并准备好快速显示?,c#,window,hidden,repaint,C#,Window,Hidden,Repaint,我有一扇窗户,大部分时间都藏在里面。用户有时通过全局热键显示它,他希望它很快变得可见。但窗口有很多控件,每个隐藏->可见的转换都调用完整的窗口重绘。在缓慢的CPU上,这是非常明显的。我想让这扇窗户即使在隐藏状态下也能一直被粉刷。那么我想展示它需要很短的时间。更新 我不知道你看到了什么。我看到并发现恼人的是,当ClipAngel的表单显示在与它隐藏的表单不同的位置时(根据您的定位逻辑),我可以看到表单在旧位置“闪烁”。AFAIU这是由应用程序本身完成的,但由DWM(桌面窗口管理器)完成,根据您的说

我有一扇窗户,大部分时间都藏在里面。用户有时通过全局热键显示它,他希望它很快变得可见。但窗口有很多控件,每个隐藏->可见的转换都调用完整的窗口重绘。在缓慢的CPU上,这是非常明显的。我想让这扇窗户即使在隐藏状态下也能一直被粉刷。那么我想展示它需要很短的时间。

更新

我不知道你看到了什么。我看到并发现恼人的是,当ClipAngel的表单显示在与它隐藏的表单不同的位置时(根据您的定位逻辑),我可以看到表单在旧位置“闪烁”。AFAIU这是由应用程序本身完成的,但由DWM(桌面窗口管理器)完成,根据您的说明,您可以使用和禁用它

private const int DWMWA_TRANSITIONS_FORCEDISABLED=3;
私有常量int S_OK=0;
[DllImport(“dwmapi”,PreserveSig=true)]
静态外部int DwmSetWindowAttribute(IntPtr hWnd、intattr、ref int value、intattrlen);
私有void ShowForPaste()
{
如果(Environment.OSVersion.Version.Major>=6)
{
int boolForceDisable=1;
int hresult=DwmSetWindowAttribute(this.Handle,DWMWA_TRANSITIONS_FORCEDISABLED,ref boolForceDisable,Marshal.SizeOf(boolForceDisable));
如果(S_OK!=hresult)
{
//在什么地方登录?
}
}
...
还要注意的是,当我在配置了16位颜色的机器上尝试此攻击时,由于某种原因,它没有任何帮助,
DwmIsCompositionEnabled
总是返回false


旧答案


为什么会有很多“隐藏->可见的转换”?我还认为双缓冲区可能会对您有所帮助,请参见

我提出了一些复杂而棘手的解决方案。简单地说,解决方案是将窗口移到屏幕外(顶部=-10000)而不是关闭和最小化,并在激活时将其移回。它的工作速度非常快。负面影响是窗口需要始终显示/隐藏在任务栏中,否则窗口将在每个任务栏图标上重新绘制隐藏->显示更改。
您可以在Main.WndProc、Main\u Closing、Main\u Activated、Main\u Deactivate、ShowForPaste、RestoreWindowIfMinimized的Main表单源代码中找到它。在某些情况下,用户按下全局热键。通常在它之前,窗口是隐藏的,因此调用Show()方法,这就是我所说的“隐藏->可见转换”。“Winforms双缓冲”我试过了,但在hide()show()之后并没有永远画出窗口内容。我知道“隐藏->可见”转换的位置“来自,但您提到的问题是,它们有很多,因此一切都很慢。此外,我想提到的是,在参考答案中使用了
WS_EX_COMPOSITED
,它无法从WinForms直接访问,因此您可能还没有尝试过。每次窗口都只显示一个“隐藏->可见”转换”正在发生,甚至在快速的CPU上,我可以看到一些延迟和绘制。关于WS_EX_COMPOSITED。我在窗体中添加了受保护的重写CreateParams CreateParams{get{CreateParams cp=base.CreateParams;cp.ExStyle |=0x020000000;//打开WS_EX_合成返回cp;}}然后,您可能必须向我们展示一些代码并创建。可能您只是在UI线程上做了一些花费太长时间的错误操作。或者您的表单太大。或者您太细心了。使用源代码VS 2015编译,运行,而(不确信){close window,按ALT+V}。使用exe run,而(不确信){close window,按ALT+V}我想让我的窗口看起来像在后台一样超快速,我只需调用SetForegroundWindow。一个重要的事情是,我需要在窗口隐藏时隐藏任务栏图标,并在窗口显示时显示它。我提出了一些复杂的棘手解决方案。我将很快在这里描述它。1.处理系统事件“活动窗口更改”总是知道它的句柄。让它成为变量lastActiveWindow。2.在窗体关闭事件上如果(lastActiveWindow!=null)lastActSet=SetForegroundWindow(lastActiveWindow);如果(!lastActSet)SetActiveWindow(IntPtr.Zero);this.Top=-this.Height;e.Cancel=true;
code
我在上一篇评论中确实试图信守诺言并描述解决方案。但难以标记,编辑评论的5分钟期限和最大长度太难克服。所以很短的解决方案是将窗口移到屏幕外,而不是关闭并移动它回到激活状态。调试起来很困难,但它的运行速度非常快。负面影响是窗口需要始终显示在任务栏上,否则它将重新绘制在任务栏图标的外观上。您可以在主窗体的源代码中找到它