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();