Try this code:
proc main()
Win2Bmp(,, 'SCR_S.bmp') // Full Screen
Win2Bmp(, .t., 'SCR_W.bmp') // Full window w/ border, title, ...
Win2Bmp(, .f., 'SCR_C.bmp') // Windows' client area
return
#pragma BEGINDUMP
#include <windows.h>
#include "hbapi.h"
/*
* Win2Bmp( [nWnd], [lFullWindow] [,cBmFile] ) --> nBitMap
*
* hWnd : window handle - if NIL then GetForegroundWindow()
* lFullWindow : .T. = Window, .F. = Client, Nil = Screen
* cBmFile : FileName for .bmp file
*/
HB_FUNC( WIN2BMP )
{
HWND hWnd = ISNUM( 1 ) ? (HWND) hb_parnl( 1 ) :
ISPOINTER( 1 ) ? (HWND) hb_parptr( 1 ) : GetForegroundWindow();
UINT iWhat = ISLOG( 2 ) ? ( hb_parl( 2 ) ? 1 : 2 ) : 0;
const char *pszBmF = ISCHAR( 3 ) && hb_parclen( 3 ) ? hb_parc( 3 ) : NULL; HDC hdcWin, hdcMem;
HBITMAP hbmWin;
RECT rc;
if( iWhat == 1 )
{
hdcWin = GetWindowDC( hWnd );
GetWindowRect( hWnd, &rc );
}
else if( iWhat == 2 )
{
hdcWin = GetDC( hWnd );
GetClientRect( hWnd, &rc );
}
else
{
hdcWin = GetDC( NULL );
rc.left = rc.top = 0;
rc.right = GetSystemMetrics( SM_CXSCREEN );
rc.bottom = GetSystemMetrics( SM_CYSCREEN );
}
hdcMem = CreateCompatibleDC( hdcWin );
hbmWin = CreateCompatibleBitmap( hdcWin, rc.right - rc.left, rc.bottom - rc.top );
SelectObject( hdcMem, hbmWin );
BitBlt( hdcMem, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hdcWin, 0, 0, SRCCOPY );
if( pszBmF ) // Save bmp to .bmp file ?
{
BITMAP bmWin;
BITMAPFILEHEADER bmfHdr;
BITMAPINFOHEADER bmiHdr;
LPBITMAPINFOHEADER lpbmi;
DWORD dwBmSize, dwByWritten = 0;
HANDLE hBmF;
// Get the BITMAP from the HBITMAP
GetObject( hbmWin, sizeof( BITMAP ), &bmWin );
// Fill in BITMAPINFOHEADER structure
memset( (void *) &bmiHdr, 0, sizeof( BITMAPINFOHEADER ) );
bmiHdr.biSize = sizeof( BITMAPINFOHEADER );
bmiHdr.biWidth = bmWin.bmWidth;
bmiHdr.biHeight = bmWin.bmHeight;
bmiHdr.biPlanes = 1; // Should always be 1
bmiHdr.biBitCount = 32; // color resolution (in bits per pixel) bmiHdr.biCompression = BI_RGB;
//bmiHdr.biSizeImage =
//bmiHdr.biXPelsPerMeter =
//bmiHdr.biYPelsPerMeter =
//bmiHdr.biClrUsed =
//bmiHdr.biClrImportant = 0;
dwBmSize = ( ( bmiHdr.biWidth * bmiHdr.biBitCount + 31 ) / 32 ) * 4 * bmiHdr.biHeight;
lpbmi = (LPBITMAPINFOHEADER) hb_xgrab( sizeof( BITMAPINFOHEADER ) + dwBmSize );
*lpbmi = bmiHdr;
GetDIBits( hdcWin, hbmWin, 0, (UINT) bmWin.bmHeight, lpbmi, (BITMAPINFO *) lpbmi, DIB_RGB_COLORS );
// Fill in BITMAPFILEHEADER structure
memset( (void *) &bmfHdr, 0, sizeof( BITMAPFILEHEADER ) );
bmfHdr.bfType = 0x4D42; //= "BM"
bmfHdr.bfSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + dwBmSize;
bmfHdr.bfOffBits = (DWORD) sizeof( BITMAPFILEHEADER ) + (DWORD) sizeof( BITMAPINFOHEADER );
// Create and Write .bmp file and Close it
hBmF = CreateFile( pszBmF, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
WriteFile( hBmF, (LPSTR) &bmfHdr, sizeof( BITMAPFILEHEADER ), &dwByWritten, NULL );
WriteFile( hBmF, (LPSTR) &bmiHdr, sizeof( BITMAPINFOHEADER ), &dwByWritten, NULL );
WriteFile( hBmF, (LPSTR) lpbmi, dwBmSize, &dwByWritten, NULL );
CloseHandle( hBmF );
hb_xfree( lpbmi );
}
DeleteDC( hdcMem );
ReleaseDC( hWnd, hdcWin );
hb_retnl( (LONG) hbmWin );
}
#pragma ENDDUMP
Best regards,
Saulius
El lunes, 14 de mayo de 2012 a la(s) 14:06:43 UTC-3, Saulius escribió:Thank you Claudio!
Try this code:
proc main()
Win2Bmp(,, 'SCR_S.bmp') // Full Screen
Win2Bmp(, .t., 'SCR_W.bmp') // Full window w/ border, title, ...
Win2Bmp(, .f., 'SCR_C.bmp') // Windows' client area
return
#pragma BEGINDUMP
#include <windows.h>
#include "hbapi.h"
/*
* Win2Bmp( [nWnd], [lFullWindow] [,cBmFile] ) --> nBitMap
*
* hWnd : window handle - if NIL then GetForegroundWindow()
* lFullWindow : .T. = Window, .F. = Client, Nil = Screen
* cBmFile : FileName for .bmp file
*/
HB_FUNC( WIN2BMP )
{
HWND hWnd = ISNUM( 1 ) ? (HWND) hb_parnl( 1 ) :
ISPOINTER( 1 ) ? (HWND) hb_parptr( 1 ) : GetForegroundWindow();
UINT iWhat = ISLOG( 2 ) ? ( hb_parl( 2 ) ? 1 : 2 ) : 0;
const char *pszBmF = ISCHAR( 3 ) && hb_parclen( 3 ) ? hb_parc( 3 ) : NULL; HDC hdcWin, hdcMem;
HBITMAP hbmWin;
RECT rc;
if( iWhat == 1 )
{
hdcWin = GetWindowDC( hWnd );
GetWindowRect( hWnd, &rc );
}
else if( iWhat == 2 )
{
hdcWin = GetDC( hWnd );
GetClientRect( hWnd, &rc );
}
else
{
hdcWin = GetDC( NULL );
rc.left = rc.top = 0;
rc.right = GetSystemMetrics( SM_CXSCREEN );
rc.bottom = GetSystemMetrics( SM_CYSCREEN );
}
hdcMem = CreateCompatibleDC( hdcWin );
hbmWin = CreateCompatibleBitmap( hdcWin, rc.right - rc.left, rc.bottom - rc.top );
SelectObject( hdcMem, hbmWin );
BitBlt( hdcMem, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hdcWin, 0, 0, SRCCOPY );
if( pszBmF ) // Save bmp to .bmp file ?
{
BITMAP bmWin;
BITMAPFILEHEADER bmfHdr;
BITMAPINFOHEADER bmiHdr;
LPBITMAPINFOHEADER lpbmi;
DWORD dwBmSize, dwByWritten = 0;
HANDLE hBmF;
// Get the BITMAP from the HBITMAP
GetObject( hbmWin, sizeof( BITMAP ), &bmWin );
// Fill in BITMAPINFOHEADER structure
memset( (void *) &bmiHdr, 0, sizeof( BITMAPINFOHEADER ) );
bmiHdr.biSize = sizeof( BITMAPINFOHEADER );
bmiHdr.biWidth = bmWin.bmWidth;
bmiHdr.biHeight = bmWin.bmHeight;
bmiHdr.biPlanes = 1; // Should always be 1
bmiHdr.biBitCount = 32; // color resolution (in bits per pixel) bmiHdr.biCompression = BI_RGB;
//bmiHdr.biSizeImage =
//bmiHdr.biXPelsPerMeter =
//bmiHdr.biYPelsPerMeter =
//bmiHdr.biClrUsed =
//bmiHdr.biClrImportant = 0;
dwBmSize = ( ( bmiHdr.biWidth * bmiHdr.biBitCount + 31 ) / 32 ) * 4 * bmiHdr.biHeight;
lpbmi = (LPBITMAPINFOHEADER) hb_xgrab( sizeof( BITMAPINFOHEADER ) + dwBmSize );
*lpbmi = bmiHdr;
GetDIBits( hdcWin, hbmWin, 0, (UINT) bmWin.bmHeight, lpbmi, (BITMAPINFO *) lpbmi, DIB_RGB_COLORS );
// Fill in BITMAPFILEHEADER structure
memset( (void *) &bmfHdr, 0, sizeof( BITMAPFILEHEADER ) );
bmfHdr.bfType = 0x4D42; //= "BM"
bmfHdr.bfSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + dwBmSize;
bmfHdr.bfOffBits = (DWORD) sizeof( BITMAPFILEHEADER ) + (DWORD) sizeof( BITMAPINFOHEADER );
// Create and Write .bmp file and Close it
hBmF = CreateFile( pszBmF, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
WriteFile( hBmF, (LPSTR) &bmfHdr, sizeof( BITMAPFILEHEADER ), &dwByWritten, NULL );
WriteFile( hBmF, (LPSTR) &bmiHdr, sizeof( BITMAPINFOHEADER ), &dwByWritten, NULL );
WriteFile( hBmF, (LPSTR) lpbmi, dwBmSize, &dwByWritten, NULL ); CloseHandle( hBmF );
hb_xfree( lpbmi );
}
DeleteDC( hdcMem );
ReleaseDC( hWnd, hdcWin );
hb_retnl( (LONG) hbmWin );
}
#pragma ENDDUMP
Best regards,Hi! sorry for jumping over an old message.
Saulius
This routine works perfectly BUT has a drawback: generates memory leaks.
If used repeatedly over a day (calling it every 5'), then the computer lost about 1.5 gb of ram. Closing the application and starting again solves the problem.
My solution to avoid this involves modifying a couple of lines, as seen below.
From:
...
CloseHandle( hBmF );
hb_xfree( lpbmi );
}
DeleteDC( hdcMem );
ReleaseDC( hWnd, hdcWin );
hb_retnl( (LONG) hbmWin );
}
#pragma ENDDUMP
To:
...
CloseHandle( hBmF );
hb_xfree( lpbmi );
}
hb_retnl( (LONG) hbmWin ); // RELOCATED
DeleteObject(hbmWin); // ADDED
DeleteObject( hdcMem ); // MODIFIED
ReleaseDC( hWnd, hdcWin );
}
#pragma ENDDUMP
It solved the problem I was facing.
Best regards!
---
Claudio Voskian
Buenos Aires - Argentina
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 296 |
Nodes: | 16 (3 / 13) |
Uptime: | 51:35:20 |
Calls: | 6,650 |
Calls today: | 2 |
Files: | 12,200 |
Messages: | 5,330,306 |