WinCE下截屏的方法有很多种,这里介绍一种利用GAPI实现的方法。GAPI是Game API的缩写,它提供了一系列函数,可以直接对屏幕缓冲区进行读/写访问。虽然现在逐渐被DirectX Mobile取代,但自从2000年首次应用在PPC上后,几乎所有的移动设备上都能看见它。GAPI主要应用于游戏开发,但也不仅限于此。下面就介绍一种在WM下如何利用GAPI快速截取屏幕的方法。
1
struct
{
2 BITMAPINFOHEADER bmih;
3 RGBQUAD rgq[ 256 ];
4 } bmi;
5 BYTE * pLCDBuffer = NULL;
6 BITMAPFILEHEADER bmfHdr;
7 HANDLE hFile;
8 DWORD dwWritten;
9 DWORD dwFrameBufferSize;
10
11 GXOpenDisplay(NULL, NULL);
12 g_DisplayProperties = GXGetDisplayProperties();
13 pLCDBuffer = (PBYTE)GXBeginDraw();
14 dwFrameBufferSize = g_DisplayProperties.cxWidth * g_DisplayProperties.cyHeight * (g_DisplayProperties.cBPP >> 3 );
15
16 ZeroMemory( & bmi, sizeof (bmi));
17 bmi.bmih.biSize = sizeof (BITMAPINFOHEADER);
18 bmi.bmih.biWidth = g_DisplayProperties.cxWidth;
19 bmi.bmih.biHeight = - g_DisplayProperties.cyHeight;
20 bmi.bmih.biPlanes = 1 ;
21 bmi.bmih.biBitCount = (WORD)g_DisplayProperties.cBPP;
22 bmi.bmih.biCompression = BI_BITFIELDS;
23 * (DWORD * )( & bmi.rgq[ 0 ]) = 0xF800 ;
24 * (DWORD * )( & bmi.rgq[ 1 ]) = 0x07E0 ;
25 * (DWORD * )( & bmi.rgq[ 2 ]) = 0x001F ;
26
27 ZeroMemory( & bmfHdr, sizeof (BITMAPFILEHEADER));
28 bmfHdr.bfType = 0x4d42 ;
29 bmfHdr.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + sizeof (DWORD) * 3 ;
30 bmfHdr.bfSize = bmfHdr.bfOffBits + dwFrameBufferSize;
31
32 hFile = CreateFile(_T( " \\1.bmp " ), GENERIC_WRITE, 0 , NULL, CREATE_ALWAYS,NULL, NULL);
33 if (INVALID_HANDLE_VALUE != hFile)
34 {
35 WriteFile(hFile, (LPSTR) & bmfHdr, sizeof (BITMAPFILEHEADER), & dwWritten, NULL);
36 WriteFile(hFile, (LPSTR) & (bmi.bmih), sizeof (BITMAPINFOHEADER) + sizeof (DWORD) * 3 , & dwWritten, NULL);
37 WriteFile(hFile, (LPSTR)pLCDBuffer, dwFrameBufferSize, & dwWritten, NULL);
38 CloseHandle(hFile);
39 }
40
41 GXEndDraw();
42 GXCloseDisplay();
2 BITMAPINFOHEADER bmih;
3 RGBQUAD rgq[ 256 ];
4 } bmi;
5 BYTE * pLCDBuffer = NULL;
6 BITMAPFILEHEADER bmfHdr;
7 HANDLE hFile;
8 DWORD dwWritten;
9 DWORD dwFrameBufferSize;
10
11 GXOpenDisplay(NULL, NULL);
12 g_DisplayProperties = GXGetDisplayProperties();
13 pLCDBuffer = (PBYTE)GXBeginDraw();
14 dwFrameBufferSize = g_DisplayProperties.cxWidth * g_DisplayProperties.cyHeight * (g_DisplayProperties.cBPP >> 3 );
15
16 ZeroMemory( & bmi, sizeof (bmi));
17 bmi.bmih.biSize = sizeof (BITMAPINFOHEADER);
18 bmi.bmih.biWidth = g_DisplayProperties.cxWidth;
19 bmi.bmih.biHeight = - g_DisplayProperties.cyHeight;
20 bmi.bmih.biPlanes = 1 ;
21 bmi.bmih.biBitCount = (WORD)g_DisplayProperties.cBPP;
22 bmi.bmih.biCompression = BI_BITFIELDS;
23 * (DWORD * )( & bmi.rgq[ 0 ]) = 0xF800 ;
24 * (DWORD * )( & bmi.rgq[ 1 ]) = 0x07E0 ;
25 * (DWORD * )( & bmi.rgq[ 2 ]) = 0x001F ;
26
27 ZeroMemory( & bmfHdr, sizeof (BITMAPFILEHEADER));
28 bmfHdr.bfType = 0x4d42 ;
29 bmfHdr.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + sizeof (DWORD) * 3 ;
30 bmfHdr.bfSize = bmfHdr.bfOffBits + dwFrameBufferSize;
31
32 hFile = CreateFile(_T( " \\1.bmp " ), GENERIC_WRITE, 0 , NULL, CREATE_ALWAYS,NULL, NULL);
33 if (INVALID_HANDLE_VALUE != hFile)
34 {
35 WriteFile(hFile, (LPSTR) & bmfHdr, sizeof (BITMAPFILEHEADER), & dwWritten, NULL);
36 WriteFile(hFile, (LPSTR) & (bmi.bmih), sizeof (BITMAPINFOHEADER) + sizeof (DWORD) * 3 , & dwWritten, NULL);
37 WriteFile(hFile, (LPSTR)pLCDBuffer, dwFrameBufferSize, & dwWritten, NULL);
38 CloseHandle(hFile);
39 }
40
41 GXEndDraw();
42 GXCloseDisplay();