Drectx 3D窗口后台截图

  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 }

 

转载于:https://www.cnblogs.com/MaxWoods/p/3396198.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值