// CutScreenDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "CutScreen.h"
#include "CutScreenDlg.h"
#include ".\cutscreendlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CCutScreenDlg 对话框
CCutScreenDlg::CCutScreenDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCutScreenDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCutScreenDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CCutScreenDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_CUTSCREEN, OnGDICutscreen)
ON_BN_CLICKED(IDC_CUTSCREEN2, OnDXCutscreen)
END_MESSAGE_MAP()
// CCutScreenDlg 消息处理程序
BOOL CCutScreenDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CCutScreenDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(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
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CCutScreenDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void Screen(char filename[])
{
CDC *pDC;//屏幕DC
pDC = CDC::FromHandle(GetDC(NULL));//获取当前整个屏幕DC
int Width = pDC->GetDeviceCaps(HORZRES);
int Height = pDC->GetDeviceCaps(VERTRES);
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
//以下代码保存memDC中的位图到文件
BITMAP bmp;
memBitmap.GetBitmap(&bmp);//获得位图信息
FILE *fp = fopen(filename, "w+b");
BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//图像数据大小
bih.biWidth = bmp.bmWidth;//宽度
BITMAPFILEHEADER bfh = {0};//位图文件头
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量
bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;//文件总的大小
bfh.bfType = (WORD)0x4d42;
fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头
fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头
byte * p = new byte[bmp.bmWidthBytes * bmp.bmHeight];//申请内存保存位图数据
GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject, 0, Height, p,
(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据
fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);//写入位图数据
delete [] p;
fclose(fp);
memDC.SelectObject(oldmemBitmap);
}
void CCutScreenDlg::OnGDICutscreen()
{
char path[MAX_PATH];
DWORD len = GetModuleFileName(AfxGetInstanceHandle(), path, MAX_PATH);
if (len)
{
int end = len - 1;
while (*(path + end) != '\\')
--end;
strcpy(path + end, "\\GDIScreen.bmp");
}
else
return;
// GDI方式截屏
Screen(path);
}
void CCutScreenDlg::OnDXCutscreen()
{
char path[MAX_PATH];
DWORD len = GetModuleFileName(AfxGetInstanceHandle(), path, MAX_PATH);
if (len)
{
int end = len - 1;
while (*(path + end) != '\\')
--end;
strcpy(path + end, "\\DXScreen.bmp");
}
else
return;
// DirectX截屏
if (!DX_Init())
return;
CDC *pDC;//屏幕DC
pDC = CDC::FromHandle(::GetDC(NULL));//获取当前整个屏幕DC
int Width = pDC->GetDeviceCaps(HORZRES);
int Height = pDC->GetDeviceCaps(VERTRES);
RECT rc;
rc.left = rc.top = 0;
rc.right = Width;
rc.bottom = Height;
UINT buflen = Width * Height * 4;
BYTE* buf = new BYTE[buflen];
CaptureScreen(rc, buf, buflen);
BITMAP bmp;
bmp.bmWidth = Width;
bmp.bmHeight = Height;
bmp.bmBitsPixel = 4;
SaveBitmapToFile(&bmp, path, (char*)buf);
delete[] buf;
}
LPDIRECTDRAW lpDD = NULL;
LPDIRECTDRAWSURFACE lpDDSPrime = NULL;
LPDIRECTDRAWSURFACE lpDDSBack = NULL;
LPDIRECTDRAWSURFACE lpDDSGdi = NULL;
LPDIRECTDRAWSURFACE lpSurf = NULL;
DDSURFACEDESC DDSdesc;
BOOL m_b24=TRUE;
//rfbServerInitMsg m_scrinfo;
RECT m_bmrect;
struct _BMInfo {
BITMAPINFO bmi;
BOOL truecolour;
RGBQUAD cmap[256];
} m_bminfo; // 用来保存位图信息的结构
// DirectX初始化。返回当前表面获取一张屏幕位图的存储空间大小
int DX_Init()
{
HRESULT hr;
// 初始化directX
hr = DirectDrawCreate(0, &lpDD, 0);
if (FAILED(hr))
return FALSE;
hr = lpDD->SetCooperativeLevel(NULL, 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))
{
m_bmrect.left = m_bmrect.top = 0;
m_bmrect.right = DDSdesc.dwWidth;
m_bmrect.bottom = DDSdesc.dwHeight;
}
else
return FALSE;
m_bminfo.bmi.bmiHeader.biCompression = BI_RGB;//BI_BITFIELDS;
m_bminfo.bmi.bmiHeader.biBitCount = 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.bottom - m_bmrect.top;
DDSdesc.dwWidth = m_bmrect.right - m_bmrect.left;
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(RECT &rect, BYTE *scrBuff, UINT scrBuffSize)
{
HRESULT hr=0;
hr = lpDDSBack->BltFast(rect.left,rect.top,lpDDSPrime,&rect,DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT);
if (FAILED(hr))
return FALSE;
DDSURFACEDESC surfdesc;
ZeroMemory(&surfdesc, sizeof(surfdesc));
surfdesc.dwSize = sizeof(surfdesc);
hr
- 1
- 2
- 3
- 4
- 5
前往页