屏幕截图程序(WTL)

时间:2022-02-03 15:24:12

如果需要思路,请访问:http://hi.baidu.com/sumos/item/9aef19f4f02e0f5ac9f337bb

如果需要程序,请访问:http://download.csdn.net/detail/zhoujielunzhimi/4724327

如果需要源码,请看:

#pragma once
#include <atlimage.h>

class MainForm;

CBitmap bmp_srcreen; //用来保存全屏图片
MainForm *mf_ptr = NULL;

//截屏窗口
class ScreenForm : public CWindowImpl<ScreenForm>
{
public:
ScreenForm() : is_lbutton_down(false){}
protected:
BEGIN_MSG_MAP(ScreenForm)
MSG_WM_CREATE(OnCreate)
MESSAGE_HANDLER(WM_KEYDOWN,OnKeyDown)
MSG_WM_RBUTTONDOWN(OnRButtonDown)
MSG_WM_SETCURSOR(OnSetCursor)
MSG_WM_LBUTTONDOWN(OnLButtonDown)
MSG_WM_MOUSEMOVE(OnMouseMove)
MSG_WM_LBUTTONUP(OnLButtonUp)
MSG_WM_ERASEBKGND(OnEraseBkgnd)
MSG_WM_PAINT(OnPaint)
END_MSG_MAP()
protected:
int OnCreate(LPCREATESTRUCT)
{
CRect rc(0,0,0,0);
SetWindowPos(HWND_TOPMOST,&rc,SWP_NOMOVE|SWP_NOSIZE); //置顶
return 0;
}
LRESULT OnKeyDown(UINT,WPARAM wp,LPARAM,BOOL&)
{
if(wp == VK_LWIN || wp == VK_RWIN || VK_ESCAPE) //左WIN + 右WIN + ESC
OnRButtonDown(0,CPoint(0,0));
return 0;
}
void OnRButtonDown(UINT nFlags, CPoint point)
{
DestroyWindow();
((CWindowImpl*)mf_ptr)->ShowWindow(SW_SHOW);
}
BOOL OnSetCursor(CWindow wnd, UINT nHitTest, UINT message)
{
static CCursor cursor = AtlLoadCursor(IDC_CURSOR1); //载入光标资源:十 字形状
::SetCursor(cursor);
return TRUE;
}
void OnLButtonDown(UINT nFlags, CPoint point)
{
is_lbutton_down = true;
pt_old = point;
}
void OnMouseMove(UINT nFlags, CPoint point)
{
pt_end = point;
Invalidate();
}
void OnLButtonUp(UINT nFlags, CPoint point)
{
is_lbutton_down = false;
int ret = MessageBox("复制到剪贴板(OK)或保存为PNG图片(CANCEL)?","ASK",MB_OKCANCEL|MB_ICONQUESTION);

CDC dc1,dc2;
dc1.CreateCompatibleDC(NULL);
dc1.SelectBitmap(bmp_srcreen);
CRect rc(pt_old.x,pt_old.y,pt_end.x,pt_end.y);
dc2.CreateCompatibleDC(dc1);
CBitmap bmp; //dc1选择了全屏图片,dc2选择了截图区域
bmp.CreateCompatibleBitmap(dc1,rc.Width(),rc.Height());
dc2.SelectBitmap(bmp);
dc2.BitBlt(0,0,rc.Width(),rc.Height(),dc1,pt_old.x,pt_old.y,SRCCOPY);
if(ret == IDOK)
{
if(OpenClipboard()) //复制到剪贴板
{
::EmptyClipboard();
::SetClipboardData(CF_BITMAP,bmp);
::CloseClipboard();
}
}
else
{
CImage img;
img.Attach(bmp);
img.Save("catch.png"); //保存为png,因为保存为bmp图片太大了
img.Detach();
}

OnRButtonDown(0,CPoint(0,0));
}
BOOL OnEraseBkgnd(CDCHandle dc)
{
return TRUE;
}
void OnPaint(CDCHandle)
{
CPaintDC dc(m_hWnd);

CRect rc;
GetClientRect(&rc);

CMemoryDC mem(dc,rc); //WTL提供的双缓存,析构时自动绘制

CBrush br;
br.CreateSolidBrush(RGB(255,255,255));

mem.FillRect(&rc,br); //把窗口底色刷白

if(bmp_srcreen.IsNull())
return;

CDC dcMem;
dcMem.CreateCompatibleDC(mem);
dcMem.SelectBitmap(bmp_srcreen);

BLENDFUNCTION bf;
bf.AlphaFormat = 0;
bf.BlendFlags = 0;
bf.BlendOp = AC_SRC_OVER;
bf.SourceConstantAlpha = 100;
//绘制半透明的全屏图像,类似win7自带的截图软件
mem.AlphaBlend(0,0,rc.Width(),rc.Height(),dcMem,0,0,rc.Width(),rc.Height(),bf);

if(is_lbutton_down)
{
CRect rc_catch(pt_old.x,pt_old.y,pt_end.x,pt_end.y);
//不透明的显示选择区域图像
mem.BitBlt(pt_old.x,pt_old.y,rc_catch.Width(),rc_catch.Height(),dcMem,pt_old.x,pt_old.y,SRCCOPY);
mem.Draw3dRect(&rc_catch,RGB(255,0,0),RGB(0,0,255));
}
}
private:
CPoint pt_old;
CPoint pt_end;
bool is_lbutton_down;
};

