C++ 获取最小化窗口的位图(如果规范化)

C++ 获取最小化窗口的位图(如果规范化),c++,windows,winapi,C++,Windows,Winapi,我正在尝试定期编写我的应用程序窗口的副本。如果窗户是标准化的,也就是在桌面上,一切正常。但是如果窗口最小化,我只得到最小化的命令栏 我尝试了各种方法,将SendMessage与WM_PRINT和PrintWindow一起使用,但都没有成功。在下面使用SendMessage的代码中,我知道规范化窗口的正确大小用于创建位图。我知道通过DefWindowProc对WM_PRINT进行的默认处理生成了一条WM_PRINTCLIENT消息。hWnd是最小化窗口的句柄 HDC

我正在尝试定期编写我的应用程序窗口的副本。如果窗户是标准化的,也就是在桌面上,一切正常。但是如果窗口最小化,我只得到最小化的命令栏

我尝试了各种方法,将SendMessage与WM_PRINT和PrintWindow一起使用,但都没有成功。在下面使用SendMessage的代码中,我知道规范化窗口的正确大小用于创建位图。我知道通过DefWindowProc对WM_PRINT进行的默认处理生成了一条WM_PRINTCLIENT消息。hWnd是最小化窗口的句柄

        HDC                 scrdc, memdc;
        HBITMAP             membit;
        WINDOWPLACEMENT     WP;
        EncoderParameters   encoderParameters;
        ULONG               quality;
        Status              status;
        RECT                Rect;

        WP.length  = sizeof (WP);
        WP.flags   = 0;
        WP.showCmd = 0;

        GetWindowPlacement (hWnd, &WP);
        int WPHeight = WP.rcNormalPosition.bottom - WP.rcNormalPosition.top;
        int WPWidth  = WP.rcNormalPosition.right  - WP.rcNormalPosition.left;

        scrdc = GetWindowDC (hWnd);                                 // source DC
        GetWindowRect(hWnd,&Rect);                                  //  source Rectangle
        int Height = Rect.bottom-Rect.top;                          //   source height
        int Width  = Rect.right-Rect.left;                          //    source width

        if (WP.showCmd == SW_SHOWMINIMIZED)
        {
            Height = WPHeight;
            Width  = WPWidth;
        }

        memdc = CreateCompatibleDC(scrdc);                          // destination DC
        membit = CreateCompatibleBitmap(scrdc, Width, Height);      //  destination bitmap
        HBITMAP hOldBitmap =(HBITMAP) SelectObject(memdc, membit);  //   add bitmap to DC

// copy screen to new BitMap

//      BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);   

//      PrintWindow (hWnd, memdc, 0);

        BitBlt 
        (
            memdc,
            0,
            0,
            GetDeviceCaps(memdc,HORZRES),
            GetDeviceCaps(memdc,VERTRES),
            NULL,
            NULL,
            NULL,
            WHITENESS
        );

        SendMessage (hWnd, WM_PRINT, unsigned int (memdc), PRF_CLIENT|PRF_NONCLIENT);
下面是WM_PRINT、WM_PRINTCLIENT和WM_PAINT处理程序的代码

    case WM_PRINT:
        return DefWindowProc (hWnd, message, wParam, lParam);

    case WM_PRINTCLIENT:
        Screen.WMPrint (hWnd, HDC (wParam), NULL);
        return true;
        return DefWindowProc (hWnd, message, wParam, lParam);

    case WM_PAINT:                          
        Screen.WMPaint (hWnd);
        break;
我还知道Screen.WMPrint会在HDC中涂鸦正确的内容

因此,如果有人能给我一些提示或建议一种方法,我将不胜感激。我可以使用Screen.WMPaint,但是我只得到了客户端区域,没有看到命令栏和边框


我不想规范化窗口,因为这会让用户感到烦恼。

这很难,因为当窗口最小化时,它看起来不像是未最小化的自己

