Я читал что-то о GetDIBits или BitBlt, но я не понимаю их.
Это может быть потому, что я не понимаю, как Windows на самом деле обрабатывает графику на окнах. Было бы идеально, если бы кто-то мог направить меня на страницу, где я мог бы узнать об этих вещах! 🙂
Я решил проблему с помощью этого кода в окнах WM_PAINT. Теперь он показывает тот же контент, что и целевое окно.
PAINTSTRUCT ps;
HDC hdc = BeginPaint(MainWindow, &ps);
HDC TargetDC = GetDC(TargetWindow);
RECT rect;
GetWindowRect(TargetWindow, &rect);
BitBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,TargetDC,0,0,SRCCOPY);
EndPaint(MainWindow, &ps);
Возможно, вам посчастливится отправить окно WM_PRINTCLIENT сообщение. Это может не работать для окон, которые используют DirectX или OpenGL.
У вас могут возникнуть проблемы с использованием WM_PRINTCLIENT в системах, в которых включен Aero (т. Е. Когда активен DWM). Если в системе активен DWM, то она может предложить способы получить доступ к хранилищу окон, но я раньше не рассматривал эту проблему.
То, что вы хотите, это:
В качестве альтернативы для шага 3 вы можете использовать DWM или стать хакером с помощью буфера обмена:
void CopyWndToClipboard(CWnd *pWnd)
{
CBitmap bitmap;
CClientDC dc(pWnd);
CDC memDC;
CRect rect;
memDC.CreateCompatibleDC(&dc);
pWnd->GetWindowRect(rect);
bitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height());
CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);
memDC.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);
pWnd->OpenClipboard() ;
EmptyClipboard() ;
SetClipboardData(CF_BITMAP, bitmap.GetSafeHandle()) ;
CloseClipboard() ;
memDC.SelectObject(pOldBitmap);
bitmap.Detach();
}