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 }