Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
Windos
win32.3rdparty
win32.directx.audio
win32.directx.ddk
win32.directx.graphics
win32.directx.input
win32.directx.managed
win32.directx.misc
win32.directx.networking
win32.directx.sdk
win32.directx.video
win32.dirx.grap.shaders
win32.gdi
win32.international
win32.kernel
win32.messaging
win32.mmedia
win32.networks
win32.ole
win32.rtc
win32.tapi
win32.tapi.beta
win32.tools
win32.ui
win32.wince
win32.wmi
windows.mediacenter
winfx.aero
winfx.announcements
winfx.avalon
winfx.collaboration
winfx.fundamentals
winfx.general
winfx.indigo
winfx.sdk
winfx.winfs
  
 
date: Tue, 01 Jul 2008 13:15:36 +0800,    group: microsoft.public.win32.programmer.gdi        back       


Having problems with screenshot code on windows vista   
We have a program which renders some graphics with Direct3D9.
We am using some GDI code to take a screenshot of the window with these 
graphics in it.
We have a screenshot class that contains (among other things) these variables
HDC bufferDevice;
HBITMAP bufferBitmap;
uint bufferWidth;
uint bufferHeight;

When a screenshot is made, this function is called
void Screenshot::makeBuffer(HWND windowHandle)
{
	RECT clientRect;
	GetClientRect(windowHandle, &clientRect);

	bufferWidth = clientRect.right - clientRect.left; // GetSystemMetrics 
(SM_CXSCREEN);
	bufferHeight = clientRect.bottom - clientRect.top; // GetSystemMetrics 
(SM_CYSCREEN);

	assert(bufferWidth > 0);
	assert(bufferHeight > 0);

	HDC targetDevice = GetDC (windowHandle);

	if (bufferDevice)
	{
		DeleteObject (bufferBitmap);
		DeleteDC (bufferDevice);
	}

	bufferDevice = CreateCompatibleDC (targetDevice);
	bufferBitmap = CreateCompatibleBitmap (targetDevice, bufferWidth, 
bufferHeight);
	HGDIOBJ oldObj = SelectObject (bufferDevice, bufferBitmap);
	
	BitBlt (bufferDevice, 0, 0, bufferWidth, bufferHeight, targetDevice, 0, 0, 
SRCCOPY);

	SelectObject(bufferDevice,oldObj);
	ReleaseDC (windowHandle, targetDevice);
}

Then I queue this Screenshot object on another thread to do the actual 
write-to-file.
The write-to-file looks like this
bool Screenshot::writeToFile()
{
	// Get bitmap data
	RGBTRIPLE* bufferPixels = new RGBTRIPLE[bufferWidth*bufferHeight];
	BITMAPINFO bufferBitmapInfo = {{sizeof(BITMAPINFOHEADER), bufferWidth, 
-(signed)bufferHeight, 1, 24, BI_RGB}};
	
	if (!GetDIBits(bufferDevice, bufferBitmap, 0, bufferHeight, bufferPixels, 
&bufferBitmapInfo, DIB_RGB_COLORS))
	{
		delete[] bufferPixels;
		return false;
	}
	// Construct rows
	RGBTRIPLE** bufferScanlines = new RGBTRIPLE*[bufferHeight];
	RGBTRIPLE* bufferScanlineIter = bufferPixels;
	for (unsigned int scanlineIndex = 0; scanlineIndex < bufferHeight; 
scanlineIndex++)
	{
		bufferScanlines[scanlineIndex] = bufferScanlineIter;
		bufferScanlineIter += bufferWidth;
	}

	DeleteObject (bufferBitmap);
	bufferBitmap = 0;
	DeleteObject (bufferDevice);
	bufferDevice = 0;
	<actual code for writing to file goes here>
}

