下面本人近来做一个框选截图的程序,主要资料参考网上的文档,再自己整理一下.可以实现屏幕截图和保存为bmp文档.如有不当之处,还请告知.^^ 以下为主要代码:
CBitmap bm; //定义bitmap
//消息循环
LRESULT ImgCaptureDlg::img_capture_dialog_proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
SendMessage( GetDlgItem(hDlg, IDC_MSG_TOSHOW), WM_SETTEXT, 0,(LPARAM) "Plase click button /"Capture/" to begin ..." );//初始化提示信息
break;
}
case WM_CLOSE:
bm.Detach();
mouse.clear_event();
hide();
return true;
case WM_LBUTTONDOWN:
{
if(b_isbegin)//鼠标左键按下开始画框
{
SetTimer(dialog_hwnd,1,100,NULL);
GetCursorPos(&oldpt);
b_isdraw=true;
}
break;
}
case WM_MOUSEMOVE://移动时
{
GetCursorPos(&temppt);
if(b_isbegin && b_isdraw)
DrawRact(oldpt,temppt);
break;
}
case WM_RBUTTONDOWN://鼠标右键按下取消捕捉
{
if(b_isbegin)
{
b_isbegin=false;
ReleaseCapture();
SendMessage( GetDlgItem(hDlg, IDC_MSG_TOSHOW), WM_SETTEXT, 0,
(LPARAM) "User Cancle!/r/nPlase click button /"Capture/" to begin ..." );
SendMessage( hwnd_toolbar, TB_ENABLEBUTTON, ID_QUECKCAPTURE, MAKELONG (1, 0));
}
}
case WM_LBUTTONUP://当鼠标左键松开时完成捕捉
{
if(b_isbegin)
{
KillTimer(dialog_hwnd,1);
GetCursorPos(&newpt);
b_isdraw=false;
b_isbegin=false;
ReleaseCapture();
CapturetoClipboard();
InvalidateRect(dialog_hwnd,NULL,false);
SendMessage( GetDlgItem(hDlg, IDC_MSG_TOSHOW), WM_SETTEXT, 0,
(LPARAM) "Complete!/r/nyou can paste or save as a bitmap!" );
SendMessage( hwnd_toolbar, TB_ENABLEBUTTON, ID_QUECKCAPTURE, MAKELONG (1, 0));
}
break;
}
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_BEGIN_CAPTURE://开始捕捉的按扭id
{
SetCapture(dialog_hwnd);
b_isbegin=true;
SendMessage( GetDlgItem(hDlg, IDC_MSG_TOSHOW), WM_SETTEXT, 0,
(LPARAM) "Plase use mouse to select a RECT. /r/nStart: mouse down ;/r/nEnd : mouse up./r/nClick Right button to cancle." );
SendMessage( hwnd_toolbar, TB_ENABLEBUTTON, ID_QUECKCAPTURE, MAKELONG (0, 0));
break;
}
case ID_SAVE_FILE://保存为bmp的按扭id
{
CString path;
char szFilter[]="Bitmap Files(*.bmp)|*.bmp|All Files(*.*)|*.*|";
CFileDialog filedlg(FALSE,"BMP","ScreenShot01.bmp",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);
if(IDOK==filedlg.DoModal())
{
path=filedlg.GetPathName();
}
char* newpath=path.GetBuffer(path.GetLength()+1);
SaveBitmapToFile((HBITMAP)bm.m_hObject,newpath);
DeleteObject((HGDIOBJ)bm.m_hObject);
break;
}
default:
break;
}
break;
case WM_TIMER://定时器
{
HDC hdc;
hdc=GetDC(NULL);//get the screen
SetROP2(hdc,R2_XORPEN);
SelectObject(hdc,GetStockObject(NULL_BRUSH));
SelectObject(hdc,GetStockObject(WHITE_PEN));
Rectangle(hdc,oldpt.x,oldpt.y,temppt.x,temppt.y);
ReleaseDC(NULL,hdc);
break;
}
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;
hdc=BeginPaint(dialog_hwnd,&ps);
SetBkMode(hdc,OPAQUE);
SetBkColor(hdc,0x00c0c0c0);
EndPaint(dialog_hwnd,&ps);
hdc=GetDC(NULL);//get the screen
SetROP2(hdc,R2_XORPEN);
SelectObject(hdc,GetStockObject(NULL_BRUSH));
SelectObject(hdc,GetStockObject(WHITE_PEN));
Rectangle(hdc,oldpt.x,oldpt.y,temppt.x,temppt.y);
ReleaseDC(NULL,hdc);
break;
}
case WM_NOTIFY:
break;
default:
break;
}
return false;
}
// ------- end of static function ImgCaptureDlg::img_capture_dialog_proc ------- //
//截图函数
// ------- Begin of static function ImgCaptureDlg::ImgCaptureDlg::CapturetoClipboard ------- //
BOOL ImgCaptureDlg::CapturetoClipboard()
{
HWND m_wndh = ::GetDesktopWindow();
CWnd* m_wnd=(CWnd *)CWnd::FromHandle (m_wndh);
CDC *dc;
dc = new CWindowDC(m_wnd);
CDC memDC;
memDC.CreateCompatibleDC(dc);
CRect r;
m_wnd->GetWindowRect(&r);
CSize sz(abs(newpt.x-oldpt.x),abs(newpt.y-oldpt.y));
bm.CreateCompatibleBitmap(dc, sz.cx, sz.cy);
CBitmap * oldbm = memDC.SelectObject(&bm);
memDC.BitBlt( 0, 0, sz.cx, sz.cy, dc, GetMin(oldpt.x,newpt.x), GetMin(oldpt.y,newpt.y), SRCCOPY);
//getmin为取两个数中的小值
m_wnd->OpenClipboard();
::EmptyClipboard();
::SetClipboardData(CF_BITMAP, bm.m_hObject);
CloseClipboard();
memDC.SelectObject(oldbm);
delete dc;
return true;
}
// ------- end of static function ImgCaptureDlg::ImgCaptureDlg::CapturetoClipboard ------- //
//画框
// ------- Begin of static function ImgCaptureDlg::ImgCaptureDlg::DrawRact ------- //
void ImgCaptureDlg::DrawRact(POINT pt1, POINT pt2)
{
HDC hdc;
hdc=GetDC(NULL);//get the screen
SetROP2(hdc,R2_XORPEN);
SelectObject(hdc,GetStockObject(NULL_BRUSH));
SelectObject(hdc,GetStockObject(WHITE_PEN));
Rectangle(hdc,pt1.x,pt1.y,pt2.x,pt2.y);
ReleaseDC(NULL,hdc);
InvalidateRect(dialog_hwnd,NULL,true);
}
// ------- end of static function ImgCaptureDlg::ImgCaptureDlg::DrawRact ------- //
//保存剪贴板的图形到文件
// ------- Begin of static function ImgCaptureDlg::SaveBitmapToFile ------- //
BOOL ImgCaptureDlg::SaveBitmapToFile(HBITMAP hBitmap, char* lpFileName)
{
HDC hDC;
//当前分辨率下每象素所占字节数
int iBits;
//位图中每象素所占字节数
WORD wBitCount;
//定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;
//位图属性结构
BITMAP Bitmap;
//位图文件头结构
BITMAPFILEHEADER bmfHdr;
//位图信息头结构
BITMAPINFOHEADER bi;
//指向位图信息头结构
LPBITMAPINFOHEADER lpbi;
//定义文件,分配内存句柄,调色板句柄
HANDLE fh, hDib, hPal,hOldPal=NULL;
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1) wBitCount = 1;
else if (iBits <= 4) wBitCount = 4;
else if (iBits <= 8) wBitCount = 8;
else wBitCount = 24;
GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrImportant = 0;
bi.biClrUsed = 0;
dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
//为位图内容分配内存
hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
// 处理调色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC = ::GetDC(NULL);
hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
+dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
}
//创建位图文件
fh = CreateFile(lpFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE) return FALSE;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
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;
// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);
return TRUE;
}
// ------- end of static function ImgCaptureDlg::SaveBitmapToFile ------- //