1 //GDI与DX截屏API操作
2 LPDIRECTDRAW lpDD = NULL;
3 LPDIRECTDRAWSURFACE lpDDSPrime = NULL;
4 LPDIRECTDRAWSURFACE lpDDSBack = NULL;
5 LPDIRECTDRAWSURFACE lpDDSGdi = NULL;
6 LPDIRECTDRAWSURFACE lpSurf = NULL;
7
8 DDSURFACEDESC DDSdesc;
9 BOOL m_b24=TRUE;
10 //rfbServerInitMsg m_scrinfo;
11 RECT m_bmrect;
12
13 struct _BMInfo {
14 BITMAPINFO bmi ;
15 BOOL truecolour;
16 RGBQUAD cmap[256] ;
17 } m_bminfo; // 用来保存位图信息的结构
18
19 int DX_Init() {// DirectX初始化。返回当前表面获取一张屏幕位图的存储空间大小
20 HRESULT hr;
21
22 // 初始化directX
23 hr = DirectDrawCreate(0, &lpDD, 0);
24 if (FAILED(hr)) return FALSE;
25
26 hr = lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL);
27 if (FAILED(hr)) return FALSE;
28
29 ZeroMemory(&DDSdesc, sizeof(DDSdesc));
30 DDSdesc.dwSize = sizeof(DDSdesc);
31 DDSdesc.dwFlags = DDSD_CAPS;
32 DDSdesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
33 hr = lpDD->CreateSurface(&DDSdesc, &lpDDSPrime, 0);
34 if (FAILED(hr)) return FALSE;
35
36 hr = lpDD->GetGDISurface(&lpDDSGdi);
37 if (FAILED(hr)) return FALSE;
38
39 ZeroMemory(&DDSdesc, sizeof(DDSdesc));
40 DDSdesc.dwSize = sizeof(DDSdesc);
41 DDSdesc.dwFlags = DDSD_ALL;
42 hr = lpDDSPrime->GetSurfaceDesc(&DDSdesc);
43 if (FAILED(hr)) return FALSE;
44
45 // 初始化位图信息
46 if ((DDSdesc.dwFlags & DDSD_WIDTH) && (DDSdesc.dwFlags & DDSD_HEIGHT)) {
47 m_bmrect.left = m_bmrect.top = 0;
48 m_bmrect.right = DDSdesc.dwWidth;
49 m_bmrect.bottom = DDSdesc.dwHeight;
50 } else return FALSE;
51
52 m_bminfo.bmi.bmiHeader.biCompression = BI_RGB;//BI_BITFIELDS;
53 m_bminfo.bmi.bmiHeader.biBitCount = DDSdesc.ddpfPixelFormat.dwRGBBitCount;
54
55 // m_bminfo.truecolour = DDSdesc.ddpfPixelFormat.dwFlags & DDPF_RGB;
56 if (m_bminfo.bmi.bmiHeader.biBitCount > 8)
57 m_bminfo.truecolour = TRUE;
58 else
59 m_bminfo.truecolour = FALSE;
60
61 ZeroMemory(&DDSdesc, sizeof(DDSdesc));
62 DDSdesc.dwSize = sizeof(DDSdesc);
63 DDSdesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
64 DDSdesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
65 DDSdesc.dwHeight = m_bmrect.bottom - m_bmrect.top;
66 DDSdesc.dwWidth = m_bmrect.right - m_bmrect.left;
67 hr = lpDD->CreateSurface(&DDSdesc, &lpDDSBack, 0);
68 if (FAILED(hr)) return FALSE;
69 // hr = lpDDSPrime->QueryInterface( IID_IDirectDrawSurface3, (LPVOID *)&lpSurf);
70 // if (FAILED(hr)) return FALSE;
71
72 switch (m_bminfo.bmi.bmiHeader.biBitCount) {
73 case 32:
74 case 24:
75 // Update the bitmapinfo header
76 m_b24 = TRUE;
77 m_bminfo.bmi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
78 m_bminfo.bmi.bmiHeader.biWidth = 1024;
79 m_bminfo.bmi.bmiHeader.biHeight = 768;
80 m_bminfo.bmi.bmiHeader.biPlanes = 1;
81 // m_bminfo.bmi.bmiHeader.biBitCount = 24;
82 m_bminfo.bmi.bmiHeader.biCompression = BI_RGB;
83 m_bminfo.bmi.bmiHeader.biSizeImage = abs((m_bminfo.bmi.bmiHeader.biWidth * m_bminfo.bmi.bmiHeader.biHeight * m_bminfo.bmi.bmiHeader.biBitCount)/8);
84 m_bminfo.bmi.bmiHeader.biXPelsPerMeter = (1024*1000)/1024;
85 m_bminfo.bmi.bmiHeader.biYPelsPerMeter = (768*1000)/768;
86 m_bminfo.bmi.bmiHeader.biClrUsed = 0;
87 m_bminfo.bmi.bmiHeader.biClrImportant = 0;
88 break;
89 }
90
91 return m_bminfo.bmi.bmiHeader.biSizeImage;
92 }
93
94 BOOL CaptureScreen(RECT &rect, BYTE *scrBuff, UINT scrBuffSize) {// 捕捉屏幕。rect: 区域。scrBuff: 输出缓冲。scrBuffSize: 缓冲区大小
95 HRESULT hr=0;
96
97 hr = lpDDSBack->BltFast(rect.left,rect.top,lpDDSPrime,&rect,DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT);
98 if (FAILED(hr)) return FALSE;
99
100 DDSURFACEDESC surfdesc;
101 ZeroMemory(&surfdesc, sizeof(surfdesc));
102 surfdesc.dwSize = sizeof(surfdesc);
103
104 hr = lpDDSBack->Lock(&rect, &surfdesc, DDLOCK_READONLY | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR /*|DDLOCK_NOSYSLOCK*/, NULL);
105 // hr = lpDDSPrime->Lock(&rect, &surfdesc, DDLOCK_READONLY | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR /*|DDLOCK_NOSYSLOCK*/, NULL);
106 if (FAILED(hr)) return FALSE;
107
108 // copy the data into our buffer
109 BYTE * destbuffpos, * srcbuffpos;
110 // m_scrinfo.format.bitsPerPixel = 24;
111 srcbuffpos = (BYTE *) surfdesc.lpSurface;
112 destbuffpos = scrBuff;
113
114 memcpy( destbuffpos, srcbuffpos,m_bminfo.bmi.bmiHeader.biSizeImage);
115
116 // unlock the primary surface
117 // lpDDSPrime->Unlock(surfdesc.lpSurface);
118 lpDDSBack->Unlock(surfdesc.lpSurface);
119 return TRUE;
120 }
121
122 int SaveBitmapToFile(BITMAP *bitmap, LPSTR lpFileName,char *lpBuf) {
123 DWORD dwWritten;
124 BITMAPFILEHEADER bmfHdr;
125 BITMAPINFOHEADER bi;
126 HANDLE fh=NULL;
127 bi.biSize = sizeof(BITMAPINFOHEADER);
128 bi.biWidth= bitmap->bmWidth;
129 bi.biHeight = bitmap->bmHeight;
130 bi.biPlanes = 1;
131 bi.biBitCount = bitmap->bmBitsPixel*8;
132 bi.biCompression = BI_RGB;
133 bi.biSizeImage = 0;
134 bi.biXPelsPerMeter = 0;
135 bi.biYPelsPerMeter = 0;
136 bi.biClrUsed = 0;
137 bi.biClrImportant = 0;
138 fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
139 if (fh == INVALID_HANDLE_VALUE) return FALSE;
140 bmfHdr.bfType = 0x4D42; // "BM"
141 bmfHdr.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+bitmap->bmWidth*bitmap->bmHeight*bitmap->bmBitsPixel;
142 bmfHdr.bfReserved1 = 0;
143 bmfHdr.bfReserved2 = 0;
144 bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
145 WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
146 WriteFile(fh, (char *)&bi,sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
147 WriteFile(fh, (char *)lpBuf,bitmap->bmWidth*bitmap->bmHeight*bitmap->bmBitsPixel, &dwWritten, NULL);
148 FlushFileBuffers(fh);
149 CloseHandle(fh);
150 return true;
151 }
152
153 //(1)获取屏幕绘图设备
154 //(2)创建一个与屏幕绘图设备相兼容的内存绘图设备
155 //(2)在内存中创建一个与屏幕绘图设备相兼容的图像对象
156 //(3)将屏幕设备中的图像复制到内存绘图设备中
157 //(4)将内存图像保存到文件中
158 //相关函数:
159 //GetDIBits:按位的方式返回指定的BITMAP,并按指定的格式存储到内存中
160 int GetBitmapFromScreen(char *lpFileName) {
161 char *lpBuf;
162 HBITMAP hBitmap,hOld ;
163 HDC hDC,hcDC;
164 BITMAP bb;
165 BITMAPINFO b;
166 HANDLE hp,fh=NULL;
167 DWORD dwX,dwY;
168
169 dwX=GetSystemMetrics(SM_CXSCREEN);
170 dwY=GetSystemMetrics(SM_CYSCREEN);
171 hDC=GetDC(NULL);
172 hcDC=CreateCompatibleDC(hDC);
173 hBitmap=CreateCompatibleBitmap(hDC,dwX,dwY);
174 hOld=(HBITMAP)SelectObject(hcDC,hBitmap);
175 BitBlt(hcDC,0, 0,dwX,dwY, hDC, 0, 0, SRCCOPY);
176 bb.bmWidth=dwX;
177 bb.bmHeight =dwY;
178 bb.bmPlanes = 1;
179 bb.bmWidthBytes=bb.bmWidth*3;
180 bb.bmBitsPixel=3;
181 bb.bmType=0;
182 b.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
183 b.bmiHeader.biWidth =dwX;
184 b.bmiHeader.biHeight =dwY;
185 b.bmiHeader.biPlanes =1;
186 b.bmiHeader.biBitCount =3*8;
187 b.bmiHeader.biCompression =BI_RGB;
188 b.bmiHeader.biSizeImage =0;
189 b.bmiHeader.biXPelsPerMeter=0;
190 b.bmiHeader.biYPelsPerMeter=0;
191 b.bmiHeader.biClrUsed =0;
192 b.bmiHeader.biClrImportant =0;
193 b.bmiColors[0].rgbBlue =8;
194 b.bmiColors[0].rgbGreen =8;
195 b.bmiColors[0].rgbRed =8;
196 b.bmiColors[0].rgbReserved =0;
197 hp=GetProcessHeap();
198 lpBuf=(char *)HeapAlloc(hp,HEAP_ZERO_MEMORY,bb.bmHeight*bb.bmWidth*4);
199 GetDIBits(hcDC,hBitmap,0,dwY,lpBuf,&b,DIB_RGB_COLORS);
200 SaveBitmapToFile(&bb,lpFileName,lpBuf);
201 ReleaseDC(NULL,hDC);
202 DeleteDC(hcDC);
203 DeleteObject(hBitmap);
204 DeleteObject(hOld);
205 HeapFree(hp,0,lpBuf);
206 return true;
207 }