On Windows XP, this code works flawlessly.
On one of our test machines running Windows Vista, if you take a second 
screenshot or a third or a forth, they always end up with the same content 
as the first one.
We have run a full run with application verifier (with "basics", "dirty 
stacks" and "dangerous APIs" turned on) on both the XP and Vista machines 
and no problems have shown up.

XP machine is running XP SP3 and everything listed on windows update.
Vista machine is Vista Ultimate x64 with SP1 and all updates.
Also failing on Vista Ultimate x86 with the same problem.
Any ideas on how to fix this (or even how to see whats going on inside GDI 
and what might be causing this) would be appreciated. If more information 
about the problem is required, I can provide it.
date: Tue, 01 Jul 2008 13:15:36 +0800   author:   Jonathan Wilson

Re: Having problems with screenshot code on windows vista   
Maybe a GdiFlush() will do the trick... worth a try...

"Jonathan Wilson" 
> We have a program which renders some graphics with Direct3D9.
> We am using some GDI code to take a screenshot of the window with these 
> graphics in it.
> We have a screenshot class that contains (among other things) these 
> variables
> HDC bufferDevice;
> HBITMAP bufferBitmap;
> uint bufferWidth;
> uint bufferHeight;
>
> When a screenshot is made, this function is called
> void Screenshot::makeBuffer(HWND windowHandle)
> {
> RECT clientRect;
> GetClientRect(windowHandle, &clientRect);
>
> bufferWidth = clientRect.right - clientRect.left; // GetSystemMetrics 
> (SM_CXSCREEN);
> bufferHeight = clientRect.bottom - clientRect.top; // GetSystemMetrics 
> (SM_CYSCREEN);
>
> assert(bufferWidth > 0);
> assert(bufferHeight > 0);
>
> HDC targetDevice = GetDC (windowHandle);
>
> if (bufferDevice)
> {
> DeleteObject (bufferBitmap);
> DeleteDC (bufferDevice);
> }
>
> bufferDevice = CreateCompatibleDC (targetDevice);
> bufferBitmap = CreateCompatibleBitmap (targetDevice, bufferWidth, 
> bufferHeight);
> HGDIOBJ oldObj = SelectObject (bufferDevice, bufferBitmap);
>
> BitBlt (bufferDevice, 0, 0, bufferWidth, bufferHeight, targetDevice, 0, 0, 
> SRCCOPY);
>
> SelectObject(bufferDevice,oldObj);
> ReleaseDC (windowHandle, targetDevice);
> }
>
> Then I queue this Screenshot object on another thread to do the actual 
> write-to-file.
> The write-to-file looks like this
> bool Screenshot::writeToFile()
> {
> // Get bitmap data
> RGBTRIPLE* bufferPixels = new RGBTRIPLE[bufferWidth*bufferHeight];
> BITMAPINFO bufferBitmapInfo = {{sizeof(BITMAPINFOHEADER), 
> bufferWidth, -(signed)bufferHeight, 1, 24, BI_RGB}};
>
> if (!GetDIBits(bufferDevice, bufferBitmap, 0, bufferHeight, bufferPixels, 
> &bufferBitmapInfo, DIB_RGB_COLORS))
> {
> delete[] bufferPixels;
> return false;
> }
> // Construct rows
> RGBTRIPLE** bufferScanlines = new RGBTRIPLE*[bufferHeight];
> RGBTRIPLE* bufferScanlineIter = bufferPixels;
> for (unsigned int scanlineIndex = 0; scanlineIndex < bufferHeight; 
> scanlineIndex++)
> {
> bufferScanlines[scanlineIndex] = bufferScanlineIter;
> bufferScanlineIter += bufferWidth;
> }
>
> DeleteObject (bufferBitmap);
> bufferBitmap = 0;
> DeleteObject (bufferDevice);
> bufferDevice = 0;
> <actual code for writing to file goes here>
> }
>
> On Windows XP, this code works flawlessly.
> On one of our test machines running Windows Vista, if you take a second 
> screenshot or a third or a forth, they always end up with the same content 
> as the first one.
> We have run a full run with application verifier (with "basics", "dirty 
> stacks" and "dangerous APIs" turned on) on both the XP and Vista machines 
> and no problems have shown up.
>
> XP machine is running XP SP3 and everything listed on windows update.
> Vista machine is Vista Ultimate x64 with SP1 and all updates.
> Also failing on Vista Ultimate x86 with the same problem.
> Any ideas on how to fix this (or even how to see whats going on inside GDI 
> and what might be causing this) would be appreciated. If more information 
> about the problem is required, I can provide it.
date: Sun, 6 Jul 2008 23:32:06 +0200   author:   Saju

Re: Having problems with screenshot code on windows vista   
If you disable the DWM (switch to Aero Basic, for example) does it fix the 
problem?
If so, you may need to use the new window thumbnailing API to get reliable 
results when the DWM is active.

"Jonathan Wilson"  wrote in message 
news:ezpWBmz2IHA.3544@TK2MSFTNGP05.phx.gbl...
> On one of our test machines running Windows Vista, if you take a second 
> screenshot or a third or a forth, they always end up with the same content 
> as the first one.
date: Mon, 7 Jul 2008 09:14:17 +1000   author:   Jon Potter am

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us