PDA

View Full Version : screenshots



arthurprs
07-02-2009, 08:24 PM
im developing an app that take screenshots of games,
at the moment i use this method, but it don't work in some windows vista/seven systems


function GetPrintScreen(wnd: HWND): TBitmap;
var
h, w: Integer;
dc: HDC;
rect: TRect;
begin
dc := GetDC(wnd);
if (dc = 0) or (not GetClientRect(wnd, rect)) then
begin
Result := nil;
Exit;
end;

w := rect.Right - rect.Left;
h := rect.Bottom - rect.Top;

Result := TBitmap.Create;
Result.Width := w;
Result.Height := h;

BitBlt(
Result.Canvas.Handle, 0, 0,
w, h,
dc, 0, 0,
SRCCOPY);

ReleaseDC(wnd, dc);
end;

so,
someone know another way to get screenshots?

jdarling
07-02-2009, 10:13 PM
Google code search returns the following:


procedure MakeDesktopScreenshot( const FN : string );
var
DesktopDC : HDC;
myBitmap : TBitmap;
ScreenHandle : HWND;
begin
myBitmap := TBitmap.Create;
try
ScreenHandle := GetDesktopWindow;
DesktopDC := GetDC( ScreenHandle );
try
myBitmap.Width := screen.Width;
myBitmap.Height := screen.Height;
BitBlt( myBitmap.Canvas.Handle, 0, 0, screen.Width, screen.Height, DesktopDC, 0, 0, SRCCOPY );
if &#40; FN <> '' &#41; then
myBitmap.SaveToFile&#40; FN &#41;
else
Clipboard.Assign&#40; myBitmap &#41;;
finally
ReleaseDC&#40; ScreenHandle, DesktopDC &#41;;
end;
finally
myBitmap.Free;
end;
end; // MakeDesktopScreenshot



procedure MakeFormScreenshot&#40;hWindow&#58; HWND; const Filename &#58; string &#41;;
var
Left, Top, Width, Height&#58; Word;
R&#58; TRect;
dc&#58; HDC;
lpPal&#58; PLOGPALETTE;
BM &#58; TBitmap;
begin
&#123;Check if valid window handle&#125;
if not IsWindow&#40;hWindow&#41; then Exit;
&#123;Retrieves the rectangular coordinates of the specified window&#125;
GetWindowRect&#40;hWindow, R&#41;;
Left &#58;= R.Left;
Top &#58;= R.Top;
Width &#58;= R.Right - R.Left;
Height &#58;= R.Bottom - R.Top;

&#123;get the screen dc&#125;
dc &#58;= GetDc&#40;0&#41;;
if &#40;dc = 0&#41; then
exit;


BM &#58;= TBitmap.Create;
try

bm.Width &#58;= Width;
bm.Height &#58;= Height;

&#123;do we have a palette device?&#125;
if &#40;GetDeviceCaps&#40;dc, RASTERCAPS&#41; and
RC_PALETTE = RC_PALETTE&#41; then
begin
&#123;allocate memory for a logical palette&#125;
GetMem&#40;lpPal,
SizeOf&#40;TLOGPALETTE&#41; +
&#40;255 * SizeOf&#40;TPALETTEENTRY&#41;&#41;&#41;;
&#123;zero it out to be neat&#125;
FillChar&#40;lpPal^,
SizeOf&#40;TLOGPALETTE&#41; +
&#40;255 * SizeOf&#40;TPALETTEENTRY&#41;&#41;,
#0&#41;;
&#123;fill in the palette version&#125;
lpPal^.palVersion &#58;= $300;
&#123;grab the system palette entries&#125;
lpPal^.palNumEntries &#58;=
GetSystemPaletteEntries&#40;dc,
0,
256,
lpPal^.palPalEntry&#41;;
if &#40;lpPal^.PalNumEntries <> 0&#41; then
begin
&#123;create the palette&#125;
bm.Palette &#58;= CreatePalette&#40;lpPal^&#41;;
end;
FreeMem&#40;lpPal, SizeOf&#40;TLOGPALETTE&#41; +
&#40;255 * SizeOf&#40;TPALETTEENTRY&#41;&#41;&#41;;
end;
&#123;copy from the screen to the bitmap&#125;
BitBlt&#40;bm.Canvas.Handle,
0,
0,
Width,
Height,
Dc,
Left,
Top,
SRCCOPY&#41;;
&#123;release the screen dc&#125;
ReleaseDc&#40;0, dc&#41;;

BM.SaveToFile&#40; Filename &#41;;

finally
BM.Free;
end;

end;

Haven't tried it, as usually I just include it in my games via a quick key.

arthurprs
08-02-2009, 06:40 PM
jdarling, this is the same method that i use, via GDI, im searching for another way :|

arthurprs
12-02-2009, 11:05 PM
after some insente googling i found that creating a opengl fullscreen context and then use glReadPixels() can work

but how can i do that?
thanks.

chronozphere
13-02-2009, 07:17 PM
Google is your friend. ;)

http://www.gamedev.net/community/forums/topic.asp?topic_id=436385

arthurprs
14-02-2009, 04:08 AM
Google is your friend. ;)

http://www.gamedev.net/community/forums/topic.asp?topic_id=436385

hi chronozphere, i found how to capture the screenshots,
but i don't know how to create a opengl fullscreen context over the current running game window

KidPaddle
14-02-2009, 08:15 AM
Only German, but with samples for saving screenshots to bmp or tga file format.

http://wiki.delphigl.com/index.php/Screenshot

I try to translate the comments for bimtap version


procedure ScreenShot(const Name : string);
var
F : file;
FileInfo: BITMAPINFOHEADER;
FileHeader : BITMAPFILEHEADER;
pPicData:Pointer;
Viewport : array[0..3] of integer;
begin
// clear header
ZeroMemory(@FileHeader, SizeOf(BITMAPFILEHEADER));
ZeroMemory(@FileInfo, SizeOf(BITMAPINFOHEADER));

// query screen size of viewpoint
glGetIntegerv(GL_VIEWPORT, @Viewport);

// Init header
FileHeader.bfType := 19778; //$4D42 = 'BM'
FileHeader.bfOffBits := SizeOf(BITMAPINFOHEADER)+SizeOf(BITMAPFILEHEADER);

// setup bitmap header
FileInfo.biSize := SizeOf(BITMAPINFOHEADER);
FileInfo.biWidth := Viewport[2];
FileInfo.biHeight := Viewport[3];
FileInfo.biPlanes := 1;
FileInfo.biBitCount := 32;
FileInfo.biSizeImage := FileInfo.biWidth*FileInfo.biHeight*(FileInfo.biBit Count div 8);

// setup file size
FileHeader.bfSize := FileHeader.bfOffBits + FileInfo.biSizeImage;

// get memory for image
GetMem(pPicData, FileInfo.biSizeImage);
try
// read pixels from opengl frame buffer
glReadPixels(0, 0, Viewport[2], Viewport[3], GL_BGRA, GL_UNSIGNED_BYTE, pPicData);

// write image to disk, modern version are using streams
AssignFile(f, name);
Rewrite( f,1 );
try
BlockWrite(F, FileHeader, SizeOf(BITMAPFILEHEADER));
BlockWrite(F, FileInfo, SizeOf(BITMAPINFOHEADER));
BlockWrite(F, pPicData^, FileInfo.biSizeImage );
finally
CloseFile(f);
end;
finally
// free reserved pixel data
FreeMem(pPicData, FileInfo.biSizeImage);
end;
end;