在开发D3D截图之前,必须安装DX9.0或以上。不然不能正常编译!
// LScreenDlg.cpp : 实现文件 // #include "stdafx.h" #include "LScreen.h" #include "LScreenDlg.h" #include "afxdialogex.h" #include#include #include #ifdef _DEBUG #define new DEBUG_NEW #endif // CLScreenDlg 对话框 #pragma comment(lib,"ddraw.lib") #pragma comment(lib,"dxguid.lib") #pragma comment(lib,"d3dx9d.lib") #pragma comment(lib,"d3d9.lib") LPDIRECTDRAW lpDD = NULL; LPDIRECTDRAWSURFACE lpDDSPrime = NULL; LPDIRECTDRAWSURFACE lpDDSBack = NULL; LPDIRECTDRAWSURFACE lpDDSGdi = NULL; LPDIRECTDRAWSURFACE lpSurf = NULL; DDSURFACEDESC DDSdesc; BOOL m_b24=TRUE; //rfbServerInitMsg m_scrinfo; CRect m_bmrect; struct _BMInfo { BITMAPINFO bmi; BOOL truecolour; RGBQUAD cmap[256]; } m_bminfo; // 用来保存位图信息的结构 // DirectX初始化。返回当前表面获取一张屏幕位图的存储空间大小 int DX_Init(HWND hWnd) { HRESULT hr; // 初始化directX hr = DirectDrawCreate(0, &lpDD, 0); if (FAILED(hr)) return FALSE; hr = lpDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL); if (FAILED(hr)) return FALSE; ZeroMemory(&DDSdesc, sizeof(DDSdesc)); DDSdesc.dwSize = sizeof(DDSdesc); DDSdesc.dwFlags = DDSD_CAPS; DDSdesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; hr = lpDD->CreateSurface(&DDSdesc, &lpDDSPrime, 0); if (FAILED(hr)) return FALSE; hr = lpDD->GetGDISurface(&lpDDSGdi); if (FAILED(hr)) return FALSE; ZeroMemory(&DDSdesc, sizeof(DDSdesc)); DDSdesc.dwSize = sizeof(DDSdesc); DDSdesc.dwFlags = DDSD_ALL; hr = lpDDSPrime->GetSurfaceDesc(&DDSdesc); if (FAILED(hr)) return FALSE; // 初始化位图信息 if (!((DDSdesc.dwFlags & DDSD_WIDTH) && (DDSdesc.dwFlags & DDSD_HEIGHT))) return FALSE; m_bminfo.bmi.bmiHeader.biCompression = BI_RGB;//BI_BITFIELDS; m_bminfo.bmi.bmiHeader.biBitCount = (WORD)DDSdesc.ddpfPixelFormat.dwRGBBitCount; //m_bminfo.truecolour = DDSdesc.ddpfPixelFormat.dwFlags & DDPF_RGB; if(m_bminfo.bmi.bmiHeader.biBitCount > 8) m_bminfo.truecolour = TRUE; else m_bminfo.truecolour = FALSE; ZeroMemory(&DDSdesc, sizeof(DDSdesc)); DDSdesc.dwSize = sizeof(DDSdesc); DDSdesc.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; DDSdesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; DDSdesc.dwHeight = m_bmrect.Height(); DDSdesc.dwWidth = m_bmrect.Width(); hr = lpDD->CreateSurface(&DDSdesc, &lpDDSBack, 0); if (FAILED(hr)) return FALSE; switch (m_bminfo.bmi.bmiHeader.biBitCount) { case 32: case 24: // Update the bitmapinfo header m_b24 = TRUE; break; } m_bminfo.bmi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); m_bminfo.bmi.bmiHeader.biWidth = DDSdesc.dwWidth; m_bminfo.bmi.bmiHeader.biHeight = DDSdesc.dwHeight; m_bminfo.bmi.bmiHeader.biPlanes = 1; m_bminfo.bmi.bmiHeader.biCompression = BI_RGB; m_bminfo.bmi.bmiHeader.biSizeImage = abs((m_bminfo.bmi.bmiHeader.biWidth * m_bminfo.bmi.bmiHeader.biHeight * m_bminfo.bmi.bmiHeader.biBitCount)/ 8); m_bminfo.bmi.bmiHeader.biClrUsed = 0; m_bminfo.bmi.bmiHeader.biClrImportant = 0; return m_bminfo.bmi.bmiHeader.biSizeImage; } // 捕捉屏幕。rect: 区域。scrBuff: 输出缓冲。scrBuffSize: 缓冲区大小 BOOL CaptureScreen() { UINT buflen = m_bmrect.Width() * m_bmrect.Height() * 4; BYTE* buf = new BYTE[buflen]; HRESULT hr=0; CRect rt; rt.left = 0; rt.top = 0; rt.right = m_bmrect.Width(); rt.bottom = m_bmrect.Height(); hr = lpDDSBack->BltFast(rt.left,rt.top,lpDDSPrime,rt,DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT); if (FAILED(hr)) return FALSE; DDSURFACEDESC surfdesc; ZeroMemory(&surfdesc, sizeof(surfdesc)); surfdesc.dwSize = sizeof(surfdesc); hr = lpDDSBack->Lock(rt, &surfdesc, DDLOCK_READONLY | DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL); if (FAILED(hr)) return FALSE; memcpy(buf, surfdesc.lpSurface,m_bminfo.bmi.bmiHeader.biSizeImage); // unlock the primary surface lpDDSBack->Unlock(surfdesc.lpSurface); CBitmap bitmap; bitmap.CreateBitmap(rt.Width(),rt.Height(),1,32,buf); //复制到粘贴板 OpenClipboard(NULL); EmptyClipboard(); SetClipboardData(CF_BITMAP, bitmap); CloseClipboard(); delete buf; return TRUE; } CLScreenDlg::CLScreenDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CLScreenDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CLScreenDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CLScreenDlg, CDialogEx) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON1, &CLScreenDlg::OnBnClickedButton1) ON_BN_CLICKED(IDC_BUTTON2, &CLScreenDlg::OnBnClickedButton2) ON_WM_HOTKEY() ON_WM_DESTROY() END_MESSAGE_MAP() // CLScreenDlg 消息处理程序 BOOL CLScreenDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 RegisterHotKey(m_hWnd,1000,NULL,VK_F8); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CLScreenDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast (dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CLScreenDlg::OnQueryDragIcon() { return static_cast (m_hIcon); } BOOL ScreenShot(LPDIRECT3DDEVICE9 lpDevice, HWND hWnd, TCHAR* fileName) { HRESULT hr; // Get adapter display mode D3DDISPLAYMODE mode; if (FAILED(hr = lpDevice->GetDisplayMode(0, &mode))) return hr; // Create the surface to hold the screen image data LPDIRECT3DSURFACE9 surf; if (FAILED(hr = lpDevice->CreateOffscreenPlainSurface(mode.Width, mode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL))) //注意第四个参数不能是D3DPOOL_DEFAULT { return hr; } // Get the screen data if (FAILED(hr = lpDevice->GetFrontBufferData(0, surf))) { surf->Release() ; return hr ; } // area to capture RECT *rect = NULL ; WINDOWINFO windowInfo ; windowInfo.cbSize = sizeof(WINDOWINFO) ; if(hWnd) // capture window { GetWindowInfo(hWnd, &windowInfo) ; rect = &windowInfo.rcWindow ; } // Save the screen date to file hr = D3DXSaveSurfaceToFile(fileName, D3DXIFF_BMP, surf, NULL, NULL); surf->Release() ; return hr ; } void CLScreenDlg::OnBnClickedButton1()//GDI { // TODO: 在此添加控件通知处理程序代码 HWND hWnd = (HWND)0x00090D64; CDC *pDC;//屏幕DC pDC = CDC::FromHandle(::GetDC(hWnd));//获取目标句柄DC CRect rt; ::GetWindowRect(hWnd,rt); int Width = rt.Width(); int Height = rt.Height(); CDC memDC;//内存DC memDC.CreateCompatibleDC(pDC); CBitmap memBitmap, *oldmemBitmap;//建立和屏幕兼容的bitmap memBitmap.CreateCompatibleBitmap(pDC, Width, Height); oldmemBitmap = memDC.SelectObject(&memBitmap);//将memBitmap选入内存DC memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY);//复制屏幕图像到内存DC //复制到粘贴板 OpenClipboard(); EmptyClipboard(); SetClipboardData(CF_BITMAP, memBitmap); CloseClipboard(); MessageBox("操作完成"); } void testDX(HWND hWnd) { LPDIRECT3D9 lpD3D = Direct3DCreate9(D3D_SDK_VERSION); LPDIRECT3DDEVICE9 lpDevice = NULL; D3DPRESENT_PARAMETERS d3dpp = {0}; d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; HRESULT Return_CreateDevice = lpD3D->CreateDevice (D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &lpDevice); D3DDISPLAYMODE mode; HRESULT hr = lpDevice->GetDisplayMode(NULL, &mode); LPDIRECT3DSURFACE9 surf; hr = lpDevice->CreateOffscreenPlainSurface(mode.Width, mode.Height,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&surf,NULL); hr = lpDevice->GetFrontBufferData(0,surf); ScreenShot(lpDevice,hWnd,"C:\\1.bmp"); } void testDX2(HWND hWnd) { LPDIRECT3DDEVICE9 lpDevice = NULL; LPDIRECT3D9 lpD3D = Direct3DCreate9(D3D_SDK_VERSION); D3DPRESENT_PARAMETERS d3dpp = {0}; d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; HRESULT result = lpD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &lpDevice); D3DDISPLAYMODE displayMode; LPDIRECT3DSURFACE9 pd3dsFront = NULL; lpDevice->GetDisplayMode(0, &displayMode); lpDevice->CreateOffscreenPlainSurface( displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pd3dsFront, NULL); lpDevice->GetFrontBufferData(0, pd3dsFront); D3DXSaveSurfaceToFile("C:\\2.bmp", D3DXIFF_BMP, pd3dsFront, NULL, NULL); if(pd3dsFront) pd3dsFront->Release(); } void CLScreenDlg::OnBnClickedButton2()//DX { // TODO: 在此添加控件通知处理程序代码 // DirectX截屏 testDX2(t_hWnd); MessageBox("操作完成"); } void CLScreenDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CDialogEx::OnHotKey(nHotKeyId, nKey1, nKey2); if (nHotKeyId == 1000) { CPoint p; ::GetCursorPos(&p); t_hWnd = ::WindowFromPoint(p); if(t_hWnd != NULL) MessageBox("成功"); } } void CLScreenDlg::OnDestroy() { CDialogEx::OnDestroy(); // TODO: 在此处添加消息处理程序代码 UnregisterHotKey(m_hWnd,1000); }
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2299
- 用户1336
- 访客10619057
每日一句
You leave, or I go with you.
你留下,或者我跟你走。——《海角七号》
你留下,或者我跟你走。——《海角七号》
新会员