C++编写截屏软件(ScreenCapture_v1.0.0)
Posted 默库
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++编写截屏软件(ScreenCapture_v1.0.0)相关的知识,希望对你有一定的参考价值。
欢迎关注小程序“默库”,包含工具与各类网址,功能持续更新中。
回复关键字"截屏",获取下载链接。资料关键字已汇总在“资料目录”栏。
资料仅供学习
“ScreenCapture.exe”又名“简约截屏.exe”
源码链接:
https://github.com/imoki/ScreenCapture
程序下载链接:
https://github.com/imoki/ScreenCapture/releases/download/v1.0.0/ScreenCapture_v1.0.0.exe
演示
程序大小187KB
双击运行程序
按快捷键“Ctrl+U”,然后用鼠标左键滑动屏幕选择区域,选择好要截屏的区域后“快速双击左键”即可截屏
程序会在后台运行,还想截屏就按“Ctrl+U”,鼠标选择截屏区域,双击左键完成截屏。
如果不想再运行程序了,按“Ctrl+I”即可关闭后台运行,此时已退出程序。
C++源码
github链接:https://github.com/imoki/ScreenCapture
ScreenCapture.cpp
// ScreenCapture.cpp : Defines the class behaviors for the application.
// CScreenCaptureApp
BEGIN_MESSAGE_MAP(CScreenCaptureApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CScreenCaptureApp construction
CScreenCaptureApp::CScreenCaptureApp()
{
// support Restart Manager
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
// The one and only CScreenCaptureApp object
CScreenCaptureApp theApp;
// CScreenCaptureApp initialization
BOOL CScreenCaptureApp::InitInstance()
{
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// Create the shell manager, in case the dialog contains
// any shell tree view or shell list view controls.
CShellManager *pShellManager = new CShellManager;
// Activate "Windows Native" visual manager for enabling themes in MFC controls
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
CScreenCaptureDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
else if (nResponse == -1)
{
TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n");
TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\n");
}
// Delete the shell manager created above.
if (pShellManager != NULL)
{
delete pShellManager;
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
ScreenCapture.h
// ScreenCapture.h : main header file for the PROJECT_NAME application
//
// CScreenCaptureApp:
// See ScreenCapture.cpp for the implementation of this class
//
class CScreenCaptureApp : public CWinApp
{
public:
CScreenCaptureApp();
// Overrides
public:
virtual BOOL InitInstance();
// Implementation
DECLARE_MESSAGE_MAP()
};
extern CScreenCaptureApp theApp;
ScreenCaptureDlg.cpp
这是绘制初始化窗口,以及实现快捷键功能的代码
// ScreenCaptureDlg.cpp : implementation file
//
// CScreenCaptureDlg dialog
CScreenCaptureDlg::CScreenCaptureDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CScreenCaptureDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CScreenCaptureDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CScreenCaptureDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CScreenCaptureDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON3, &CScreenCaptureDlg::OnBnClickedButton3)
ON_WM_HOTKEY() //快捷键
END_MESSAGE_MAP()
// CScreenCaptureDlg message handlers
BOOL CScreenCaptureDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 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
// 快捷键
::RegisterHotKey(m_hWnd, 199, MOD_CONTROL, 'U'); // 注册的热键id为199,可以自己改,Ctrl+U。MOD_ALU就是Alt
::RegisterHotKey(m_hWnd, 200, MOD_CONTROL, 'I');
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
//快捷键
void CScreenCaptureDlg::OnHotKey(UINT nHotKeyID, UINT nKey1, UINT nKey2)
{
if (nHotKeyID == 199)
{
//AfxMessageBox(_T("使用了热键"));
//DoModal();
ShowWindow(SW_HIDE); // 点击完后隐藏此对话框
Sleep(500); // 休眠500毫秒,以免截屏太快,上面的对话框没来得及完全消失
CShowDlg dlg; // 定义点击截图后弹出的窗口
dlg.DoModal(); // 模态,点击截图,则弹出窗口
return;
}
if (nHotKeyID == 200)
{
//AfxMessageBox(_T("使用了热键"));
//DoModal();
exit(0);
return;
}
CDialogEx::OnHotKey(nHotKeyID, nKey1, nKey2);
}
BOOL CScreenCaptureDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
::UnregisterHotKey(m_hWnd, 199);
return CDialogEx::DestroyWindow();
}
// 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 CScreenCaptureDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<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
{
CDialogEx::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CScreenCaptureDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
// 截图按钮
void CScreenCaptureDlg::OnBnClickedButton1()
{
ShowWindow(SW_HIDE); // 点击完后隐藏此对话框
Sleep(500); // 休眠500毫秒,以免截屏太快,上面的对话框没来得及完全消失
CShowDlg dlg; // 定义点击截图后弹出的窗口
dlg.DoModal(); // 模态,点击截图,则弹出窗口
}
void CScreenCaptureDlg::OnBnClickedButton3()
{
// TODO: Add your control notification handler code here
//CShowDlg dlg; // 定义点击截图后弹出的窗口
//dlg.DoModal(); // 模态,点击截图,则弹出窗口
ShowWindow(SW_HIDE); // 点击完后隐藏此对话框
}
ScreenCaptureDlg.h
// ScreenCaptureDlg.h : header file
//
// CScreenCaptureDlg dialog
class CScreenCaptureDlg : public CDialogEx
{
// Construction
public:
CScreenCaptureDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
enum { IDD = IDD_SCREENCAPTURE_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton3();
// 快捷键
afx_msg void OnHotKey(UINT nHotKeyID, UINT nKey1, UINT nKey2);
virtual BOOL DestroyWindow();
};
ShowDlg.cpp
用来绘制截屏区域,就是绘制如下的黑框框
// ShowDlg.cpp : implementation file
//
// CShowDlg dialog
IMPLEMENT_DYNAMIC(CShowDlg, CDialogEx)
CShowDlg::CShowDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CShowDlg::IDD, pParent)
{
// 采集屏幕当前瞬间的图像
// 获取屏幕的宽和高
m_nWidth = GetSystemMetrics(SM_CXSCREEN);
m_nHeight = GetSystemMetrics(SM_CYSCREEN);
// 获取桌面DC
// 设备上下文
CDC *pDC = GetDesktopWindow()->GetDC();
// 创建位图
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC, m_nWidth, m_nHeight);
// 创建内存DC
m_memDC.CreateCompatibleDC(pDC);
m_memDC.SelectObject(&bmp);
m_memDC.BitBlt(0, 0, m_nWidth, m_nHeight, pDC, 0, 0, SRCCOPY);
// 释放DC,释放GDI对象
pDC->DeleteDC();
bmp.DeleteObject();
}
CShowDlg::~CShowDlg()
{
}
void CShowDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CShowDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
//ON_MESSAGE(WM_HOTKEY,OnHotKey)
//ON_WM_HOTKEY() //快捷键
END_MESSAGE_MAP()
// CShowDlg message handlers
// 初始化
BOOL CShowDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 快捷键
::RegisterHotKey(m_hWnd, 199, MOD_CONTROL, 'U'); // 注册的热键id为199,可以自己改,Ctrl+U。MOD_ALU就是Alt
// 将窗口移动,调节成和屏幕一样大,前两位参数是移动到的初始坐标在左上角,后两位的最后的坐标在右下角
MoveWindow(0, 0, m_nWidth, m_nHeight);
// 初始化橡皮筋
// resizeInside是点向里,resizeOutside点向外,dottedline是虚线,solidLine是实线
m_tracker.m_nStyle = (CRectTracker::resizeInside | CRectTracker::solidLine);
m_tracker.m_nHandleSize = 5; // 控制柄的像素大小
m_tracker.m_rect.SetRect(0, 0, 0, 0); // 初始化选框大小,没有大小
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
/*
//快捷键
void CShowDlg::OnHotKey(UINT nHotKeyID, UINT nKey1, UINT nKey2)
{
if (nHotKeyID == 199)
{
AfxMessageBox(_T("使用了热键"));
//DoModal();
return;
}
CDialogEx::OnHotKey(nHotKeyID, nKey1, nKey2);
}
BOOL CShowDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
::UnregisterHotKey(m_hWnd, 199);
return CDialogEx::DestroyWindow();
}
*/
void CShowDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CDialogEx::OnPaint() for painting messages
// 将桌面图像显示到对话框上,达到一截屏就屏幕就“不动”
dc.BitBlt(0, 0, m_nWidth, m_nHeight, &m_memDC, 0, 0, SRCCOPY);
// 绘制橡皮筋
m_tracker.Draw(&dc);
}
void CShowDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
// 选择函数,按F1可以自动去浏览器查找说明。这里是HitTest的返回值
// CRectTracker::hitNothing –1
// CRectTracker::hitTopLeft 0
// CRectTracker::hitTopRight 1
// CRectTracker::hitBottomRight 2
// CRectTracker::hitBottomLeft 3
// CRectTracker::hitTop 4
// CRectTracker::hitRight 5
// CRectTracker::hitBottom 6
// CRectTracker::hitLeft 7
// CRectTracker::hitMiddle 8
// 如果点中的区域是上一次框选的区域,那么不会出现画,否则就可以在另一个区域重新框选
if (m_tracker.HitTest(point) == CRectTracker::hitNothing)
{
m_tracker.TrackRubberBand(this, point, TRUE); // 是否允许翻转,TRUE是允许,FALSE是不允许
m_tracker.m_rect.NormalizeRect(); // 如果允许翻转那么需要让矩形坐标正常化
}
else // 如果鼠标点在选取里面,则可以移动选区
{
m_tracker.Track(this, point, TRUE); // 挪动选区,如果是边则可以改变大小,在内部则可以移动
m_tracker.m_rect.NormalizeRect();
}
Invalidate(FALSE); // FALSE刷新不擦除背景
CDialogEx::OnLButtonDown(nFlags, point);
}
// 双击
void CShowDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
// 获取选框大小
int nWidth = m_tracker.m_rect.Width();
int nHeight = m_tracker.m_rect.Height();
// 创建一个位图
CBitmap bmp;
bmp.CreateCompatibleBitmap(&m_memDC, nWidth, nHeight);
// 做一个临时内存DC
CDC tempDC;
tempDC.CreateCompatibleDC(NULL);
tempDC.SelectObject(&bmp);
// 复制数据
tempDC.BitBlt(0, 0, nWidth, nHeight, &m_memDC, m_tracker.m_rect.left, m_tracker.m_rect.top, SRCCOPY);
// 放到剪切板里,先打开剪切板
OpenClipboard();
// 清空剪切板
EmptyClipboard();
// 设置剪切板数据
SetClipboardData(CF_BITMAP, bmp);
// 关闭剪切板
CloseClipboard();
// 结束程序
//exit(0);
EndDialog(0);
CDialogEx::OnLButtonDblClk(nFlags, point);
}
ShowDlg.h
// CShowDlg dialog
class CShowDlg : public CDialogEx
{
DECLARE_DYNAMIC(CShowDlg)
public:
CShowDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CShowDlg();
// Dialog Data
enum { IDD = IDD_SHOW_DLG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
virtual BOOL OnInitDialog();
int m_nWidth; // 屏幕的宽
int m_nHeight; // 屏幕的高
CDC m_memDC; // 内存DC
CRectTracker m_tracker; // 橡皮筋,也就是可以伸缩矩形框
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
// 添加快捷键
//afx_msg LRESULT OnHotKey(WPARAM wParam, LPARAM lParam); // 添加消息响应函数声明
//afx_msg void OnHotKey(UINT nHotKeyID, UINT nKey1, UINT nKey2);
//virtual BOOL DestroyWindow();
};
因本人学识浅薄,文章若有存在的问题,请不吝赐教,笔者会万分感激并积极改进。
如有侵权,请联系删除。
》》》 扫码关注 》》》
以上是关于C++编写截屏软件(ScreenCapture_v1.0.0)的主要内容,如果未能解决你的问题,请参考以下文章
基于OpenCV C++写了一个截屏程序,但是当视频总帧数为截屏间隔整数倍时候 死循环