Can make Qt under
grabWindow(WId window, int x = 0, int y = 0, int width = -1, int height = -1)
Create and return a QPixmap by grabbing the contents of a given window (x, y, width, height).
The parameters (x, y) specify the offset in the window, and (width, height) specify the area to be copied. If the width is negative, the function copies everything to the right boundary of the window. If the height is negative, the function copies everything to the bottom of the window.
The window system identifier (WId) can be retrieved using the QWidget::winId() function. The basic principle of using window identifiers instead of QWidget is to allow windows that are not part of application windows system frameworks and so on.
The main implementation code:
QPixmap m_pixmap = QPixmap::grabWindow(QApplication::desktop()->winId()); m_pixmap ->save("test.jpg");
But one drawback of this method is that it can't grab the mouse; it's not mouse cursor in the implementation of QT grabWindow.
The concrete realization is as follows
QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h ) { RECT r; GetClientRect(winId, &r); if (w < 0) w = r.right - r.left; if (h < 0) h = r.bottom - r.top; #ifdef Q_WS_WINCE_WM if (qt_wince_is_pocket_pc()) { QWidget *widget = QWidget::find(winId); if (qobject_cast<QDesktopWidget *>(widget)) { RECT rect = {0,0,0,0}; AdjustWindowRectEx(&rect, WS_BORDER | WS_CAPTION, FALSE, 0); int magicNumber = qt_wince_is_high_dpi() ? 4 : 2; y += rect.top - magicNumber; } } #endif // Create and setup bitmap HDC display_dc = GetDC(0); HDC bitmap_dc = CreateCompatibleDC(display_dc); HBITMAP bitmap = CreateCompatibleBitmap(display_dc, w, h); HGDIOBJ null_bitmap = SelectObject(bitmap_dc, bitmap); // copy data HDC window_dc = GetDC(winId); BitBlt(bitmap_dc, 0, 0, w, h, window_dc, x, y, SRCCOPY #ifndef Q_WS_WINCE | CAPTUREBLT #endif ); // clean up all but bitmap ReleaseDC(winId, window_dc); SelectObject(bitmap_dc, null_bitmap); DeleteDC(bitmap_dc); QPixmap pixmap = QPixmap::fromWinHBITMAP(bitmap); DeleteObject(bitmap); ReleaseDC(0, display_dc); return pixmap; }
So let's change our minds; let's do it ourselves. Don't say much about code directly
QPixmap MainWindow::grabWindow(HWND winId, int x, int y, int w, int h) { RECT r; GetClientRect(winId, &r); if (w < 0) w = r.right - r.left; if (h < 0) h = r.bottom - r.top; HDC display_dc = GetDC(winId); HDC bitmap_dc = CreateCompatibleDC(display_dc); HBITMAP bitmap = CreateCompatibleBitmap(display_dc, w, h); HGDIOBJ null_bitmap = SelectObject(bitmap_dc, bitmap); BitBlt(bitmap_dc, 0, 0, w, h, display_dc, x, y, SRCCOPY | CAPTUREBLT); CURSORINFO ci; ci.cbSize = sizeof(CURSORINFO); GetCursorInfo(&ci); if((ci.ptScreenPos.x > x) && (ci.ptScreenPos.y > y) && (ci.ptScreenPos.x < (x+w)) && (ci.ptScreenPos.y < (y+h))) DrawIcon(bitmap_dc, ci.ptScreenPos.x-x, ci.ptScreenPos.y-y, ci.hCursor); // clean up all but bitmap ReleaseDC(winId, display_dc); SelectObject(bitmap_dc, null_bitmap); DeleteDC(bitmap_dc); QPixmap pixmap = QtWin::fromHBITMAP(bitmap); DeleteObject(bitmap); return pixmap; }