//主窗口
class MainForm : public CWindowImpl<MainForm>
{
protected:
BEGIN_MSG_MAP(MainForm)
MSG_WM_CLOSE(OnClose)
MSG_WM_ERASEBKGND(OnEraseBkgnd)
COMMAND_CODE_HANDLER(BN_CLICKED,OnClick)
END_MSG_MAP()
protected:
void OnClose()
{
DestroyWindow();
::PostMessage(NULL,WM_QUIT,0,0);
}
BOOL OnEraseBkgnd(CDCHandle dc) //这不过是为主窗口加个背景图罢了
{
CRect rc;
GetClientRect(&rc);
CBitmap bk;
bk.LoadBitmap(IDB_BITMAP1);
CDC mem;
mem.CreateCompatibleDC(dc);
mem.SelectBitmap(bk);
BITMAP bkInf;
bk.GetBitmap(&bkInf);
dc.StretchBlt(0,0,rc.Width(),rc.Height(),mem,0,0,bkInf.bmWidth,bkInf.bmHeight,SRCCOPY);
return TRUE;
}
LRESULT OnClick(WORD,WORD id,HWND,BOOL&)
{
CRect rc;
switch(id)
{
case IDC_CREATE :
ShowWindow(SW_HIDE);
Sleep(300); //需要等待一下,否则会把主窗口图像也捕捉下来
{
//捕捉屏幕
CRect rcDesk;
CWindow wndDesk = ::GetDesktopWindow();
wndDesk.GetClientRect(&rcDesk);
rc = rcDesk;
CDCHandle dcDesk = wndDesk.GetDC();
CDC dcMem;
dcMem.CreateCompatibleDC(dcDesk);
if(bmp_srcreen.IsNull() == FALSE)
bmp_srcreen.DeleteObject();
bmp_srcreen.CreateCompatibleBitmap(dcDesk,rcDesk.Width(),rcDesk.Height());
dcMem.SelectBitmap(bmp_srcreen);
dcMem.BitBlt(0,0,rcDesk.Width(),rcDesk.Height(),dcDesk,0,0,SRCCOPY);
wndDesk.ReleaseDC(dcDesk);
}
sf.Create(m_hWnd,rc,NULL,WS_VISIBLE|WS_POPUP);
break;
default:
break;
}
return 0;
}
public:
void InitForm()
{
font_btn.CreatePointFont(110,"宋体");
// 400 * 300
btn_create.Create(m_hWnd,CRect(20,10,120,40),"新建",WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON,0,IDC_CREATE);
btn_create.SetFont(font_btn);
}
private:
CButton btn_create;
CFont font_btn;
ScreenForm sf;

enum { IDC_CREATE = 10001 };
};

截图中:背景是半透明,选中区域是不透明。

屏幕截图程序(WTL)