我有一扇窗户,大部分时间都是隐藏的。用户有时通过全局热键显示它,他们希望它很快变得可见。但是窗口有很多控件,每个隐藏到可见的转换都会调用整个窗口重绘。在慢速 CPU 上,这是非常明显的。我想让这个窗口即使在隐藏状态下也始终被绘制。那么我认为需要很短的时间来展示它。
更新
我不确定你看到了什么。我看到并觉得烦人的是,当 ClipAngel 的表单显示在与隐藏的表单不同的位置时(根据您的定位逻辑),我可以在旧位置看到表单的“闪烁”。 AFAIU 这是由您的应用程序本身完成的,但由 DWM(桌面窗口管理器)完成,并且根据 Raymond Chen,您可以使用
DwmSetWindowAttribute
和 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?
}
}
...
另请注意,当我在配置了 16 位颜色的计算机上尝试此 hack 时,由于某种原因它没有帮助,并且
DwmIsCompositionEnabled
始终返回 false。
为什么会有很多“隐藏->可见的转换”?另外我认为双缓冲可能对你有帮助,请参阅Winforms双缓冲
我做了一些复杂棘手的解决方案。简而言之,解决方案是将窗口移到屏幕之外(TOP = -10000),而不是关闭并最小化并在激活时将其移回。它的工作速度非常快。负面影响是窗口需要始终在任务栏中显示/隐藏,否则窗口将在每个任务栏图标隐藏->显示更改时重新绘制。 您可以在主窗体的源代码http://sourceforge.net/p/clip-angel/code中找到它,方法为Main.WndProc、Main_Closing、Main_Activated、Main_Deactivate、ShowForPaste、RestoreWindowIfMinimized