WM_PRINT
通过调用常用的WM_NCPAINT处理程序打印窗口的非客户端区域(因为您正在传递标志)。该处理程序查看窗口状态,因此如果最小化,则无法获得所需的内容。然后它尝试打印客户端区域,但是(我怀疑)这里的最小化状态也会导致跳过这一部分——最小化窗口没有客户端区域


调用内部绘制例程可能是最简单的解决方案。是的,它只提供客户区。请注意,当您将鼠标悬停在最小化窗口的互动程序上时,在Windows 7任务栏上看到的预览也排除了非客户端区域。我认为这太难了。

这很难,因为当你的窗口最小化时,它看起来不像是未最小化的自己

WM_PRINT
通过调用常用的WM_NCPAINT处理程序打印窗口的非客户端区域(因为您正在传递标志)。该处理程序查看窗口状态,因此如果最小化,则无法获得所需的内容。然后它尝试打印客户端区域,但是(我怀疑)这里的最小化状态也会导致跳过这一部分——最小化窗口没有客户端区域


调用内部绘制例程可能是最简单的解决方案。是的,它只提供客户区。请注意,当您将鼠标悬停在最小化窗口的互动程序上时,在Windows 7任务栏上看到的预览也排除了非客户端区域。我认为这太难了。

在WM_PAINT处理程序中,假设您使用双缓冲,将backbuffer hdc设置为全局,然后当您想拍摄程序快照时,只需将该hdc设置为屏幕外位图,就可以了

以下是WM_绘制处理程序的外观:

在WM_PAINT处理程序中,假设您使用双缓冲,将backbuffer hdc设置为全局,然后当您想拍摄程序快照时,只需将该hdc设置为屏幕外位图即可

以下是WM_绘制处理程序的外观:

这可能就是构建这样一个位图的可能。我认为,为了获得标题栏和边框,在每次绘制操作之后,必须在整个窗口的位图上进行glom。然后可以删除客户端区域。这将提供一个起点,人们可以在这个起点上进行各种GDI操作。更复杂的是,任何控件(如滚动条、日期控件、编辑框等)都必须单独捕获并添加到位图中。对于我的申请,我决定不处理这种情况。我在将控件放到新位图上时遇到了很多麻烦。控件出现问题的原因是,不能简单地将其作为主窗口的子窗口,因为您只有一个位图,窗口本身被最小化,控件被遮挡或关闭在屏幕上。

这就可能构造这样的位图。我认为,为了获得标题栏和边框,在每次绘制操作之后,必须在整个窗口的位图上进行glom。然后可以删除客户端区域。这将提供一个起点,人们可以在这个起点上进行各种GDI操作。更复杂的是,任何控件(如滚动条、日期控件、编辑框等)都必须单独捕获并添加到位图中。对于我的申请,我决定不处理这种情况。我在将控件放到新位图上时遇到了很多麻烦。控件出现问题的原因是,不能简单地将其作为主窗口的子窗口,因为您只有一个位图,窗口本身正在最小化,或者控件模糊或不在屏幕上。

是否会隐藏窗口、还原窗口、使用
PrintWindow
、最小化窗口并最终显示其工作?你也可以用它来处理任务栏中的活动。隐藏窗口、还原窗口、使用
PrintWindow
、最小化窗口并最终显示它是否有效?也许你也可以用它来处理任务栏上的活动。我知道这很难!我已经为此挣扎了好几天了。如果没有其他问题,我将使用我的内部绘制例程并绘制我自己的边框。当窗口处于最小化状态时,我是否会收到一些WM消息?如果是这样的话,我可以使用SendMessage(WM_NCPAINT)在帧仍然正常化的情况下捕获帧的位图吗?然后我可以用它作为我的内部绘制例程的基础。@Mike D:我相信在最小化之前你会得到一个
WM\u WINPOSCHANGING
。你必须检查参数,看看它是什么样的大小和位置变化。我知道这很难!我被折磨了