【问题标题】:ShowWindow() SW_HIDE window instantly, without effectShowWindow() SW_HIDE 窗口立即生效,不生效
【发布时间】:2016-02-28 18:48:17
【问题描述】:

在我的 C++ 应用程序中,我有以下代码:

ShowWindow(hDlg, SW_HIDE);
MakeScreenshot();
ShowWindow(hDlg, SW_SHOW);

这应该在没有当前应用程序窗口的情况下捕获屏幕截图。然而有一个问题。 SW_HIDE 需要一些时间,因为我的 windows 8.1 配置为使用动画效果。所以窗口的隐藏大约需要 400 毫秒,如果在这个时间间隔内(确实如此)捕获了屏幕截图,它还将包含应用程序本身的窗口,我不喜欢。

有什么办法可以立即隐藏当前窗口,使其不包含在紧随其后调用的create screenshot函数中?如果没有,是否有任何其他首选方式如何截取 Windows 桌面的屏幕截图,不包括应用程序本身?在 MakeScreenshot 之前添加延迟不是任何好的解决方案。谢谢。

【问题讨论】:

  • @HansPassant:你在想DWMWA_CLOAK 属性吗?
  • @Tomas:尝试使用SystemParametersInfo() 在隐藏窗口之前禁用动画,并在显示窗口后重新启用动画。或者在窗口上启用WS_EX_LAYERED 样式,然后将其不透明度设置为0,然后再设置回255。或者,只需将窗口移出屏幕,然后再将其移回。
  • 使用 DWMWA_TRANSITIONS_FORCEDISABLED 禁用帧动画。另一种非常体面的方法是使用 WS_EX_LAYERED + SetLayeredWindowAttributes() 使窗口立即变得透明和不透明。
  • 我从来不知道SW_HIDE 会触发动画。显示我知道多少!

标签: c++ winapi


【解决方案1】:

您可以使用 MoveWindow(或 SetWindowsPos)将不需要的窗口移到虚拟桌面的可见区域之外,然后将其移回。

您可能需要枚举监视器以找到所有监视器无法触及的坐标,这需要一点工作。大概您的屏幕截图代码正在计算要快照的坐标,因此您可以重新使用该计算来找到一个安全的地方来停放窗户。

【讨论】:

    【解决方案2】:

    什么对我有用:

        this->ModifyStyleEx(0, WS_EX_LAYERED | WS_EX_TOPMOST); //just a backup
    
    
        COLORREF c;
        BYTE b;
        DWORD flags;
        this->GetLayeredWindowAttributes(&c, &b, &flags); //just a backup
    
        this->SetLayeredWindowAttributes(0, 0, LWA_ALPHA);
    
    
        //CODE TO TAKE A SCREENSHOT
    
    
        this->SetLayeredWindowAttributes(c, b, flags); //just a restore
    
        this->ModifyStyleEx(WS_EX_LAYERED | WS_EX_TOPMOST, 0); //just a restore
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多