📄 catchscreendlg.cpp
字号:
// CatchScreenDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CatchScreen.h"
#include "CatchScreenDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCatchScreenDlg dialog
CCatchScreenDlg::CCatchScreenDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCatchScreenDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCatchScreenDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
//*******************************************************************************
//初始化像皮筋类
m_rectTracker.m_nStyle=CRectTracker::resizeInside|CRectTracker::solidLine;
m_rectTracker.m_rect.SetRect(-1,-1,-1,-1);
m_hCursor=AfxGetApp()->LoadCursor(IDC_CURSOR1);
m_bDraw=FALSE;
m_bFirstDraw=FALSE;
m_bQuit=FALSE;
m_bShowMsg=FALSE;
m_startPt=0;
//获取屏幕分辩率
m_xScreen = GetSystemMetrics(SM_CXSCREEN);
m_yScreen = GetSystemMetrics(SM_CYSCREEN);
//截取屏幕到位图中
CRect rect(0, 0,m_xScreen,m_yScreen);
m_pBitmap=CBitmap::FromHandle(CopyScreenToBitmap(&rect));
//一定要初始化m_rgn,
m_rgn.CreateRectRgn(0,0,50,50);
//*******************************************************************************
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCatchScreenDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCatchScreenDlg)
DDX_Control(pDX, IDC_EDIT1, m_tipEdit);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCatchScreenDlg, CDialog)
//{{AFX_MSG_MAP(CCatchScreenDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDBLCLK()
ON_WM_RBUTTONDOWN()
ON_WM_ERASEBKGND()
ON_WM_SETCURSOR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCatchScreenDlg message handlers
BOOL CCatchScreenDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//**************************************************************************
//把对化框设置成全屏顶层窗口
SetWindowPos(&wndTopMost,0,0,m_xScreen,m_yScreen,SWP_SHOWWINDOW);
//移动操作提示窗口
CRect rect;
m_tipEdit.GetWindowRect(&rect);
m_tipEdit.MoveWindow(10,10,rect.Width(),rect.Height());
//显示操作提示窗口文字
DrawTip();
//捕获按键消息窗口,将对话框的句柄传递到CCatchScreenApp中
((CCatchScreenApp *)AfxGetApp())->m_hwndDlg=m_hWnd;
//**************************************************************************
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CCatchScreenDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
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;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
//**************************************************************************
CPaintDC dc(this);
//显示截取矩形大小信息
if(m_bShowMsg&&m_bFirstDraw)
{
CRect rect;
m_rectTracker.GetTrueRect(&rect);
DrawMessage(rect);
}
//画出像皮筋矩形
if(m_bFirstDraw)
{
m_rectTracker.Draw(&dc);
}
//DrawTip();
//*************************************************************************
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CCatchScreenDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CCatchScreenDlg::OnOK()
{
// TODO: Add extra validation here
//CDialog::OnOK();
}
void CCatchScreenDlg::OnCancel()
{
// TODO: Add extra cleanup here
//***************************************************************
if(m_bFirstDraw)
{
m_bFirstDraw=FALSE;
m_bDraw=FALSE;
m_rectTracker.m_rect.SetRect(-1,-1,-1,-1);
PaintWindow();
}
else
{
CDialog::OnCancel();
}
//*******************************************************************
}
void CCatchScreenDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//**************************************************************************************
if(m_bDraw)
{
m_rectTracker.m_rect.SetRect(m_startPt.x+1,m_startPt.y+1,point.x,point.y);
m_bFirstDraw=TRUE;
PaintWindow();
}
DrawTip();
//*****************************************************************************************
CDialog::OnMouseMove(nFlags, point);
}
void CCatchScreenDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//*****************************************************************************************
int nHitTest;
nHitTest=m_rectTracker.HitTest(point);
m_bShowMsg=TRUE;
//PaintWindow();
PaintWindow();
//判断击中位置
if(nHitTest<0)
{
if(!m_bFirstDraw)
{
m_startPt=point;
m_bDraw=TRUE;
PaintWindow();
}
}
else
{
if(m_bFirstDraw)
{
m_rectTracker.Track(this,point,TRUE);
SendMessage(WM_LBUTTONUP,NULL,NULL);
PaintWindow();
}
}
//****************************************************************************************
CDialog::OnLButtonDown(nFlags, point);
}
void CCatchScreenDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//****************************************************************************************
m_bShowMsg=FALSE;
m_bDraw=FALSE;
PaintWindow();
//****************************************************************************************
CDialog::OnLButtonUp(nFlags, point);
}
void CCatchScreenDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
int nHitTest;
nHitTest=m_rectTracker.HitTest(point);
if(nHitTest==8)
{
CopyScreenToBitmap(m_rectTracker.m_rect,TRUE);
PostQuitMessage(0);
}
CDialog::OnLButtonDblClk(nFlags, point);
}
void CCatchScreenDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//****************************************************************************************
if(m_bFirstDraw)
{
//如果已经截取矩则清除截取矩形
m_bFirstDraw=FALSE;
m_rectTracker.m_rect.SetRect(-1,-1,-1,-1);
PaintWindow();
}
else
{
//关闭程序
//ShowWindow(SW_HIDE);
PostQuitMessage(0);
}
//****************************************************************************************
CDialog::OnRButtonDown(nFlags, point);
}
BOOL CCatchScreenDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
//**************************************************************************************
//用整个桌面填充全屏对话框背景
BITMAP bmp;
m_pBitmap->GetBitmap(&bmp);
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(pDC);
dcCompatible.SelectObject(m_pBitmap);
CRect rect;
GetClientRect(&rect);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);
return TRUE;
//**************************************************************************************
//return CDialog::OnEraseBkgnd(pDC);
}
BOOL CCatchScreenDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
//***********************************************************************
//设置改变截取矩形大小时光标
if (pWnd == this && m_rectTracker.SetCursor(this, nHitTest))
{
return TRUE;
}
else
{
//设置彩色光标
SetCursor(m_hCursor);
return TRUE;
}
//*******************************************************************
//return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
//*********************增加的函数**********************************************************
//考贝屏幕,这段代码是拿来主义 呵呵
HBITMAP CCatchScreenDlg::CopyScreenToBitmap(LPRECT lpRect,BOOL bSave)
//lpRect 代表选定区域
{
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap, hOldBitmap;
// 位图句柄
int nX, nY, nX2, nY2;
// 选定区域坐标
int nWidth, nHeight;
// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
//确保选定区域是可见的
if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > m_xScreen)
nX2 = m_xScreen;
if (nY2 > m_yScreen)
nY2 = m_yScreen;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap
(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
if(bSave)
{
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(CDC::FromHandle(hMemDC));
dcCompatible.SelectObject(m_pBitmap);
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
dcCompatible, nX, nY, SRCCOPY);
}
else
{
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
hScrDC, nX, nY, SRCCOPY);
}
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
//得到屏幕位图的句柄
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// 返回位图句柄
if(bSave)
{
if (OpenClipboard())
{
//清空剪贴板
EmptyClipboard();
//把屏幕内容粘贴到剪贴板上,
//hBitmap 为刚才的屏幕位图句柄
SetClipboardData(CF_BITMAP, hBitmap);
//关闭剪贴板
CloseClipboard();
}
}
return hBitmap;
}
//显示操作提示信息
void CCatchScreenDlg::DrawTip()
{
//得当前坐标像素,
CPoint pt;
GetCursorPos(&pt);
//pt.x+=3;
//pt.y+=3;
//当到当前R,G,B,各像素值
COLORREF color;
CClientDC dc(this);
color=dc.GetPixel(pt);
BYTE rValue,gValue,bValue;
rValue=GetRValue(color);
gValue=GetGValue(color);
bValue=GetGValue(color);
//按格式排放字符串
CString string;
CString strTemp;
string.Format("\r\n\r\n\r\n ·当前像素RGB (%d,%d,%d)\r\n",rValue,gValue,bValue);
if(!m_bDraw&&!m_bFirstDraw)
{
strTemp="\r\n ·按下鼠标左键不放选择截取\r\n 范围\r\n\r\n ·按ESC键或鼠标右键退出";
}
else
if(m_bDraw&&m_bFirstDraw)
{
strTemp="\r\n ·松开鼠标左键确定截取范围\r\n\r\n ·按ESC键退出";
}
else
if(m_bFirstDraw)
{
strTemp="\r\n ·用鼠标左键调整截取范围的\r\n 大小和位置\r\n\r\n·截取范围内双击鼠标左键保存\r\n 图像,结束操作\r\n\r\n·点击鼠标右键重新选择";
}
string+=strTemp;
//显示到编缉框中,操作提示窗口
m_tipEdit.SetWindowText(string);
}
//显示截取矩形信息
void CCatchScreenDlg::DrawMessage(CRect &inRect)
{
//截取矩形大小信息离鼠标间隔
const int space=3;
//设置字体颜色大小
CClientDC dc(this);
CPoint pt;
CPen pen(PS_SOLID,1,RGB(147,147,147));
dc.SetTextColor(RGB(147,147,147));
CFont font;
font.CreatePointFont(90,"宋体");
dc.SelectObject(&font);
//得到字体宽度和高度
GetCursorPos(&pt);
dc.SetBkMode(TRANSPARENT);
TEXTMETRIC tm;
int charHeight;
CSize size;
int lineLength;
dc.GetTextMetrics(&tm);
charHeight = tm.tmHeight+tm.tmExternalLeading;
size=dc.GetTextExtent("顶点位置 ",strlen("顶点位置 "));
lineLength=size.cx;
//初始化矩形, 以保证写下六行文字
CRect rect(pt.x+space,pt.y-charHeight*6-space,pt.x+lineLength+space,pt.y-space);
int x = GetDeviceCaps(dc, HORZRES);
int y = GetDeviceCaps(dc, VERTRES);
//创建临时矩形
CRect rectTemp;
//当矩形到达桌面边缘时调整方向和大小
if((pt.x+rect.Width())>=x)
{
//桌面上方显示不下矩形
rectTemp=rect;
rectTemp.left=rect.left-rect.Width()-space*2;
rectTemp.right=rect.right-rect.Width()-space*2;;
rect=rectTemp;
}
if((pt.y-rect.Height())<=0)
{
//桌面右方显示不下矩形
rectTemp=rect;
rectTemp.top=rect.top+rect.Height()+space*2;;
rectTemp.bottom=rect.bottom+rect.Height()+space*2;;
rect=rectTemp;
}
//创建空画刷画矩形
dc.SelectObject((HBRUSH)GetStockObject(NULL_BRUSH));
dc.Rectangle(rect);
rect.top+=2;
//在矩形中显示文字
CString string(" 顶点位置 ");
dc.TextOut(rect.left,rect.top,string);
string.Format(" (%d,%d)",inRect.left,inRect.top);
dc.TextOut(rect.left,rect.top+charHeight,string);
string=" 矩形大小 ";
dc.TextOut(rect.left,rect.top+charHeight*2,string);
string.Format(" (%d,%d)",inRect.Width(),inRect.Height());
dc.TextOut(rect.left,rect.top+charHeight*3,string);
string=" 光标坐标 ";
dc.TextOut(rect.left,rect.top+charHeight*4,string);
string.Format(" (%d,%d)",pt.x,pt.y);
dc.TextOut(rect.left,rect.top+charHeight*5,string);
}
//重画窗口
void CCatchScreenDlg::PaintWindow()
{
//获取当全屏对话框窗口大小
CRect rect1;
GetWindowRect(rect1);
//获取编辑框窗口大小
CRect rect2;
m_tipEdit.GetWindowRect(rect2);
CRgn rgn1,rgn2;
rgn1.CreateRectRgnIndirect(rect1);
rgn2.CreateRectRgnIndirect(rect2);
//获取更新区域,就是除了编辑框窗口不更新
m_rgn.CombineRgn(&rgn1,&rgn2,RGN_DIFF);
InvalidateRgn(&m_rgn);
}
//*******************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -