|
|
|
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
|
|