下载本应用
本windows应用录制屏幕图像写入MP4,WMV,ASF视频文件。下面是软件的界面图片。
屏幕录像应用程序的使用
一.录制区域的选择。有3中录制方案。
1.录制选定区域。调整红色选框,可以调整选定区域。由于使用“写视频文件”过滤器,该过滤器要求视频的宽高是4的倍数;选定区域宽高将始终为4的倍数。可以将选定区域与屏幕边缘自动对齐。
2.录制工作区。工作区是除去任务栏的整个屏幕。
3.录制全屏幕。
二.帧率选择。可以将帧率设置为1-30帧/每秒。
三.输出文件比特率设置。默认使用默认比特率,默认比特率的计算方法为:视频宽度X视频高度X帧率/6。也可指定其它比特率值。程序输出MP4,WMV,ASF视频文件。
四.声音为录制系统声音。
五.不录制鼠标光标。
六.录制全屏和录制工作区时,可以隐藏控制窗口。这时可以使用快捷键控制运行(F9),暂停(F10)和停止(F11)。如果是录制选定区域,在运行和暂停时将无法调整红色选框和控制窗口。
七.适用系统。win8及以上。仅在win10系统下做过测试,其它系统下没有测试。注意,无法在win7及以下系统下使用。
屏幕录像应用程序开发信息
程序由32位MFC对话框应用程序创建。
创建过滤器图。在图中创建“屏幕录像”过滤器和“写视频文件”过滤器,并连接引脚。
理论上,根据需要创建过滤器图并运行即可。但实际上,停止图后,用户有可能更改设置参数;设置参数更改后,须重新连接引脚,将更改后的参数应用于引脚媒体类型;故,使用两个函数实现对过滤器图的操作,CreateGraph函数创建过滤器图,ResetGraph函数重新设置过滤器图。
程序设置为只可运行一个实例。
C屏幕录像App为应用程序类。
C屏幕录像Dlg为MFC程序主对话框,作为控制窗口。
CFrame选区窗口。
CDlg4设置窗口。
CDlg2显示选区大小窗口。
CMyButton用于绘制按钮。
CMyComboBox绘制组合框。
CRABtn绘制单选按钮。
下面是屏幕录像应用程序的全部代码
屏幕录像.h
// 屏幕录像.h : PROJECT_NAME 应用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif
#include "resource.h" // 主符号
#include "Frame.h"
#include "dshow.h"
#pragma comment(lib, "strmiids")
class C屏幕录像App : public CWinApp
{
public:
C屏幕录像App();
public:
virtual BOOL InitInstance();
DECLARE_MESSAGE_MAP()
public:
HMODULE h1 = NULL;//“屏幕录像”DLL模块句柄
HMODULE h2 = NULL;//”写MP4”DLL模块句柄
CFrame FrameDlg;//区域窗口
virtual int ExitInstance();
};
extern C屏幕录像App theApp;
屏幕录像.cpp
// 屏幕录像.cpp : 定义应用程序的类行为。
//
#include "stdafx.h"
#include "屏幕录像.h"
#include "屏幕录像Dlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// C屏幕录像App
BEGIN_MESSAGE_MAP(C屏幕录像App, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// C屏幕录像App 构造
C屏幕录像App::C屏幕录像App()
{
// 支持重新启动管理器
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 C屏幕录像App 对象
C屏幕录像App theApp;
HANDLE hMutex;//互斥对象句柄
BOOL C屏幕录像App::InitInstance()
{
HANDLE hLinShi = CreateMutex(NULL, FALSE, L"屏幕录像001");//创建互斥对象
DWORD dwRet = ::GetLastError();
if (hLinShi)
{
if (ERROR_ALREADY_EXISTS == dwRet)//如果已创建实例
{
CloseHandle(hLinShi); MessageBox(NULL, L"只可运行1个“屏幕录像”实例", L"注意", MB_OK);
return FALSE;//返回,不创建新的实例
}
}
hMutex = hLinShi;
h1 = LoadLibrary(L"屏幕录像.dll");
h2 = LoadLibrary(L"写视频文件.dll");
if (h1 == NULL)
{
MessageBox(NULL, L"缺失“屏幕录像.dll”", L"屏幕录像", MB_OK); return FALSE;
}
if (h2 == NULL)
{
MessageBox(NULL, L"缺失“写视频文件.dll”", L"屏幕录像", MB_OK); return FALSE;
}
HRESULT hr = CoInitialize(NULL);//初始化COM库
if (hr != S_OK)
{
MessageBox(NULL, _T("COM库初始化失败!"), L"屏幕录像", MB_OK);
}
FARPROC Proc1 = GetProcAddress(h1, "DllRegisterServer");//获取“屏幕录像DLL”注册函数的地址
FARPROC Proc2 = GetProcAddress(h2, "DllRegisterServer");//获取“写MP4DLL”注册函数的地址
if (Proc1 != NULL)//如果地址不为空
Proc1();//注册屏幕录像过滤器
if (Proc2 != NULL)//如果地址不为空
Proc2();//注册写视频文件过滤器
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// 创建 shell 管理器,以防对话框包含
// 任何 shell 树视图控件或 shell 列表视图控件。
CShellManager *pShellManager = new CShellManager;
// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
SetRegistryKey(_T("屏幕录像"));
FrameDlg.Create(IDD_DIALOG1, NULL);
C屏幕录像Dlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: 在此放置处理何时用
// “确定”来关闭对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用
// “取消”来关闭对话框的代码
}
else if (nResponse == -1)
{
TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
}
if (pShellManager != NULL)
{
delete pShellManager;
}
return FALSE;
}
int C屏幕录像App::ExitInstance()
{
FARPROC Proc3 = GetProcAddress(h1, "DllUnregisterServer");//获取“屏幕录像DLL”删除注册函数的地址
FARPROC Proc4 = GetProcAddress(h2, "DllUnregisterServer");//获取“写视频文件DLL”删除注册函数的地址
if (Proc3 != NULL)//如果地址不为空
Proc3();//删除屏幕录像过滤器注册
if (Proc4 != NULL)//如果地址不为空
Proc4();//删除写视频文件过滤器注册
CoUninitialize();//关闭COM库
CloseHandle(hMutex);//在销毁实例时,销毁互斥对象
return CWinApp::ExitInstance();
}
屏幕录像Dlg.h
// 屏幕录像Dlg.h : 头文件
//
#pragma once
#include "afxwin.h"
#include "MyButton.h"
#include "Dlg4.h"
interface IMy001 : public IUnknown//“屏幕录像”过滤器自定义接口,用于设置和获取图像输出编码比特率
{
public:
virtual HRESULT SetFramesPerSec(DWORD nFrames) = 0;//设置每秒帧数
virtual HRESULT SetRect(RECT rect) = 0;//设置录制矩形
virtual HRESULT GetLostNum(DWORD* Nu) = 0;//获取丢帧数量
virtual HRESULT GetPos(DWORD* cur) = 0;//获取当前时间,单位毫秒
};
interface IMy002 : public IUnknown//自定义接口,用于设置和获取图像输出编码比特率
{
public:
virtual HRESULT GetVideoBitRate(UINT32* Rate) = 0;//获取图像输出编码比特率
virtual HRESULT SetVideoBitRate(UINT32 Rate) = 0;//设置图像输出编码比特率
};
template <class T> void SafeRelease(T** ppT)
{
if (*ppT)
{
(*ppT)->Release();
*ppT = NULL;
}
}
// C屏幕录像Dlg 对话框
class C屏幕录像Dlg : public CDialogEx
{
// 构造
public:
C屏幕录像Dlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MY_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedOk();
CMyButton Run_btn;
CMyButton Pause_btn;
CMyButton Stop_btn;
CMyButton btn10;
CMyButton btn9;
CMyButton Mo_btn;
CMyButton Set_btn;
CMyButton End_btn;
CRect SelRect;//录制区域矩形
CRect PM_rect;//工作区矩形
CRect ScreenRect;//屏幕矩形
void _SetPos();//定位控件
CStatic sta3;
CStatic ShowTime;
CStatic pic;
CBrush brush1;
CBrush brush2;
CBrush brush3;
COLORREF color1;
CFont font1;
CFont font2;
CString Path;//输出文件夹路径
CString ExName=L".mp4";//输出文件扩展名
BOOL TOP = TRUE;//为TRUE时,控制窗口在上,反之在下
DWORD VIDEO_FPS = 30;//每秒帧数
UINT32 VIDEO_BIT_RATE = 0;//图像输出编码比特率
int Index = 0;//0录制选定区域,1录制工作区,2录制全屏
int Left = 0;
int MinWidth = 428;//控制窗口最小宽度
BOOL BSet = FALSE;
IGraphBuilder* pGraph1 = NULL;//过滤器图管理器1接口指针
IBaseFilter *pScreenRecorder1 = NULL;//图1”屏幕录像“过滤器指针
IMy001* pIMy001_1 = NULL;//”屏幕录像“过滤器自定义接口
IBaseFilter *pWriter1 = NULL;//图1“写视频文件”过滤器指针
IMediaControl* pControl1 = NULL;//图1媒体控制接口指针
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnBnClickedButton1();//运行按钮
afx_msg void OnBnClickedButton2();//暂停按钮
afx_msg void OnBnClickedButton3();//停止按钮
afx_msg void OnBnClickedButton4();//“隐藏窗口”按钮
afx_msg void OnBnClickedButton5();//“最小化窗口”按钮
afx_msg void OnBnClickedButton6();//“移动窗口”按钮
afx_msg void OnBnClickedButton7();//“设置”按钮
afx_msg void OnBnClickedButton8();//退出程序按钮
afx_msg LRESULT OnNcHitTest(CPoint point);
afx_msg void OnDestroy();
HRESULT CreateGraph1();
HRESULT ResetGraph1();
afx_msg void OnMoving(UINT fwSide, LPRECT pRect);
afx_msg void OnExitSizeMove();
};
屏幕录像Dlg.cpp
// 屏幕录像Dlg.cpp : 实现文件
//
#include "stdafx.h"
#include "屏幕录像.h"
#include "屏幕录像Dlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
UINT LightThread(LPVOID pParam)//时间和指示灯线程函数
{
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)pParam;
CBitmap bmp0, bmp1, bmp2;
bmp0.LoadBitmap(IDB_BITMAP1); bmp1.LoadBitmap(IDB_BITMAP21); bmp2.LoadBitmap(IDB_BITMAP22);
Agan:
if (pDlg->pControl1 != NULL)
{
FILTER_STATE fs;
pDlg->pControl1->GetState(1, (OAFilterState*)&fs);//获取图1状态
switch (fs)
{
case State_Stopped://如果停止
pDlg->pic.SetBitmap((HBITMAP)bmp0);
pDlg->pic.RedrawWindow();
return 1;
case State_Running://如果运行
pDlg->pic.SetBitmap((HBITMAP)bmp1);
pDlg->pic.RedrawWindow();
break;
case State_Paused://如果暂停
pDlg->pic.SetBitmap((HBITMAP)bmp2);
pDlg->pic.RedrawWindow();
Sleep(30); goto Agan;
break;
}
}
DWORD dw; HRESULT hr;
if (pDlg->pIMy001_1 != NULL)
hr = pDlg->pIMy001_1->GetPos(&dw);//获取当前时间
if (hr == S_OK)
{
int cur = (int)dw / 1000;//以秒为单位的当前位置
int shi = cur / 60 / 60;//时
int fen = (cur / 60) % 60;//分
int miao = cur % 60;//秒
wchar_t wch[50];
swprintf_s(wch, 50, L"%0*d:%0*d:%0*d", 2, shi, 2, fen, 2, miao);
pDlg->ShowTime.SetWindowText(wch);
}
Sleep(500);
pDlg->pic.SetBitmap((HBITMAP)bmp0);
pDlg->pic.RedrawWindow();
Sleep(500);
goto Agan;
return 1;
}
C屏幕录像Dlg::C屏幕录像Dlg(CWnd* pParent /*=NULL*/) : CDialogEx(IDD_MY_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
color1 = RGB(14, 241, 209);
brush1.CreateSolidBrush(RGB(0, 0, 0));
brush2.CreateSolidBrush(color1);
brush3.CreateSolidBrush(RGB(3, 38, 73));
font1.CreatePointFont(110, L"CAmbria");
font2.CreatePointFont(100, L"微软雅黑");
}
void C屏幕录像Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_BUTTON1, Run_btn);
DDX_Control(pDX, IDC_BUTTON2, Pause_btn);
DDX_Control(pDX, IDC_BUTTON3, Stop_btn);
DDX_Control(pDX, IDC_BUTTON4, btn10);
DDX_Control(pDX, IDC_BUTTON5, btn9);
DDX_Control(pDX, IDC_BUTTON6, Mo_btn);
DDX_Control(pDX, IDC_BUTTON7, Set_btn);
DDX_Control(pDX, IDC_BUTTON8, End_btn);
DDX_Control(pDX, IDC_STA3, sta3);
DDX_Control(pDX, IDC_STA1, ShowTime);
DDX_Control(pDX, IDC_STA2, pic);
}
BEGIN_MESSAGE_MAP(C屏幕录像Dlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &C屏幕录像Dlg::OnBnClickedOk)
ON_WM_ERASEBKGND()
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_BUTTON1, &C屏幕录像Dlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &C屏幕录像Dlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &C屏幕录像Dlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4, &C屏幕录像Dlg::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON5, &C屏幕录像Dlg::OnBnClickedButton5)
ON_BN_CLICKED(IDC_BUTTON6, &C屏幕录像Dlg::OnBnClickedButton6)
ON_BN_CLICKED(IDC_BUTTON7, &C屏幕录像Dlg::OnBnClickedButton7)
ON_BN_CLICKED(IDC_BUTTON8, &C屏幕录像Dlg::OnBnClickedButton8)
ON_WM_NCHITTEST()
ON_WM_DESTROY()
ON_WM_MOVING()
ON_WM_EXITSIZEMOVE()
END_MESSAGE_MAP()
HHOOK hhookKeyboardMsg;//键盘消息钩子过程句柄
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)//定义钩子过程函数
{
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam;
if (pDlg->BSet == FALSE)//设置对话框弹出时,阻止快捷键
{
if (p->vkCode == VK_F9)//如果按下F9键
{
pDlg->OnBnClickedButton1();//运行
}
if (p->vkCode == VK_F10)//如果按下F10键
{
pDlg->OnBnClickedButton2();//暂停
}
if (p->vkCode == VK_F11)//如果按下F11键
{
pDlg->OnBnClickedButton3();//停止
}
if (p->vkCode == VK_F5)//如果按下F5键
{
pDlg->ShowWindow(SW_RESTORE);//显示设置窗口
}
}
return CallNextHookEx(hhookKeyboardMsg, nCode, wParam, lParam);
}
BOOL C屏幕录像Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&PM_rect, 0);//获取工作区矩形
MoveWindow(PM_rect.Width() / 2 - 247, PM_rect.Height() / 2 - 201, 494, 28, 0);
_SetPos();//定位控件
sta3.SetFont(&font2);
ShowTime.SetFont(&font1);
ScreenRect.left = 0; ScreenRect.top = 0;
ScreenRect.right = GetSystemMetrics(SM_CXSCREEN);//获取主显示器的宽度,以像素为单位
ScreenRect.bottom = GetSystemMetrics(SM_CYSCREEN);//获取主显示器的高度,以像素为单位
theApp.FrameDlg.MoveWindow(PM_rect.Width() / 2 - 247, PM_rect.Height() / 2 - 173, 494, 374, 0);
theApp.FrameDlg.GetClientRect(SelRect); theApp.FrameDlg.ClientToScreen(SelRect);//初始化录制区域
GetCurrentDirectory(MAX_PATH, Path.GetBufferSetLength(MAX_PATH));
Path.ReleaseBuffer();
Path += L"\\录像输出";
CreateDirectory(Path, NULL);//创建“录像输出”文件夹,如果输出文件夹已存在,创建文件夹会失败
hhookKeyboardMsg = SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyboardProc, (HINSTANCE)NULL, 0);//安装键盘消息钩子
SetWindowText(L"屏幕录像");
CFileFind FF;
if (FF.FindFile(L"Set.dat"))//如果Set.dat文件存在,读取该文件
{
CFile F(L"Set.dat", CFile::modeRead);
CArchive ar(&F, CArchive::load);
ar >> VIDEO_FPS >> VIDEO_BIT_RATE >> Index >> ExName;
}
else//如果Set.dat文件存在,给录制方式,帧率,传输率赋初始值
{
Index = 0; VIDEO_FPS = 20; VIDEO_BIT_RATE = 0;
}
if (Index == 1 || Index == 2)
theApp.FrameDlg.ShowWindow(SW_HIDE);
if (Index == 0)sta3.SetWindowText(L"录制区域");
if (Index == 1)sta3.SetWindowText(L"录制工作区");
if (Index == 2)sta3.SetWindowText(L"录制全屏");
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void C屏幕录像Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
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;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
pic.RedrawWindow();//重绘指示灯
}
HCURSOR C屏幕录像Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void C屏幕录像Dlg::OnBnClickedOk()
{
}
void C屏幕录像Dlg::_SetPos()//定位控件
{
CRect rect;
GetClientRect(rect);
End_btn.MoveWindow(rect.right - 28, 4, 20, 20);//定位“退出”按钮
Set_btn.MoveWindow(rect.right - 54, 4, 20, 20);//定位“设置”按钮
Mo_btn.MoveWindow(rect.right - 80, 4, 20, 20);//定位“移动窗口”按钮
btn9.MoveWindow(rect.right - 106, 4, 20, 20);
btn10.MoveWindow(rect.right - 132, 4, 20, 20);
sta3.MoveWindow(28, 4, 80, 20);//静态文本控件,指示录制方案
int L = rect.Width() / 2 - 146 / 2;
ShowTime.MoveWindow(L - 10, 4, 68, 20);
Run_btn.MoveWindow(L + 68 + 6, 4, 20, 20);
Pause_btn.MoveWindow(L + 68 + 6 + 26, 4, 20, 20);
Stop_btn.MoveWindow(L + 68 + 6 + 26 + 26, 4, 20, 20);
CRect r; ShowTime.GetWindowRect(r); ScreenToClient(r);
pic.MoveWindow(r.left - 30, 7, 14, 14);//图片控件,表示指示灯
}
BOOL C屏幕录像Dlg::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(rect);
pDC->FillRect(rect, &CBrush(RGB(3, 38, 73)));
pDC->FrameRect(rect, &CBrush(RGB(120, 150, 160)));
CRect r1;
ShowTime.GetWindowRect(r1); ScreenToClient(r1); r1.InflateRect(1, 1);
pDC->FrameRect(r1, &brush2);
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP2);
CDC comdc;
comdc.CreateCompatibleDC(pDC);
comdc.SelectObject(&bmp);
pDC->BitBlt(4, 4, 20, 20, &comdc, 0, 0, SRCCOPY);//以原始大小绘制位图
return TRUE;
// return CDialogEx::OnEraseBkgnd(pDC);
}
HBRUSH C屏幕录像Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd->GetDlgCtrlID() == IDC_STA1)
{
pDC->SetBkColor(RGB(0, 0, 0)); pDC->SetTextColor(color1);
return (HBRUSH)brush1;
}
if (pWnd->GetDlgCtrlID() == IDC_STA3)
{
pDC->SetBkColor(RGB(3, 38, 73)); pDC->SetTextColor(color1);
return (HBRUSH)brush3;
}
return hbr;
}
void C屏幕录像Dlg::OnBnClickedButton1()//运行按钮
{
HRESULT hr;
if (pGraph1 == NULL)
{
hr = CreateGraph1();//创建图
if (hr != S_OK)
{
MessageBox(L"创建过滤器图失败"); return;
}
}
FILTER_STATE fs;
pControl1->GetState(1, (OAFilterState*)&fs);
switch (fs)
{
case State_Running://如果过滤器图正在运行,不进行任何操作
return;
case State_Paused://如果过滤器图正在暂停,运行过滤器图
if (pControl1 != NULL)
pControl1->Run();//运行图
break;
case State_Stopped://如果过滤器图正在停止,初始化过滤器图,并运行图
hr = ResetGraph1();//重新设置图
if (hr != S_OK)
{
MessageBox(L"创建过滤器图失败"); return;
}
pControl1->Run();//运行图
AfxBeginThread(LightThread, this);//创建时间和指示灯线程
break;
}
if (Index == 0)//如果是录制区域
theApp.FrameDlg.EnableWindow(FALSE);//运行时防止调整区域选择窗口
}
void C屏幕录像Dlg::OnBnClickedButton2()//暂停按钮
{
if (pControl1 != NULL)
{
FILTER_STATE fs;
pControl1->GetState(1, (OAFilterState*)&fs);
if (fs == State_Running)pControl1->Pause();//如果过滤器在运行状态,暂停图
}
}
void C屏幕录像Dlg::OnBnClickedButton3()//停止按钮
{
HRESULT hr;
if (pControl1 != NULL)
{
hr = pControl1->Stop();//停止图
}
Sleep(3000);//等待“写视频文件”过滤器完全停止
theApp.FrameDlg.EnableWindow(TRUE);
}
void C屏幕录像Dlg::OnBnClickedButton4()//“隐藏控制窗口”按钮
{
ShowWindow(SW_HIDE);
}
void C屏幕录像Dlg::OnBnClickedButton5()//“最小化控制窗口”按钮
{
ShowWindow(SW_MINIMIZE);
}
void C屏幕录像Dlg::OnBnClickedButton6()//“移动控制窗口”按钮
{
if (Index != 0)return;//如果不是录制区域,禁用“移动窗口”按钮
if (pControl1 != NULL)
{
FILTER_STATE fs;
pControl1->GetState(1, (OAFilterState*)&fs);
if (fs != State_Stopped)return;//如果不在停止状态,禁用“移动控制窗口”按钮
}
CRect rect;
theApp.FrameDlg.GetWindowRect(rect);
CRect Rect;
GetWindowRect(Rect);
if (TOP)//向下调整控制窗口位置
{
TOP = FALSE;
int b = rect.bottom + Rect.Height();
if (b > PM_rect.bottom)//如果控制窗口底边大于工作区底边
{
MoveWindow(Rect.left, PM_rect.bottom - Rect.Height(), Rect.Width(), Rect.Height());
theApp.FrameDlg.MoveWindow(rect.left, PM_rect.bottom - Rect.Height() - rect.Height(), rect.Width(), rect.Height());
}
else
{
MoveWindow(Rect.left, rect.bottom, Rect.Width(), Rect.Height());
}
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP6);
Mo_btn.SetBitmap((HBITMAP)bmp);
}
else//向上调整控制窗口位置
{
TOP = TRUE;
int t = rect.top - Rect.Height();
if (t < 0)//如果控制窗口顶边小于屏幕顶边
{
MoveWindow(Rect.left, 0, Rect.Width(), Rect.Height());
rect.MoveToY(Rect.Height());
theApp.FrameDlg.MoveWindow(rect);
}
else
{
MoveWindow(Rect.left, t, Rect.Width(), Rect.Height());
}
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP14);
Mo_btn.SetBitmap((HBITMAP)bmp);
}
}
void C屏幕录像Dlg::OnBnClickedButton7()//“设置”按钮
{
if (pControl1 != NULL)
{
FILTER_STATE fs;
pControl1->GetState(1, (OAFilterState*)&fs);
if (fs != State_Stopped)return;//如果不在停止状态,禁用“设置”按钮
}
EnableWindow(FALSE);
theApp.FrameDlg.EnableWindow(FALSE);
BSet = TRUE;
CDlg4 dlg4;//“设置”对话框
dlg4.DoModal();
BSet = FALSE;
EnableWindow(TRUE);
theApp.FrameDlg.EnableWindow(TRUE);
pic.RedrawWindow();//重绘指示灯
}
void C屏幕录像Dlg::OnBnClickedButton8()//退出程序按钮
{
if (pControl1 != NULL)
{
FILTER_STATE fs;
pControl1->GetState(1, (OAFilterState*)&fs);//获取过滤器图1状态
if (fs != State_Stopped)//如果不在停止状态,禁用退出程序按钮
{
return;
}
}
EndDialog(1);
}
LRESULT C屏幕录像Dlg::OnNcHitTest(CPoint point)//用于鼠标左键拖动控制窗口
{
if (pControl1 != NULL)
{
FILTER_STATE fs;
pControl1->GetState(1, (OAFilterState*)&fs);
if (fs != State_Stopped && Index == 0)return CDialogEx::OnNcHitTest(point);//如果不在停止状态,且为录制区域,禁用移动控制窗口
}
CRect rect;
GetClientRect(&rect);
ScreenToClient(&point);//将point的屏幕坐标转换为对话框客户区坐标
if (rect.PtInRect(point))//当point位于rect内,可以移动对话框
return HTCAPTION;
else
return CDialogEx::OnNcHitTest(point);
}
void C屏幕录像Dlg::OnDestroy()
{
CDialogEx::OnDestroy();
theApp.FrameDlg.ShowWindow(SW_HIDE);
if (pGraph1 != NULL)
{
pGraph1->RemoveFilter(pScreenRecorder1); pGraph1->RemoveFilter(pWriter1);//删除图所有过滤器
}
SafeRelease(&pIMy001_1);
SafeRelease(&pScreenRecorder1); SafeRelease(&pWriter1);//销毁过滤器
SafeRelease(&pControl1); SafeRelease(&pGraph1);//释放图媒体控制接口,销毁图
CFile F(L"Set.dat", CFile::modeCreate | CFile::modeWrite);
CArchive ar(&F, CArchive::store);
ar << VIDEO_FPS << VIDEO_BIT_RATE << Index << ExName;
}
HRESULT C屏幕录像Dlg::CreateGraph1()//创建图
{
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraph1));//创建过滤器图管理器
if (hr == S_OK)
{
hr = pGraph1->QueryInterface(IID_IMediaControl, (void **)&pControl1);//获取媒体控制接口
}
GUID guid1 = { 0x3e4ff11d, 0x128c, 0x4d71, 0x8b, 0xcc, 0x46, 0x1f, 0xcb, 0xae, 0x63, 0x20 };
hr = CoCreateInstance(guid1, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pScreenRecorder1));//创建屏幕录像过滤器
if (hr == S_OK)
{
hr = pGraph1->AddFilter(pScreenRecorder1, L"屏幕录像");//添加屏幕录像过滤器到图中
}
SafeRelease(&pIMy001_1);
GUID IID_IMy001 = { 0x9932100d, 0x67f0, 0x4265, 0x8c, 0x12, 0xde, 0x23, 0x54, 0xb1, 0x97, 0x6d };
hr = pScreenRecorder1->QueryInterface(IID_IMy001, (void**)&pIMy001_1);//获取“屏幕录像”过滤器自定义接口
if (hr == S_OK)
{
hr = pIMy001_1->SetFramesPerSec(VIDEO_FPS);//为“屏幕录像过滤器”设置帧率
}
if (hr == S_OK)
{
RECT rect;
if (Index == 0)//如果是录制选定区域
{
rect = SelRect;
}
else if (Index == 1)//如果是录制工作区
{
rect = PM_rect;
}
else//如果是录制全屏
{
rect = ScreenRect;
}
hr = pIMy001_1->SetRect(rect);//设置录制矩形
}
IPin* pV = NULL, *pA = NULL;
if (hr == S_OK)
{
hr = pScreenRecorder1->FindPin(L"Video", &pV);//获取“屏幕录像”过滤器视频输出引脚
}
if (hr == S_OK)
{
hr = pScreenRecorder1->FindPin(L"Audio", &pA);//获取“屏幕录像”过滤器音频输出引脚
}
if (hr == S_OK)
{
GUID guid2 = { 0x34c61e22, 0x9e18, 0x4192, 0x9e, 0x75, 0x4c, 0x26, 0x68, 0xc, 0xf0, 0xde };//创建写视频文件过滤器
hr = CoCreateInstance(guid2, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pWriter1));
}
if (hr == S_OK)
{
hr = pGraph1->AddFilter(pWriter1, L"写视频文件");//添加写视频文件过滤器到图中
}
IFileSinkFilter* pIFileSinkFilter = NULL;
if (hr == S_OK)
{
hr = pWriter1->QueryInterface(IID_IFileSinkFilter, (void**)&pIFileSinkFilter);
}
if (hr == S_OK)
{
CTime time = CTime::GetCurrentTime();
CString Name;
Name.Format(L"\\%0*d时%0*d分%0*d秒%s", 2, time.GetHour(), 2, time.GetMinute(), 2, time.GetSecond(), ExName);//以当前时间作为输出文件名
CString PathName = Path + Name;
hr = pIFileSinkFilter->SetFileName((LPCOLESTR)(LPCTSTR)PathName, NULL);//指定输出文件
}
SafeRelease(&pIFileSinkFilter);
IMy002* pIMy002 = NULL;
if (hr == S_OK)
{
GUID IID_IMy002 = { 0x587f38a2, 0x9c63, 0x45d2, 0xb9, 0x57, 0xa6, 0xf, 0xb1, 0x27, 0xdd, 0xb0 };
hr = pWriter1->QueryInterface(IID_IMy002, (void**)&pIMy002);//获取写视频文件自定义接口
}
if (hr == S_OK)
{
hr = pIMy002->SetVideoBitRate(VIDEO_BIT_RATE);//设置图像输出编码比特率
}
SafeRelease(&pIMy002);
IPin* pInV = NULL, *pInA = NULL;
if (hr == S_OK)
{
hr = pWriter1->FindPin(L"Video", &pInV);//获取“写视频文件”视频输入引脚
}
if (hr == S_OK)
{
hr = pWriter1->FindPin(L"Audio", &pInA);//获取“写视频文件”音频输入引脚
}
if (hr == S_OK)
{
hr = pGraph1->ConnectDirect(pV, pInV, NULL);//连接“屏幕录像”过滤器视频输出引脚,到“写视频文件”视频输入引脚
}
if (hr == S_OK)
{
hr = pGraph1->ConnectDirect(pA, pInA, NULL);//连接“屏幕录像”过滤器音频输出引脚,到“写视频文件”音频输入引脚
}
SafeRelease(&pV); SafeRelease(&pA); SafeRelease(&pInV); SafeRelease(&pInA);
return hr;
}
HRESULT C屏幕录像Dlg::ResetGraph1()//重新设置图
{
HRESULT hr;
IPin* pV = NULL, *pA = NULL;
hr = pScreenRecorder1->FindPin(L"Video", &pV);//获取“屏幕录像”过滤器视频输出引脚
if (hr == S_OK)
{
hr = pScreenRecorder1->FindPin(L"Audio", &pA);//获取“屏幕录像”过滤器音频输出引脚
}
IPin* pInV = NULL, *pInA = NULL;
if (hr == S_OK)
{
hr = pWriter1->FindPin(L"Video", &pInV);//获取“写视频文件”视频输入引脚
}
if (hr == S_OK)
{
hr = pWriter1->FindPin(L"Audio", &pInA);//获取“写视频文件”音频输入引脚
}
if (hr == S_OK)
{
hr = pGraph1->Disconnect(pV);//断开“屏幕录像”过滤器视频输出引脚连接
}
if (hr == S_OK)
{
hr = pGraph1->Disconnect(pInV);//断开“写视频文件”视频输入引脚连接
}
if (hr == S_OK)
{
hr = pGraph1->Disconnect(pA);//断开“屏幕录像”过滤器音频输出引脚连接
}
if (hr == S_OK)
{
hr = pGraph1->Disconnect(pInA);//断开“写视频文件”音频输入引脚连接
}
if (hr == S_OK)
{
hr = pIMy001_1->SetFramesPerSec(VIDEO_FPS);//为“屏幕录像过滤器”设置帧率
}
if (hr == S_OK)
{
RECT rect;
if (Index == 0)//如果是录制选定区域
{
rect = SelRect;
}
else if (Index == 1)//如果是录制工作区
{
rect = PM_rect;
}
else//如果是录制全屏
{
rect = ScreenRect;
}
hr = pIMy001_1->SetRect(rect);//设置录制矩形
}
IFileSinkFilter* pIFileSinkFilter = NULL;
if (hr == S_OK)
{
hr = pWriter1->QueryInterface(IID_IFileSinkFilter, (void**)&pIFileSinkFilter);
}
if (hr == S_OK)
{
CTime time = CTime::GetCurrentTime();
CString Name;
Name.Format(L"\\%0*d时%0*d分%0*d秒%s", 2, time.GetHour(), 2, time.GetMinute(), 2, time.GetSecond(), ExName);//以当前时间作为输出文件名
CString PathName = Path + Name;
hr = pIFileSinkFilter->SetFileName((LPCOLESTR)(LPCTSTR)PathName, NULL);//指定输出文件
}
SafeRelease(&pIFileSinkFilter);
IMy002* pIMy002 = NULL;
if (hr == S_OK)
{
GUID IID_IMy002 = { 0x587f38a2, 0x9c63, 0x45d2, 0xb9, 0x57, 0xa6, 0xf, 0xb1, 0x27, 0xdd, 0xb0 };
hr = pWriter1->QueryInterface(IID_IMy002, (void**)&pIMy002);//获取写视频文件过滤器自定义接口
}
if (hr == S_OK)
{
hr = pIMy002->SetVideoBitRate(VIDEO_BIT_RATE);//设置图像输出编码比特率
}
SafeRelease(&pIMy002);
if (hr == S_OK)
{
hr = pGraph1->ConnectDirect(pV, pInV, NULL);//连接“屏幕录像”过滤器视频输出引脚,到“写视频文件”视频输入引脚
}
if (hr == S_OK)
{
hr = pGraph1->ConnectDirect(pA, pInA, NULL);//连接“屏幕录像”过滤器音频输出引脚,到“写视频文件”音频输入引脚
}
SafeRelease(&pV); SafeRelease(&pA); SafeRelease(&pInV); SafeRelease(&pInA);
return hr;
}
void C屏幕录像Dlg::OnMoving(UINT fwSide, LPRECT pRect)
{
CDialogEx::OnMoving(fwSide, pRect);
CRect rect;
theApp.FrameDlg.GetWindowRect(rect);
if (TOP)
{
theApp.FrameDlg.MoveWindow(pRect->left + Left, pRect->bottom, rect.Width(), rect.Height());
}
else
{
theApp.FrameDlg.MoveWindow(pRect->left + Left, pRect->top - rect.Height(), rect.Width(), rect.Height());
}
if (Index == 0)//如果录制区域
{
theApp.FrameDlg.GetClientRect(SelRect); theApp.FrameDlg.ClientToScreen(SelRect);
}
}
void C屏幕录像Dlg::OnExitSizeMove()
{
CRect R;//控制窗口矩形
GetWindowRect(R);
CRect r;//选区窗口矩形
theApp.FrameDlg.GetWindowRect(r);
CRect r2;//选区矩形
theApp.FrameDlg.GetClientRect(r2); theApp.FrameDlg.ClientToScreen(r2);
int F = r2.left - r.left;//选区窗口边框宽度
if (TOP)//控制窗口在上
{
if (R.bottom != r.top)//如果控制窗口底边!=选区窗口顶边,以控制窗口底边对齐选区窗口顶边
{
r.MoveToY(R.bottom);
r2.MoveToY(R.bottom + F);
}
if (r2.bottom > ScreenRect.bottom)//如果选区矩形底边超出屏幕矩形,以屏幕矩形底边作为选区矩形底边,定位窗口
{
r2.MoveToY(ScreenRect.bottom - r2.Height());
r.MoveToY(ScreenRect.bottom - r2.Height() - F);
R.MoveToY(ScreenRect.bottom - r2.Height() - F - R.Height());
}
}
else//控制窗口在下
{
if (R.bottom > ScreenRect.bottom)//如果控制窗口底边超出屏幕矩形底边,以屏幕矩形底边对齐控制窗口底边
{
R.MoveToY(ScreenRect.bottom - R.Height());
r.MoveToY(R.top - r.Height());
r2.MoveToY(R.top - r.Height() + F);
}
if (r2.top < 0)//如果选区矩形顶边超出屏幕矩形,以屏幕矩形顶边作为选区矩形顶边,定位窗口
{
r2.MoveToY(0);
r.MoveToY(-F);
R.MoveToY(r2.Height() + F);
}
}
if (r2.left < 0)//如果选区矩形左边超出屏幕矩形,以屏幕矩形左边作为选区矩形左边,定位窗口
{
r2.MoveToX(0);
r.MoveToX(-F);
R.MoveToX(-F);
if (R.left < 0)R.MoveToX(0);
}
if (r2.right > ScreenRect.right)//如果选区矩形右边超出屏幕矩形,以屏幕矩形右边作为选区矩形左边,定位窗口
{
r2.MoveToX(ScreenRect.right - r2.Width());
r.MoveToX(ScreenRect.right - r2.Width() - F);
R.MoveToX(ScreenRect.right - r2.Width() - F);
if (R.right > ScreenRect.right)R.MoveToX(ScreenRect.right - R.Width());
}
MoveWindow(R); theApp.FrameDlg.MoveWindow(r);
SelRect = r2;
CDialogEx::OnExitSizeMove();
}
Dlg2.h
#pragma once
#include "afxwin.h"
// CDlg2 对话框
class CDlg2 : public CDialogEx
{
DECLARE_DYNAMIC(CDlg2)
public:
CDlg2(CWnd* pParent = NULL); // 标准构造函数
virtual ~CDlg2();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG2 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedOk();
CStatic sta21;
CStatic sta22;
CBrush brush;
CFont font;
virtual BOOL OnInitDialog();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
virtual BOOL PreTranslateMessage(MSG* pMsg);
};
Dlg2.cpp
// Dlg2.cpp : 实现文件
//
#include "stdafx.h"
#include "屏幕录像.h"
#include "Dlg2.h"
#include "afxdialogex.h"
// CDlg2 对话框
IMPLEMENT_DYNAMIC(CDlg2, CDialogEx)
CDlg2::CDlg2(CWnd* pParent /*=NULL*/) : CDialogEx(IDD_DIALOG2, pParent)
{
brush.CreateSolidBrush(RGB(3, 38, 73));
font.CreatePointFont(100, L"微软雅黑");
}
CDlg2::~CDlg2()
{
}
void CDlg2::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_STA21, sta21);
DDX_Control(pDX, IDC_STA22, sta22);
}
BEGIN_MESSAGE_MAP(CDlg2, CDialogEx)
ON_BN_CLICKED(IDOK, &CDlg2::OnBnClickedOk)
ON_WM_CTLCOLOR()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
void CDlg2::OnBnClickedOk()
{
}
BOOL CDlg2::OnInitDialog()
{
CDialogEx::OnInitDialog();
MoveWindow(0, 0, 140, 26);
sta21.MoveWindow(2, 2, 68, 22);
sta22.MoveWindow(70, 2, 68, 22);
sta21.SetFont(&font); sta22.SetFont(&font);
return TRUE;
}
HBRUSH CDlg2::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd->GetDlgCtrlID() == IDC_STA21 || pWnd->GetDlgCtrlID() == IDC_STA22)
{
pDC->SetBkColor(RGB(3, 38, 73)); pDC->SetTextColor(RGB(14, 241, 209));
return (HBRUSH)brush;
}
return hbr;
}
BOOL CDlg2::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(rect);
pDC->FillRect(rect, &CBrush(RGB(3, 38, 73)));
pDC->FrameRect(rect, &CBrush(RGB(14, 241, 209)));
return TRUE;
// return CDialogEx::OnEraseBkgnd(pDC);
}
BOOL CDlg2::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)return TRUE;//阻止ESC键关闭对话框
return CDialogEx::PreTranslateMessage(pMsg);
}
Dlg4.h
#pragma once
#include "afxwin.h"
#include "MyButton.h"
#include "RABtn.h"
#include "MyComboBox.h"
class CDlg4 : public CDialogEx
{
DECLARE_DYNAMIC(CDlg4)
public:
CDlg4(CWnd* pParent = NULL); // 标准构造函数
virtual ~CDlg4();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG4 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedOk();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
CFont font1;
CFont font2;
COLORREF BkColor;//背景颜色
COLORREF TextColor;//文本颜色
CBrush brush1;//对话框背景画刷
CBrush brush2;//编辑框背景画刷
CPen pen, pen2;
CStatic sta31;
CStatic sta34;
CStatic sta35;
CStatic sta36;
CStatic sta331;
CStatic sta332;
CRABtn ra311;
CRABtn ra312;
CRABtn ra313;
CMyComboBox combox31;
CEdit edit31;
CMyButton btnA1;
CRABtn ra317;
CRABtn ra318;
CRABtn ra319;
CRABtn ra320;
CRABtn ra321;
CRABtn ra322;
virtual BOOL OnInitDialog();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnBnClickedButton3a1();//“默认”按钮单击响应函数
afx_msg void OnBnClickedButton311();//“录制选定区域”单选按钮
afx_msg void OnBnClickedButton312();//“录制工作区”单选按钮
afx_msg void OnBnClickedButton313();//”录制全屏”单选按钮
afx_msg void OnBnClickedButton317();//“显示控制窗口”单选按钮
afx_msg void OnBnClickedButton318();//“最小化控制窗口”单选按钮
afx_msg void OnBnClickedButton319();//”隐藏控制窗口”单选按钮
afx_msg void OnBnClickedButton320();//“输出MP4”单选按钮
afx_msg void OnBnClickedButton321();//“输出WMV”单选按钮
afx_msg void OnBnClickedButton322();//“输出ASF”单选按钮
afx_msg void OnCbnSelchangeCombo31();//帧率组合框选择改变
afx_msg void OnEnChangeEdit31();//比特率编辑框文本改变
};
Dlg4.cpp
// Dlg4.cpp : 实现文件
//
#include "stdafx.h"
#include "屏幕录像.h"
#include "Dlg4.h"
#include "afxdialogex.h"
#include "屏幕录像Dlg.h"
// CDlg4 对话框
IMPLEMENT_DYNAMIC(CDlg4, CDialogEx)
CDlg4::CDlg4(CWnd* pParent /*=NULL*/) : CDialogEx(IDD_DIALOG4, pParent)
{
BkColor = RGB(50, 50, 50);
TextColor = RGB(142, 142, 142);
font1.CreatePointFont(100, L"微软雅黑"); font2.CreatePointFont(100, L"Cambria");
brush1.CreateSolidBrush(BkColor);
brush2.CreateSolidBrush(RGB(70, 70, 70));
pen.CreatePen(PS_SOLID, 1, RGB(70, 70, 70));
pen2.CreatePen(PS_SOLID, 1, TextColor);
}
CDlg4::~CDlg4()
{
}
void CDlg4::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_STA31, sta31);
DDX_Control(pDX, IDC_STA34, sta34);
DDX_Control(pDX, IDC_STA305, sta35);
DDX_Control(pDX, IDC_BUTTON311, ra311);
DDX_Control(pDX, IDC_BUTTON312, ra312);
DDX_Control(pDX, IDC_BUTTON313, ra313);
DDX_Control(pDX, IDC_STA331, sta331);
DDX_Control(pDX, IDC_COMBO31, combox31);
DDX_Control(pDX, IDC_STA332, sta332);
DDX_Control(pDX, IDC_EDIT31, edit31);
DDX_Control(pDX, IDC_BUTTON3A1, btnA1);
DDX_Control(pDX, IDC_BUTTON317, ra317);
DDX_Control(pDX, IDC_BUTTON318, ra318);
DDX_Control(pDX, IDC_BUTTON319, ra319);
DDX_Control(pDX, IDC_BUTTON320, ra320);
DDX_Control(pDX, IDC_BUTTON321, ra321);
DDX_Control(pDX, IDC_BUTTON322, ra322);
DDX_Control(pDX, IDC_STA306, sta36);
}
BEGIN_MESSAGE_MAP(CDlg4, CDialogEx)
ON_BN_CLICKED(IDOK, &CDlg4::OnBnClickedOk)
ON_WM_ERASEBKGND()
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_BUTTON311, &CDlg4::OnBnClickedButton311)
ON_BN_CLICKED(IDC_BUTTON3A1, &CDlg4::OnBnClickedButton3a1)
ON_BN_CLICKED(IDC_BUTTON312, &CDlg4::OnBnClickedButton312)
ON_BN_CLICKED(IDC_BUTTON313, &CDlg4::OnBnClickedButton313)
ON_BN_CLICKED(IDC_BUTTON317, &CDlg4::OnBnClickedButton317)
ON_BN_CLICKED(IDC_BUTTON318, &CDlg4::OnBnClickedButton318)
ON_BN_CLICKED(IDC_BUTTON319, &CDlg4::OnBnClickedButton319)
ON_BN_CLICKED(IDC_BUTTON320, &CDlg4::OnBnClickedButton320)
ON_BN_CLICKED(IDC_BUTTON321, &CDlg4::OnBnClickedButton321)
ON_BN_CLICKED(IDC_BUTTON322, &CDlg4::OnBnClickedButton322)
ON_CBN_SELCHANGE(IDC_COMBO31, &CDlg4::OnCbnSelchangeCombo31)
ON_EN_CHANGE(IDC_EDIT31, &CDlg4::OnEnChangeEdit31)
END_MESSAGE_MAP()
void CDlg4::OnBnClickedOk()
{
}
BOOL CDlg4::OnEraseBkgnd(CDC* pDC)
{
CRect rect;
GetClientRect(rect);
pDC->FillRect(rect, &CBrush(BkColor));
CBrush* pOldBrush = pDC->SelectObject(&brush2);
CPen* pOldPen = pDC->SelectObject(&pen2);
pDC->RoundRect(28, 38, 472, 154, 6, 6);
pDC->RoundRect(28, 194, 472, 310, 6, 6);
pDC->RoundRect(28, 348, 472, 462, 6, 6);
pDC->RoundRect(28, 498, 472, 562, 6, 6);
pDC->SetTextColor(TextColor);
pDC->SelectObject(&font2);
pDC->SetBkColor(RGB(70, 70, 70));
pDC->TextOutW(58, 510, L"F9");
pDC->TextOutW(58 +100, 510, L"F10");
pDC->TextOutW(58 + 200, 510, L"F11");
pDC->TextOutW(58 + 300, 510, L"F5");
pDC->SelectObject(&font1);
pDC->TextOutW(58, 498 + 30, L"运行");
pDC->TextOutW(58 + 100, 528, L"暂停");
pDC->TextOutW(58 + 200, 528, L"停止");
pDC->TextOutW(58 + 300, 528, L"显示控制窗口");
CRect r1;
edit31.GetWindowRect(r1); ScreenToClient(r1); r1.InflateRect(1, 1);
pDC->FrameRect(r1, &CBrush(TextColor));
CRect r2;
combox31.GetWindowRect(r2); ScreenToClient(r2); r2.InflateRect(1, 1);
pDC->FrameRect(r2, &CBrush(TextColor));//绘制“帧率选择”组合框边框
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
return TRUE;
// return CDialogEx::OnEraseBkgnd(pDC);
}
BOOL CDlg4::OnInitDialog()
{
CDialogEx::OnInitDialog();
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
CRect rect(0, 0, 500, 606);//设置客户区大小
DWORD style = GetExStyle();//获取对话框扩展样式
if (style & WS_EX_CLIENTEDGE)//如果对话框包含WS_EX_CLIENTEDGE样式,CalcWindowRect函数参数2使用CWnd::adjustOutside
{
CalcWindowRect(rect, CWnd::adjustOutside);//计算带边框的对话框窗口大小。CalcWindowRect函数为CWnd类函数
}
else//如果对话框不包含WS_EX_CLIENTEDGE样式,CalcWindowRect函数参数2使用CWnd::adjustBorder
{
CalcWindowRect(rect, CWnd::adjustBorder);//计算带边框的对话框窗口大小
}
MoveWindow(pDlg->PM_rect.Width() / 2 - rect.Width() / 2, pDlg->PM_rect.Height() / 2 - rect.Height() / 2, rect.Width(), rect.Height());//设置对话框的大小
sta31.MoveWindow(220, 10, 60, 20); sta31.SetFont(&font1);//“录制设置”静态文本控件
ra311.MoveWindow(58, 58, 112, 20);//“录制选定区域”单选按钮
ra312.MoveWindow(58, 86, 112, 20);//“录制工作区”单选按钮
ra313.MoveWindow(58, 114, 112, 20);//“录制全屏幕”单选按钮
sta331.MoveWindow(188, 68, 128, 20); sta331.SetFont(&font1);//“帧率”静态文本控件
sta332.MoveWindow(188, 104, 128, 20); sta332.SetFont(&font1);//“输出文件比特率”静态文本控件
combox31.MoveWindow(318, 68 - 2, 90, 20); combox31.SetFont(&font2);//“帧率”选择组合框
combox31.SetItemHeight(0, 14);//“帧率”选择组合框设置项高度
edit31.MoveWindow(318, 104, 90, 20); edit31.SetFont(&font1);//“比特率值”编辑框
btnA1.MoveWindow(418, 104, 30, 20);//“默认”按钮
sta34.MoveWindow(220, 164, 60, 20); sta34.SetFont(&font1);//“窗口”静态文本控件
ra317.MoveWindow(58, 214, 112, 20);//“显示控制窗口”单选按钮
ra318.MoveWindow(58, 242, 120, 20);//“最小化控制窗口”单选按钮
ra319.MoveWindow(58, 270, 120, 20);//”隐藏控制窗口”单选按钮
sta35.MoveWindow(200, 318, 100, 20); sta35.SetFont(&font1);//“输出文件格式”静态文本控件
ra320.MoveWindow(58, 367, 120, 20); //“显示控制窗口”单选按钮
ra321.MoveWindow(58, 395, 120, 20);//“最小化控制窗口”单选按钮
ra322.MoveWindow(58, 423, 120, 20);//”隐藏控制窗口”单选按钮
sta36.MoveWindow(200, 470, 100, 20); sta36.SetFont(&font1);//“快捷键”静态文本控件
combox31.AddString(L"30"); combox31.AddString(L"29"); combox31.AddString(L"28"); combox31.AddString(L"27"); combox31.AddString(L"26");
combox31.AddString(L"25"); combox31.AddString(L"24"); combox31.AddString(L"23"); combox31.AddString(L"22"); combox31.AddString(L"21");
combox31.AddString(L"20"); combox31.AddString(L"19"); combox31.AddString(L"18"); combox31.AddString(L"17"); combox31.AddString(L"16");
combox31.AddString(L"15"); combox31.AddString(L"14"); combox31.AddString(L"13"); combox31.AddString(L"12"); combox31.AddString(L"11");
combox31.AddString(L"10"); combox31.AddString(L"9"); combox31.AddString(L"8"); combox31.AddString(L"7"); combox31.AddString(L"6");
combox31.AddString(L"5"); combox31.AddString(L"4"); combox31.AddString(L"3"); combox31.AddString(L"2"); combox31.AddString(L"1");
combox31.SetCurSel(30 - pDlg->VIDEO_FPS);
if (pDlg->Index == 0)//录制选定区域
{
ra311.SetCheck(BST_CHECKED);
}
else if (pDlg->Index == 1)//录制工作区
{
ra312.SetCheck(BST_CHECKED);
}
else if (pDlg->Index == 2)//录制全屏
{
ra313.SetCheck(BST_CHECKED);
}
if (pDlg->VIDEO_BIT_RATE == 0)
edit31.SetWindowText(L"使用默认值");//“比特率值”编辑框初始文本
else
SetDlgItemInt(IDC_EDIT31, pDlg->VIDEO_BIT_RATE);
ra317.SetCheck(BST_CHECKED);//选中“显示控制窗口”单选按钮
ra320.SetCheck(BST_CHECKED);//选中“MP4”单选按钮
if (pDlg->ExName == L".mp4")
{
ra320.SetCheck(BST_CHECKED); ra321.SetCheck(BST_UNCHECKED); ra322.SetCheck(BST_UNCHECKED);
}
if (pDlg->ExName == L".wmv")
{
ra321.SetCheck(BST_CHECKED); ra320.SetCheck(BST_UNCHECKED); ra322.SetCheck(BST_UNCHECKED);
}
if (pDlg->ExName == L".asf")
{
ra322.SetCheck(BST_CHECKED); ra320.SetCheck(BST_UNCHECKED); ra321.SetCheck(BST_UNCHECKED);
}
return TRUE;
}
HBRUSH CDlg4::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
if (pWnd->GetDlgCtrlID() == IDC_STA31 || pWnd->GetDlgCtrlID() == IDC_STA32 || pWnd->GetDlgCtrlID() == IDC_STA33 || pWnd->GetDlgCtrlID() == IDC_STA34
|| pWnd->GetDlgCtrlID() == IDC_STA305 || pWnd->GetDlgCtrlID() == IDC_STA306)
{
pDC->SetBkColor(BkColor); pDC->SetTextColor(TextColor);
return (HBRUSH)brush1;
}
if (pWnd->GetDlgCtrlID() == IDC_EDIT31 || pWnd->GetDlgCtrlID() == IDC_STA331 || pWnd->GetDlgCtrlID() == IDC_STA332)
{
pDC->SetBkColor(RGB(70, 70, 70)); pDC->SetTextColor(TextColor);
return (HBRUSH)brush2;
}
return hbr;
}
void CDlg4::OnBnClickedButton3a1()//“默认”按钮单击响应函数
{
edit31.SetWindowText(L"使用默认值");
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->VIDEO_BIT_RATE = 0;//设置VIDEO_BIT_RATE=0,将使用默认比特率
}
void CDlg4::OnBnClickedButton311()//“录制选定区域”单选按钮
{
ra311.SetCheck(BST_CHECKED);
ra312.SetCheck(BST_UNCHECKED);
ra313.SetCheck(BST_UNCHECKED);
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->sta3.SetWindowText(L"录制区域");
pDlg->Index = 0;//录制方法索引置0
pDlg->btn9.ShowWindow(SW_HIDE);
pDlg->btn10.ShowWindow(SW_HIDE);
theApp.FrameDlg.ShowWindow(SW_SHOW);
OnBnClickedButton317();//“显示控制窗口”单选按钮
theApp.FrameDlg.GetClientRect(pDlg->SelRect); theApp.FrameDlg.ClientToScreen(pDlg->SelRect);
}
void CDlg4::OnBnClickedButton312()//“录制工作区”单选按钮
{
ra312.SetCheck(BST_CHECKED);
ra311.SetCheck(BST_UNCHECKED);
ra313.SetCheck(BST_UNCHECKED);
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->sta3.SetWindowText(L"录制工作区");
pDlg->Index = 1;//录制方法索引置1
pDlg->btn9.ShowWindow(SW_SHOW);
pDlg->btn10.ShowWindow(SW_SHOW);
theApp.FrameDlg.ShowWindow(SW_HIDE);//隐藏选区窗口
SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID)&pDlg->PM_rect, 0);//获取工作区矩形
}
void CDlg4::OnBnClickedButton313()//”录制全屏”单选按钮
{
ra313.SetCheck(BST_CHECKED);
ra311.SetCheck(BST_UNCHECKED);
ra312.SetCheck(BST_UNCHECKED);
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->sta3.SetWindowText(L"录制全屏");
pDlg->Index = 2;//录制方法索引置2
pDlg->btn9.ShowWindow(SW_SHOW);
pDlg->btn10.ShowWindow(SW_SHOW);
theApp.FrameDlg.ShowWindow(SW_HIDE);//隐藏选区窗口
}
void CDlg4::OnBnClickedButton317()//“显示控制窗口”单选按钮
{
ra317.SetCheck(BST_CHECKED);
ra318.SetCheck(BST_UNCHECKED);
ra319.SetCheck(BST_UNCHECKED);
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->ShowWindow(SW_RESTORE);//显示控制窗口
SetWindowPos(&CWnd::wndTop, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);//将设置窗口置顶
}
void CDlg4::OnBnClickedButton318()//“最小化控制窗口”单选按钮
{
ra318.SetCheck(BST_CHECKED);
ra317.SetCheck(BST_UNCHECKED);
ra319.SetCheck(BST_UNCHECKED);
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->ShowWindow(SW_MINIMIZE);//最小化控制窗口
ShowWindow(SW_SHOW);
theApp.FrameDlg.ShowWindow(SW_HIDE);//隐藏选区窗口
}
void CDlg4::OnBnClickedButton319()//”隐藏控制窗口”单选按钮
{
ra319.SetCheck(BST_CHECKED);
ra317.SetCheck(BST_UNCHECKED);
ra318.SetCheck(BST_UNCHECKED);
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->ShowWindow(SW_HIDE);//隐藏控制窗口
theApp.FrameDlg.ShowWindow(SW_HIDE);//隐藏选区窗口
}
void CDlg4::OnBnClickedButton320()//“输出MP4”单选按钮
{
ra320.SetCheck(BST_CHECKED);
ra321.SetCheck(BST_UNCHECKED);
ra322.SetCheck(BST_UNCHECKED);
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->ExName = L".mp4";
}
void CDlg4::OnBnClickedButton321()//“输出WMV”单选按钮
{
ra321.SetCheck(BST_CHECKED);
ra320.SetCheck(BST_UNCHECKED);
ra322.SetCheck(BST_UNCHECKED);
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->ExName = L".wmv";
}
void CDlg4::OnBnClickedButton322()//“输出ASF”单选按钮
{
ra322.SetCheck(BST_CHECKED);
ra320.SetCheck(BST_UNCHECKED);
ra321.SetCheck(BST_UNCHECKED);
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->ExName = L".asf";
}
void CDlg4::OnCbnSelchangeCombo31()//帧率组合框选择改变
{
int Sel = combox31.GetCurSel();
if (Sel != -1)
{
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->VIDEO_FPS = 30 - Sel;
}
}
void CDlg4::OnEnChangeEdit31()//比特率编辑框文本改变
{
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
pDlg->VIDEO_BIT_RATE = GetDlgItemInt(IDC_EDIT31);
}
Frame.h
#pragma once
#include "Dlg2.h"
// CFrame 对话框
class CFrame : public CDialogEx
{
DECLARE_DYNAMIC(CFrame)
public:
CFrame(CWnd* pParent = NULL); // 标准构造函数
virtual ~CFrame();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG1 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedOk();
virtual BOOL PreTranslateMessage(MSG* pMsg);
HBRUSH hBrush;
CDlg2 dlg2;//用作显示选定区域大小提示窗口
static VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);//计时器回调函数声明
virtual BOOL OnInitDialog();
afx_msg void OnNcPaint();
afx_msg void OnExitSizeMove();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSizing(UINT fwSide, LPRECT pRect);
int vB, hB;
};
Frame.cpp
// Frame.cpp : 实现文件
//
#include "stdafx.h"
#include "屏幕录像.h"
#include "Frame.h"
#include "afxdialogex.h"
#include "屏幕录像Dlg.h"
IMPLEMENT_DYNAMIC(CFrame, CDialogEx)
CFrame::CFrame(CWnd* pParent /*=NULL*/) : CDialogEx(IDD_DIALOG1, pParent)
{
}
CFrame::~CFrame()
{
}
void CFrame::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CFrame, CDialogEx)
ON_BN_CLICKED(IDOK, &CFrame::OnBnClickedOk)
ON_WM_NCPAINT()
ON_WM_EXITSIZEMOVE()
ON_WM_CREATE()
ON_WM_SIZING()
END_MESSAGE_MAP()
void CFrame::OnBnClickedOk()
{
}
BOOL CFrame::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)//阻止ESC键关闭窗口
{
return TRUE;
}
return CDialogEx::PreTranslateMessage(pMsg);
}
VOID CALLBACK CFrame::TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)//计时器回调函数定义
{
CFrame* pCFrame = (CFrame*)FromHandle(hwnd);
CRect rect;
pCFrame->GetWindowRect(rect);
rect.MoveToXY(0, 0);
CDC* pDC = pCFrame->GetWindowDC();
pDC->FillRect(rect, &CBrush(RGB(255, 0, 0)));
pCFrame->ReleaseDC(pDC);
}
BOOL CFrame::OnInitDialog()
{
CDialogEx::OnInitDialog();
hBrush = ::CreateSolidBrush(RGB(255, 0, 0));
SetTimer(0, 30, &TimerProc);
CRect Rect, rect;
GetWindowRect(Rect); GetClientRect(rect);
hB = Rect.Width() - rect.Width();
vB = Rect.Height() - rect.Height();
return TRUE;
}
void CFrame::OnNcPaint()
{
CRect FrameRect;
GetWindowRect(FrameRect);
int x = FrameRect.left; int y = FrameRect.top;
FrameRect.OffsetRect(-x, -y);
CRect ClientRect;
GetClientRect(ClientRect);
ClientToScreen(ClientRect);
ClientRect.OffsetRect(-x, -y);
CRgn r1, r2, R;
r2.CreateRectRgnIndirect(FrameRect);
r1.CreateRectRgnIndirect(ClientRect);
R.CreateRectRgn(0, 0, 0, 0);
R.CombineRgn(&r2, &r1, RGN_DIFF);
SetWindowRgn(R.operator HRGN(), 0);
}
int CFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialogEx::OnCreate(lpCreateStruct) == -1)
return -1;
dlg2.Create(IDD_DIALOG2);
return 0;
}
void CFrame::OnExitSizeMove()
{
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
CRect Rect;
pDlg->GetWindowRect(Rect);//获取控制窗口矩形
CRect rect;
GetWindowRect(rect);//获取选区窗口矩形
pDlg->Left = rect.left - Rect.left;
GetClientRect(pDlg->SelRect); ClientToScreen(pDlg->SelRect);
if (pDlg->SelRect.Width() % 4 != 0)//如果选区宽度不是4的倍数
{
int xAdd = 4 - pDlg->SelRect.Width() % 4;//计算宽度应添加的值
rect.right += xAdd;
Rect.right += xAdd;
}
if (pDlg->SelRect.Height() % 4 != 0)//如果选区高度不是4的倍数
{
int yAdd = 4 - pDlg->SelRect.Height() % 4;//计算高度应添加的值
rect.bottom += yAdd;
}
MoveWindow(rect);//按新矩形设置选区窗口位置
GetClientRect(pDlg->SelRect); ClientToScreen(pDlg->SelRect);
pDlg->MoveWindow(Rect);//按新矩形设置控制窗口位置
pDlg->RedrawWindow();
dlg2.ShowWindow(SW_HIDE);
CDialogEx::OnExitSizeMove();
}
void CFrame::OnSizing(UINT fwSide, LPRECT pRect)
{
CDialogEx::OnSizing(fwSide, pRect);
int W = pRect->right- pRect->left-hB, H = pRect->bottom- pRect->top-vB;
if (W % 4 != 0)//如果选区宽度不是4的倍数
{
W = (W / 4) * 4 + 4;//将宽度进行4倍取整
}
if (H % 4 != 0)//如果选区高度不是4的倍数
{
H = (H / 4) * 4 + 4;//将高度进行4倍取整
}
CString item1, item2;
item1.Format(L"宽:%d", W); item2.Format(L"高:%d", H);
dlg2.sta21.SetWindowText(item1); dlg2.sta22.SetWindowText(item2);
dlg2.CenterWindow(this);
dlg2.ShowWindow(SW_SHOW);
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
if (pRect->right - pRect->left < pDlg->MinWidth)//限制控制窗口最小宽度428
{
pDlg->RedrawWindow();
return;
}
if (pDlg != NULL)
{
if (pDlg->TOP)//如果控制窗口在上
{
pDlg->MoveWindow(pRect->left, pRect->top - 28, pRect->right - pRect->left, 28);
}
else//如果控制窗口在下
{
pDlg->MoveWindow(pRect->left, pRect->bottom, pRect->right - pRect->left, 28);
}
pDlg->_SetPos();//定位控件
pDlg->ShowTime.RedrawWindow();
pDlg->Run_btn.RedrawWindow();
pDlg->Pause_btn.RedrawWindow();
pDlg->Stop_btn.RedrawWindow();
pDlg->btn9.RedrawWindow();
pDlg->btn10.RedrawWindow();
pDlg->Mo_btn.RedrawWindow();
pDlg->Set_btn.RedrawWindow();
pDlg->End_btn.RedrawWindow();
pDlg->RedrawWindow();
}
}
MyButton.h
#pragma once
// CMyButton
class CMyButton : public CButton
{
DECLARE_DYNAMIC(CMyButton)
public:
CMyButton();
virtual ~CMyButton();
protected:
DECLARE_MESSAGE_MAP()
public:
CFont font;
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};
MyButton.cpp
// MyButton.cpp : 实现文件
//
#include "stdafx.h"
#include "屏幕录像.h"
#include "MyButton.h"
#include "屏幕录像Dlg.h"
// CMyButton
IMPLEMENT_DYNAMIC(CMyButton, CButton)
CMyButton::CMyButton()
{
font.CreatePointFont(80, L"微软雅黑");
}
CMyButton::~CMyButton()
{
}
BEGIN_MESSAGE_MAP(CMyButton, CButton)
END_MESSAGE_MAP()
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
C屏幕录像Dlg* pDlg = (C屏幕录像Dlg*)theApp.m_pMainWnd;
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
CString text; GetWindowText(text);
dc.SetBkColor(RGB(50, 50, 50));
dc.SetTextColor(RGB(142, 142, 142));
dc.SelectObject(&font);
if (lpDrawItemStruct->CtlID == IDC_BUTTON3A1)
{
dc.FillRect(&lpDrawItemStruct->rcItem, &CBrush(RGB(50, 50, 50)));
dc.DrawText(text, &lpDrawItemStruct->rcItem, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
dc.FrameRect(&lpDrawItemStruct->rcItem, &CBrush(RGB(142, 142, 142)));
}
CDC comdc;
comdc.CreateCompatibleDC(&dc);
if (lpDrawItemStruct->CtlID == IDC_BUTTON1)//绘制“运行”按钮
{
CBitmap bmp1, bmp2; BITMAP bitmap;
if (lpDrawItemStruct->itemState & ODS_SELECTED)//绘制按钮按下状态
{
bmp2.LoadBitmap(IDB_BITMAP3);
bmp2.GetBitmap(&bitmap);
comdc.SelectObject(&bmp2);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
else//绘制正常状态
{
bmp1.LoadBitmap(IDB_BITMAP4);
bmp1.GetBitmap(&bitmap);
comdc.SelectObject(&bmp1);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
}
if (lpDrawItemStruct->CtlID == IDC_BUTTON2)//绘制“暂停”按钮
{
CBitmap bmp1, bmp2; BITMAP bitmap;
if (lpDrawItemStruct->itemState & ODS_SELECTED)//绘制按钮按下状态
{
bmp2.LoadBitmap(IDB_BITMAP5);
bmp2.GetBitmap(&bitmap);
comdc.SelectObject(&bmp2);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
else//绘制正常状态
{
bmp1.LoadBitmap(IDB_BITMAP6);
bmp1.GetBitmap(&bitmap);
comdc.SelectObject(&bmp1);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
}
if (lpDrawItemStruct->CtlID == IDC_BUTTON3)//绘制“停止”按钮
{
CBitmap bmp1, bmp2; BITMAP bitmap;
if (lpDrawItemStruct->itemState & ODS_SELECTED)//绘制按钮按下状态
{
bmp2.LoadBitmap(IDB_BITMAP7);
bmp2.GetBitmap(&bitmap);
comdc.SelectObject(&bmp2);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
else//绘制正常状态
{
bmp1.LoadBitmap(IDB_BITMAP8);
bmp1.GetBitmap(&bitmap);
comdc.SelectObject(&bmp1);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
}
if (lpDrawItemStruct->CtlID == IDC_BUTTON4)//绘制“隐藏窗口”按钮
{
CBitmap bmp1, bmp2; BITMAP bitmap;
if (lpDrawItemStruct->itemState & ODS_SELECTED)//绘制按钮按下状态
{
bmp2.LoadBitmap(IDB_BITMAP9);
bmp2.GetBitmap(&bitmap);
comdc.SelectObject(&bmp2);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
else//绘制正常状态
{
bmp1.LoadBitmap(IDB_BITMAP10);
bmp1.GetBitmap(&bitmap);
comdc.SelectObject(&bmp1);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
}
if (lpDrawItemStruct->CtlID == IDC_BUTTON5)//绘制“最小化窗口”按钮
{
CBitmap bmp1, bmp2; BITMAP bitmap;
if (lpDrawItemStruct->itemState & ODS_SELECTED)//绘制按钮按下状态
{
bmp2.LoadBitmap(IDB_BITMAP11);
bmp2.GetBitmap(&bitmap);
comdc.SelectObject(&bmp2);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
else//绘制正常状态
{
bmp1.LoadBitmap(IDB_BITMAP12);
bmp1.GetBitmap(&bitmap);
comdc.SelectObject(&bmp1);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
}
if (lpDrawItemStruct->CtlID == IDC_BUTTON6)//绘制“移动”按钮
{
CBitmap bmp1, bmp2; BITMAP bitmap;
if (pDlg->TOP)//如果控制窗口在上
{
if (lpDrawItemStruct->itemState & ODS_SELECTED)//绘制按钮按下状态
{
bmp2.LoadBitmap(IDB_BITMAP13);
bmp2.GetBitmap(&bitmap);
comdc.SelectObject(&bmp2);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
else//绘制正常状态
{
bmp1.LoadBitmap(IDB_BITMAP14);
bmp1.GetBitmap(&bitmap);
comdc.SelectObject(&bmp1);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
}
else//如果控制窗口在下
{
if (lpDrawItemStruct->itemState & ODS_SELECTED)//绘制按钮按下状态
{
bmp2.LoadBitmap(IDB_BITMAP15);
bmp2.GetBitmap(&bitmap);
comdc.SelectObject(&bmp2);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
else//绘制正常状态
{
bmp1.LoadBitmap(IDB_BITMAP16);
bmp1.GetBitmap(&bitmap);
comdc.SelectObject(&bmp1);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
}
}
if (lpDrawItemStruct->CtlID == IDC_BUTTON7)//绘制“设置”按钮
{
CBitmap bmp1, bmp2; BITMAP bitmap;
if (lpDrawItemStruct->itemState & ODS_SELECTED)//绘制按钮按下状态
{
bmp2.LoadBitmap(IDB_BITMAP17);
bmp2.GetBitmap(&bitmap);
comdc.SelectObject(&bmp2);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
else//绘制正常状态
{
bmp1.LoadBitmap(IDB_BITMAP18);
bmp1.GetBitmap(&bitmap);
comdc.SelectObject(&bmp1);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
}
if (lpDrawItemStruct->CtlID == IDC_BUTTON8)//绘制“退出”按钮
{
CBitmap bmp1, bmp2; BITMAP bitmap;
if (lpDrawItemStruct->itemState & ODS_SELECTED)//绘制按钮按下状态
{
bmp2.LoadBitmap(IDB_BITMAP19);
bmp2.GetBitmap(&bitmap);
comdc.SelectObject(&bmp2);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
else//绘制正常状态
{
bmp1.LoadBitmap(IDB_BITMAP20);
bmp1.GetBitmap(&bitmap);
comdc.SelectObject(&bmp1);
dc.SetStretchBltMode(COLORONCOLOR);
dc.StretchBlt(0, 0, lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom, &comdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
}
dc.Detach();
}
MyComboBox.h
#pragma once
// CMyComboBox
class CMyComboBox : public CComboBox
{
DECLARE_DYNAMIC(CMyComboBox)
public:
CMyComboBox();
virtual ~CMyComboBox();
protected:
DECLARE_MESSAGE_MAP()
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
afx_msg void OnPaint();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
CBrush brush;
};
MyComboBox.cpp
// MyComboBox.cpp : 实现文件
//
#include "stdafx.h"
#include "屏幕录像.h"
#include "MyComboBox.h"
// CMyComboBox
IMPLEMENT_DYNAMIC(CMyComboBox, CComboBox)
CMyComboBox::CMyComboBox()
{
brush.CreateSolidBrush(RGB(70, 70, 70));
}
CMyComboBox::~CMyComboBox()
{
}
BEGIN_MESSAGE_MAP(CMyComboBox, CComboBox)
ON_WM_DRAWITEM()
ON_WM_PAINT()
ON_WM_CTLCOLOR()
END_MESSAGE_MAP()
void CMyComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CString str;
if (lpDrawItemStruct->itemID != -1)
GetLBText(lpDrawItemStruct->itemID, str);//获取项的文本
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
COLORREF crOldTextColor = dc.GetTextColor();
COLORREF crOldBkColor = dc.GetBkColor();//获取dc原来的文本和背景颜色
dc.SetTextColor(RGB(142, 142, 142));//设置文本颜色
dc.SetBkMode(TRANSPARENT);//设置背景透明
dc.FillSolidRect(&lpDrawItemStruct->rcItem, RGB(70, 70, 70));
if (lpDrawItemStruct->itemState & ODS_SELECTED)//绘制选中项
{
dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
dc.FillSolidRect(&lpDrawItemStruct->rcItem, ::GetSysColor(COLOR_HIGHLIGHT));
}
dc.DrawText(str, &lpDrawItemStruct->rcItem, DT_SINGLELINE | DT_VCENTER);//绘制项文本
dc.SetTextColor(crOldTextColor);
dc.SetBkColor(crOldBkColor);//恢复原来的文本和背景颜色
dc.Detach();
}
void CMyComboBox::OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
dc.FillSolidRect(&rect, RGB(70, 70, 70));//绘制组合框背景
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP23);
BITMAP bitmap;
bmp.GetBitmap(&bitmap);
CDC comDC;
comDC.CreateCompatibleDC(&dc);
comDC.SelectObject(&bmp);
COMBOBOXINFO info;
info.cbSize = sizeof(COMBOBOXINFO);
GetComboBoxInfo(&info);
dc.SetStretchBltMode(COLORONCOLOR);//设置拉伸模式
switch (info.stateButton)
{
case 0://绘制组合框按钮未按下状态
dc.StretchBlt(info.rcButton.left, info.rcButton.top, info.rcButton.right - info.rcButton.left, info.rcButton.bottom - info.rcButton.top, &comDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
break;
case STATE_SYSTEM_PRESSED://绘制组合框按钮按下状态
dc.StretchBlt(info.rcButton.left, info.rcButton.top, info.rcButton.right - info.rcButton.left, info.rcButton.bottom - info.rcButton.top, &comDC, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
break;
}
}
HBRUSH CMyComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_EDIT)
{
pDC->SetTextColor(RGB(142, 142, 142));//设置组合框编辑窗口文本颜色
pDC->SetBkMode(TRANSPARENT);//设置组合框编辑窗口文本背景透明
return (HBRUSH)brush;//绘制编辑窗口背景色
}
return hbr;
}
RABtn.h
#pragma once
// CRABtn
class CRABtn : public CButton
{
DECLARE_DYNAMIC(CRABtn)
public:
CRABtn();
virtual ~CRABtn();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
CFont font;
CPen pen1, pen2;
CBrush brush1, brush2;
};
RABtn.cpp
// RABtn.cpp : 实现文件
//
#include "stdafx.h"
#include "屏幕录像.h"
#include "RABtn.h"
// CRABtn
IMPLEMENT_DYNAMIC(CRABtn, CButton)
CRABtn::CRABtn()
{
font.CreatePointFont(100, L"微软雅黑");
pen1.CreatePen(PS_SOLID | PS_ENDCAP_FLAT, 1, RGB(142, 142, 142));
pen2.CreatePen(PS_SOLID | PS_ENDCAP_FLAT, 1, RGB(0, 0, 0));
brush1.CreateSolidBrush(RGB(142, 142, 142));
brush2.CreateSolidBrush(RGB(142, 42, 42));
}
CRABtn::~CRABtn()
{
}
BEGIN_MESSAGE_MAP(CRABtn, CButton)
ON_WM_PAINT()
END_MESSAGE_MAP()
void CRABtn::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rect;
GetClientRect(rect);
dc.FillSolidRect(rect, RGB(70, 70, 70));
dc.SelectObject(&pen1);
dc.SelectObject(&brush1);
dc.Ellipse(rect.left, rect.top, rect.left + 20, rect.top + 20);
if (GetCheck() == BST_CHECKED)//如果被选中
{
dc.SelectObject(&pen2);
dc.SelectObject(&brush2);
CRect R; R.left = rect.left; R.top = rect.top; R.right = rect.left + 20; R.bottom = rect.top + 20;
R.DeflateRect(2, 2);
dc.Ellipse(R.left, R.top, R.right, R.bottom);
}
CString item;
GetWindowText(item);
dc.SelectObject(&font);
dc.SetTextColor(RGB(142, 142, 142));
dc.SetBkColor(RGB(70, 70, 70));
rect.left += 30;
dc.DrawText(item, rect, DT_SINGLELINE | DT_VCENTER);
}