Windows XP - drawing on hidden/inactive/out of desktop window
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5

Thread: Windows XP - drawing on hidden/inactive/out of desktop window

  1. #1
    Join Date
    Sep 2012
    Posts
    3

    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:
    Name:  EQIky.jpg
Views: 462
Size:  3.3 KB
    but when part of it is moved out of desktop area as here:
    Name:  KFX44.jpg
Views: 522
Size:  61.4 KB

    im receiving that:
    Name:  N9WLa.jpg
Views: 440
Size:  1.7 KB

    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

  2. #2
    ovidiucucu's Avatar
    ovidiucucu is offline Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,058

    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.
    Ovidiu Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

  3. #3
    Join Date
    Sep 2012
    Posts
    3

    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

  4. #4
    ovidiucucu's Avatar
    ovidiucucu is offline Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,058

    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.
    Last edited by ovidiucucu; September 13th, 2012 at 04:08 AM.
    Ovidiu Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

  5. #5
    Join Date
    Sep 2012
    Posts
    3

    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

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center