www.gusucode.com > VC++屏幕捕获(抓屏、截图)程序-源码程序 > VC++屏幕捕获(抓屏、截图)程序-源码程序\code\Page1.cpp

    // Page1.cpp : implementation file
// Download by http://www.NewXing.com

#include "stdafx.h"
#include "Page.h"
#include "Page1.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CPage1 property page

IMPLEMENT_DYNCREATE(CPage1, CPropertyPage)

CPage1::CPage1() : CPropertyPage(CPage1::IDD)
{
	//{{AFX_DATA_INIT(CPage1)
	m_bOpenMspaint = (::GetPrivateProfileInt("HowTo","bOpenMspaint",1,".\\Settings.ini")==0? false:true);

	m_bCopyToClip = (::GetPrivateProfileInt("HowTo","bCopyToClip",1,".\\Settings.ini")==0? false:true);

	m_strFilePath="c:\\1.bmp";
	m_bSaveToFile = (::GetPrivateProfileInt("HowTo","bSaveToFile",1,".\\Settings.ini")==0? false:true);




	//}}AFX_DATA_INIT
		m_bIsCapturing=false;

}

CPage1::~CPage1()
{
}

void CPage1::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPage1)
	DDX_Control(pDX, IDC_AREA, m_area);
	DDX_Check(pDX, IDC_CHECK1_OPENMSPAINT, m_bOpenMspaint);
	DDX_Check(pDX, IDC_CHECK2_COPYTOCLIP, m_bCopyToClip);
	DDX_Check(pDX, IDC_CHECK3_SAVETOFILE, m_bSaveToFile);
	DDX_Text(pDX, IDC_EDIT2, m_strFilePath);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CPage1, CPropertyPage)
	//{{AFX_MSG_MAP(CPage1)
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_BN_CLICKED(IDC_CHECK1_OPENMSPAINT, OnCheck1Openmspaint)
	ON_BN_CLICKED(IDC_CHECK2_COPYTOCLIP, OnCheck2Copytoclip)
	ON_BN_CLICKED(IDC_CHECK3_SAVETOFILE, OnCheck3Savetofile)
	ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
	ON_WM_LBUTTONDBLCLK()
	ON_BN_CLICKED(IDC_CATCH_FULL, OnCatchFull)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPage1 message handlers

void CPage1::OnLButtonDown(UINT nFlags, CPoint point) 
{

	CWnd* pWnd = ChildWindowFromPoint(point);  //该函数确定属于父窗口的哪一个子窗口(如果存在的话)包含着指定的点
	if (pWnd && pWnd->GetSafeHwnd() == m_area.GetSafeHwnd())
	{
		SetCapture();	
		SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR));  	
		m_area.SetIcon(AfxGetApp()->LoadIcon(IDI_ICON4));			
		m_bIsCapturing = TRUE;
	}
	

   AfxGetMainWnd()->SendMessage(WM_NCLBUTTONDOWN,HTCAPTION,0);	

	CPropertyPage::OnLButtonDown(nFlags, point);
}

void CPage1::OnMouseMove(UINT nFlags, CPoint point) 
{

	if(m_bIsCapturing)    //如果用户将鼠标左键按住不放,则开始抓取图片 
	{ 
		AfxGetMainWnd()->ShowWindow(SW_HIDE);
		SetCapture();
		
		ClientToScreen(&point); 
		m_hwndCapture=(HWND)::WindowFromPoint(point);    	//获得鼠标所在处的窗口句柄 	
		::GetWindowRect(m_hwndCapture,&m_rectCapture); //得到鼠标所在处的窗口的区域 
		
		/*-------------------------------------------------*/	 
		m_GetWinInfo.GetWindowFromCursorInfo();
		/*-------------------------------------------------*/	 
 
	}
	
	CPropertyPage::OnMouseMove(nFlags, point);
}

void CPage1::OnLButtonUp(UINT nFlags, CPoint point) 
{
	/*-------------------------------------------------*/
	m_GetWinInfo.EraseLastWindow();		
	/*-------------------------------------------------*/	

	if(this->m_bSaveToFile)
		this->WriteBmpToFile(this->GethBitmap());
	
	if(this->m_bCopyToClip)
		this->CopyBmpToClipBoard(this->GethBitmap());

	if(this->m_bOpenMspaint)
		::ShellExecute(NULL,"open","mspaint.exe",this->m_strFilePath,NULL,SW_SHOWNORMAL);

	this->StopCapture();
	AfxGetMainWnd()->ShowWindow(SW_NORMAL);     //恢复窗口显示模式 
	   
	
	CPropertyPage::OnLButtonUp(nFlags, point);
}

