如果规范化,获取最小化窗口的位图

时间:2012-02-24 20:41:28

标签: c++ windows winapi

我正在尝试定期编写应用程序窗口的副本。如果窗口正常化,事情就可以正常工作了。在桌面上。但是如果窗口最小化,我只得到最小化的命令栏。

我尝试过使用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但是我只得到客户区并错过命令栏和边框。

我不想对窗口进行规范化,因为这会使用户烦恼。

3 个答案:

答案 0 :(得分:0)

这很难,因为当你的窗口被最小化时,它看起来并不像它未被最小化的自我。

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

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

答案 1 :(得分:0)

在你的WM_PAINT处理程序中,假设你正在使用双缓冲,让你的backbuffer hdc全局,然后当你想拍摄程序的快照时,只需将HDC写入屏幕外的位图,然后就可以了

这是你的WM_PAINT处理程序应该是这样的: http://pastebin.com/aNvtHiD6

答案 2 :(得分:0)

这可能只是构造这样的位图。我认为在每次绘制操作之后,为了获得标题栏和边框,必须在整个窗口的位图上闪烁。然后可以擦除客户区。这将给出一个可以进行各种GDI操作的起点。更复杂的是,任何控件(如滚动条,日期控件,编辑框等)都必须单独捕获并添加到位图中。对于我的申请,我认为我不会处理最小化的情况。我在将控件放到新位图上时遇到了麻烦。控件的问题出现是因为人们不能简单地让它们成为主窗口的子项,因为你拥有的只是一个位图,窗口本身被最小化或控件被遮挡或离开屏幕。