3 Attachment(s)
Windows XP - drawing on hidden/inactive/out of desktop window
Hi
Im developing a program that need to take snapshot from main application window and write it to jpeg file, when window is on the desktop center its all ok:
Attachment 30325
but when part of it is moved out of desktop area as here:
Attachment 30323
im receiving that:
Attachment 30327
i have this problem on windows xp(win 7 works fine, didnt check on vista), as you ma guess i would like to receive same snapshot as on the screen 1, even if windows is moved out of desktop area, thanks for help
Re: Windows XP - drawing on hidden/inactive/out of desktop window
Which API function(s) have you used to take snapshots?
A sample code would be useful to find out what you are doing wrong.
Re: Windows XP - drawing on hidden/inactive/out of desktop window
Im using gdiplus, here is the code
Code:
int GetEncoderClsid(WCHAR *format, CLSID *pClsid)
{
unsigned int num = 0, size = 0;
GetImageEncodersSize(&num, &size);
if(size == 0) return -1;
ImageCodecInfo *pImageCodecInfo=(ImageCodecInfo*)GlobalAlloc(GPTR,size);
if(pImageCodecInfo == NULL) return -1;
GetImageEncoders(num, size, pImageCodecInfo);
for(unsigned int j = 0; j < num; ++j){
if(wcscmp(pImageCodecInfo[j].MimeType, format) == 0){
*pClsid = pImageCodecInfo[j].Clsid;
GlobalFree(pImageCodecInfo);
return j;
}
}
GlobalFree(pImageCodecInfo);
return -1;
}
int GetScreeny(HWND hTarget,char* file,ULONG uQuality)
{
LPWSTR lpszFilename=(LPWSTR)GlobalAlloc(GPTR,sizeof(WCHAR)*MAX_PATH);
MultiByteToWideChar(CP_ACP, 0, file, -1, lpszFilename, MAX_PATH);
ULONG_PTR gdiplusToken;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
//HDC hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL);
HDC hdcScreen=GetDC(hTarget);
HDC hdcCapture = CreateCompatibleDC(hdcScreen);
//int nWidth = GetDeviceCaps(hdcScreen, HORZRES),
//int nHeight = GetDeviceCaps(hdcScreen, VERTRES),
int nWidth=300;
int nHeight=300;
int nBPP = GetDeviceCaps(hdcCapture, BITSPIXEL);
LPBYTE lpCapture;
BITMAPINFO bmiCapture = { {
sizeof(BITMAPINFOHEADER), nWidth, -nHeight, 1, nBPP, BI_RGB, 0, 0, 0, 0, 0,
} };
HBITMAP hbmCapture = CreateDIBSection(hdcScreen, &bmiCapture,
DIB_PAL_COLORS, (LPVOID *)&lpCapture, NULL, 0);
if(!hbmCapture){
DeleteDC(hdcCapture);
DeleteDC(hdcScreen);
GdiplusShutdown(gdiplusToken);
return 1;
}
int nCapture = SaveDC(hdcCapture);
SelectObject(hdcCapture, hbmCapture);
BitBlt(hdcCapture, 0, 0, nWidth, nHeight, hdcScreen, 0, 0, SRCCOPY);
RestoreDC(hdcCapture, nCapture);
DeleteDC(hdcCapture);
DeleteDC(hdcScreen);
CLSID imageCLSID;
//Bitmap *pScreenShot = new Bitmap(hbmCapture, (HPALETTE)NULL);
GpBitmap *bitmap = NULL;
DllExports::GdipCreateBitmapFromHBITMAP(hbmCapture, (HPALETTE)NULL, &bitmap);
EncoderParameters encoderParams;
encoderParams.Count = 1;
encoderParams.Parameter[0].NumberOfValues = 1;
encoderParams.Parameter[0].Guid = EncoderQuality;
encoderParams.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParams.Parameter[0].Value = &uQuality;
GetEncoderClsid(L"image/jpeg", &imageCLSID);
//int result = (pScreenShot->Save(lpszFilename, &imageCLSID, &encoderParams) == Ok);
DllExports::GdipSaveImageToFile(bitmap,lpszFilename, &imageCLSID, &encoderParams);
//delete pScreenShot;
DeleteObject(hbmCapture);
GdiplusShutdown(gdiplusToken);
GlobalFree(lpszFilename);
return 0;
}
But i think that code works just fine
I have even downloaded some screenshot programs but none of them except ashampoo screen capture doesn't had option to capture user-defined window, i found only "full destktop, foreground window, user-snipped area", and ashampoo havent't captured full window too...only the part that was visible on the desktop
Its rather look like windows xp just don't paint on that part of window and my question is : is there a way to force it to paint on that area?
i have tried with WM_PAINT/WM_PRINT message etc. but nothing worked for me, GetPixel is returnig 255,255,255 values for invisible part of window
Re: Windows XP - drawing on hidden/inactive/out of desktop window
For starting purpose, you can have a look at this article: Easy Screen Capture Using MFC/ATL.
It provides an easier way than GDI+, by extending CImage class which uses GDI+ itself.
It has a lightweight implementation but can be easily improved, e.g. by adding a method that capures an arbitrary window, other than the foreground one. Or, you can let it as it is, and bring to front the desired window from your application before capture.
However, it does not resolve the OP problem. But probably, you have made a false assumption: capturing a window partially out-of-screen works on Windows 7 and doesn't work on XP. Most possible, you have set multi-monitor display on one system, while the other one has set only primary display monitor. So, if a part of a window falls in another monitor area, then no problem. Otherwise, that's it... Windows doesn't paint outside the (virtual) display area.
One alternative solution is to use PrintWindow function. It allows "capturing" covered and off-screen windows but loses layered and desktop composition (aero) effects.
Re: Windows XP - drawing on hidden/inactive/out of desktop window
PrintWindow works, i tried that before but looks like i did something wrong and didn't worked, thank you very much