void CPage1::StopCapture()
{
	if (m_bIsCapturing)
	{
		ReleaseCapture();
		m_bIsCapturing = FALSE;		
		SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
		m_area.SetIcon(AfxGetApp()->LoadIcon(IDI_ICON5));
	}
}



void CPage1::WriteBmpToFile(HBITMAP hBitmap)
{
    HDC hDC =::CreateDC("DISPLAY",NULL,NULL,NULL); 
    int iBits = ::GetDeviceCaps(hDC, BITSPIXEL) * ::GetDeviceCaps(hDC, PLANES);//当前分辨率下每个像素所占字节数  
    ::DeleteDC(hDC);

    WORD   wBitCount;   //位图中每个像素所占字节数    
    if (iBits <= 1)
		wBitCount = 1;
    else if (iBits <= 4)
		wBitCount = 4;
    else if (iBits <= 8)
		wBitCount = 8;
    else if (iBits <= 24)
		wBitCount = 24;
    else
		wBitCount = iBits;
		    
	DWORD   dwPaletteSize=0;	//调色板大小, 位图中像素字节大小 
    if (wBitCount <= 8)		
		dwPaletteSize = (1 << wBitCount) *	sizeof(RGBQUAD);	
	

	BITMAP  bm;        //位图属性结构
    ::GetObject(hBitmap, sizeof(bm), (LPSTR)&bm);  

    
	BITMAPINFOHEADER   bi;       //位图信息头结构     
	bi.biSize            = sizeof(BITMAPINFOHEADER);  
    bi.biWidth           = bm.bmWidth;
    bi.biHeight          = bm.bmHeight;
    bi.biPlanes          = 1;
    bi.biBitCount        = wBitCount;
    bi.biCompression     = BI_RGB; //BI_RGB表示位图没有压缩
    bi.biSizeImage       = 0;
    bi.biXPelsPerMeter   = 0;
    bi.biYPelsPerMeter   = 0;
    bi.biClrUsed         = 0;
    bi.biClrImportant    = 0;
	
    DWORD dwBmBitsSize = ((bm.bmWidth * wBitCount+31)/32) * 4 * bm.bmHeight;    
    HANDLE hDib  = ::GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));  //为位图内容分配内存
    LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
    *lpbi = bi;
	
    HANDLE hPal = ::GetStockObject(DEFAULT_PALETTE);  // 处理调色板 
	HANDLE  hOldPal=NULL; 
    if (hPal)
    {
		hDC = ::GetDC(NULL);
		hOldPal = SelectPalette(hDC,(HPALETTE)hPal, FALSE);
		RealizePalette(hDC);
    }
    ::GetDIBits(hDC, hBitmap, 0, (UINT) bm.bmHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,(BITMAPINFO*)lpbi,DIB_RGB_COLORS);// 获取该调色板下新的像素值
    if (hOldPal)//恢复调色板
    {
		SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
		RealizePalette(hDC);
		::ReleaseDC(NULL, hDC);
    }	
   
	BITMAPFILEHEADER   bmfHdr; //位图文件头结构     
	bmfHdr.bfType = 0x4D42;  // "BM"  	// 设置位图文件头
	DWORD dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;  
	bmfHdr.bfSize = dwDIBSize;
	bmfHdr.bfReserved1 = 0;
	bmfHdr.bfReserved2 = 0;
	bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
	
	HANDLE hFile = CreateFile(m_strFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);//创建位图文件   
	DWORD dwWritten;
	WriteFile(hFile, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);	// 写入位图文件头
	WriteFile(hFile, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);// 写入位图文件其余内容
	
	GlobalUnlock(hDib);   //清除   
	GlobalFree(hDib);
	CloseHandle(hFile); 	
	
}

void CPage1::CopyBmpToClipBoard(HBITMAP hBitmap)
{
	OpenClipboard() ; 	//打开剪贴板,并将位图拷到剪贴板上 
	EmptyClipboard(); 
	SetClipboardData(CF_BITMAP, hBitmap);
	CloseClipboard(); 	//关闭剪贴板  


}

void CPage1::OnCheck1Openmspaint() 
{

	UpdateData();
	::WritePrivateProfileString("HowTo","bOpenMspaint",this->m_bOpenMspaint? "1":"0",".\\Settings.ini");
	
}

void CPage1::OnCheck2Copytoclip() 
{
	UpdateData();
	::WritePrivateProfileString("HowTo","bCopyToClip",this->m_bCopyToClip? "1":"0",".\\Settings.ini");
}

void CPage1::OnCheck3Savetofile() 
{
	UpdateData();
	if(this->m_bSaveToFile)
	{
		GetDlgItem(IDC_EDIT2)->EnableWindow(true);
		GetDlgItem(IDC_BROWSE)->EnableWindow(true);
	}
	else
	{
		GetDlgItem(IDC_EDIT2)->EnableWindow(false);
		GetDlgItem(IDC_BROWSE)->EnableWindow(false);
	}

	::WritePrivateProfileString("HowTo","bSaveToFile",m_bSaveToFile? "1":"0",".\\Settings.ini");
}

HBITMAP CPage1::GethBitmap()
{
	int nWidth=m_rectCapture.Width(); 
	int nHeight=m_rectCapture.Height(); //得到鼠标所在处的窗口的区域宽、高  
	
	HDC hdcScreen, hMemDC;  
	HBITMAP hBitmap, hOldBitmap;  
	
	hdcScreen = CreateDC(						//建立一个屏幕设备环境句柄 
						"DISPLAY",			 //用vbNullString传递null值给该参数,除非:1、用DISPLAY,是获取整个屏幕的设备场景;2、用WINSPOOL,则是访问打印驱动
						NULL,				 //所用专门设备的名称。该名由打印管理器分配显示
						NULL,				//用vbNullString传递null值给该参数
						NULL				 //DEVMODE,这个结构保存初始值。用CreateDCBynum传递0(NULL)值则适用默认设置
						); 			
	hMemDC = CreateCompatibleDC(hdcScreen);   //建立一个与屏幕设备环境句柄兼容、与鼠标所在处的窗口的区域等大的位图 
	hBitmap = CreateCompatibleBitmap(hdcScreen, nWidth, nHeight); 
	hOldBitmap =(HBITMAP)SelectObject(hMemDC, hBitmap);   	//把新位图选到内存设备描述表中 
	BitBlt(hMemDC, 0, 0, nWidth, nHeight, hdcScreen,m_rectCapture.left,m_rectCapture.top,SRCCOPY); 	// 把屏幕设备描述表拷贝到内存设备描述表中 
	hBitmap =(HBITMAP)SelectObject(hMemDC, hOldBitmap);   	//取回鼠标所在处的窗口屏幕位图的句柄 
	DeleteDC(hdcScreen); 
	DeleteDC(hMemDC);    //不再需要时,该设备场景可用DeleteDC函数删除。删除前,其所有对象应回复初始状态。
	
	return hBitmap;
}

void CPage1::OnBrowse() 
{
	
	CFileDialog fileDlg(false,NULL,NULL,OFN_ALLOWMULTISELECT | OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_LONGNAMES,"所有文件(*.*)|*.*",this);
	if(fileDlg.DoModal()==IDOK)
	{
		this->m_strFilePath=fileDlg.GetPathName()+".bmp";
		UpdateData(false);		
	}




}

BOOL CPage1::OnInitDialog() 
{
	CPropertyPage::OnInitDialog();
	

	this->OnCheck3Savetofile();

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}







void CPage1::OnLButtonDblClk(UINT nFlags, CPoint point) 
{

	
	CPropertyPage::OnLButtonDblClk(nFlags, point);
}

void CPage1::OnCatchFull() 
{

	AfxGetMainWnd()->ShowWindow(SW_HIDE);

	HWND hWnd = ::GetDesktopWindow();//获得屏幕的HWND.
	HDC hScreenDC = ::GetDC(hWnd);   //获得屏幕的HDC.
	HDC MemDC = ::CreateCompatibleDC(hScreenDC);
	RECT rect; 
	::GetWindowRect(hWnd,&rect);
	SIZE screensize;
	screensize.cx=rect.right-rect.left;
	screensize.cy=rect.bottom-rect.top;
	HBITMAP hBitmap = ::CreateCompatibleBitmap(hScreenDC,screensize.cx,screensize.cy);
	HGDIOBJ hOldBMP = ::SelectObject(MemDC,hBitmap);
	::BitBlt(MemDC,0,0,screensize.cx,screensize.cy,hScreenDC,rect.left,rect.top,SRCCOPY);
	::SelectObject(MemDC,hOldBMP);
	::DeleteObject(MemDC);
	::ReleaseDC(hWnd,hScreenDC);


	if(this->m_bSaveToFile)
		this->WriteBmpToFile(hBitmap);
	
	if(this->m_bCopyToClip)
		this->CopyBmpToClipBoard(hBitmap);

	if(this->m_bOpenMspaint)
		::ShellExecute(NULL,"open","mspaint.exe",this->m_strFilePath,NULL,SW_SHOWNORMAL);

	AfxGetMainWnd()->ShowWindow(SW_NORMAL);     //恢复窗口显示模式 


	
}