DirectShow应用-屏幕录像

下载本应用
本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);
}


下载本应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

h3974

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值