You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

482 lines
11 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// ShowReplayDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "CH91PayloadSoftware.h"
#include "ShowReplayDlg.h"
#include "afxdialogex.h"
#include "Global.h"
#include "GlobalMessage.h"
// 多媒体定时器
#include "MMSystem.h"
#pragma comment(lib, "winmm")
//timeSetEvent中的回调函数名字随便起但是内容固定
void CALLBACK TimerPlayFunc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
{
// 目的调用ReadandPlay将dwUser强制转换为ptr可以使用ptr格式更加方便
CShowReplayDlg* ptr = reinterpret_cast<CShowReplayDlg*>(dwUser);
// 读取文件并播放
if (ptr != NULL)
{
ptr->ReadAndPlay();
}
}
// CShowReplayDlg 对话框
IMPLEMENT_DYNAMIC(CShowReplayDlg, CDialogEx)
CShowReplayDlg::CShowReplayDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CShowReplayDlg::IDD, pParent)
{
m_TimerID = 0;
m_TimerPeriod = 20; // 默认20ms 调用一次多媒体时钟函数由于EO和IR穿插因此一秒钟调用50次EO和IR帧频各25
m_bFileOpen = FALSE;
m_bIsPlay = FALSE;
m_bPauseSliderReflect = FALSE;
m_bService = FALSE; // 初始情况下后台服务程序未打开
m_bTransParent = FALSE; // 初始情况下不透明
}
CShowReplayDlg::~CShowReplayDlg()
{
}
void CShowReplayDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_SLIDER_REPLAYRATIO, m_SliderReplayRatio);
}
BEGIN_MESSAGE_MAP(CShowReplayDlg, CDialogEx)
ON_BN_CLICKED(IDC_BTN_OPENFILE, &CShowReplayDlg::OnBnClickedBtnOpenfile)
ON_BN_CLICKED(IDC_BTN_FILEPLAYPAUSE, &CShowReplayDlg::OnBnClickedBtnFileplaypause)
ON_BN_CLICKED(IDC_BTN_FILESTOP, &CShowReplayDlg::OnBnClickedBtnFilestop)
ON_BN_CLICKED(IDC_BTN_FILESLOW, &CShowReplayDlg::OnBnClickedBtnFileslow)
ON_BN_CLICKED(IDC_BTN_FILEFAST, &CShowReplayDlg::OnBnClickedBtnFilefast)
ON_CBN_SELCHANGE(IDC_COMBOX_PLAYTYPE, &CShowReplayDlg::OnCbnSelchangeComboxPlaytype)
ON_WM_DESTROY()
ON_MESSAGE(WM_BITMAPSLIDER_MOVING, OnBitmapSliderMoving)
ON_MESSAGE(WM_RETURN_PAYLOAD_TYPE_WARNING, &CShowReplayDlg::ReturnPayloadTypeWarning)
END_MESSAGE_MAP()
// CShowReplayDlg 消息处理程序
BOOL CShowReplayDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
// 键盘消息
if (pMsg->message == WM_KEYDOWN)
{
// 忽略ESC和回车键
if (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)
{
return TRUE;
}
// F1键控制“视频控制”窗口的现实/隐藏
if (pMsg->wParam == VK_F1)
{
// 关闭窗口
OnOK();
}
}
return CDialogEx::PreTranslateMessage(pMsg);
}
BOOL CShowReplayDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置对话框标题
SetWindowText(g_str_TitleReplay);
// 设置文件路径名称
GetDlgItem(IDC_STATIC_HF_FILE_PATH) -> SetWindowText(g_str_FilePath);
//设置回放进度条各参数
m_SliderReplayRatio.SetBitmapChannel( IDB_MP_CHANNEL, IDB_MP_CHANNEL_ACTIVE );
m_SliderReplayRatio.SetBitmapThumb( IDB_MP_THUMB, IDB_MP_THUMB_ACTIVE, TRUE );
m_SliderReplayRatio.DrawFocusRect( FALSE );
m_SliderReplayRatio.SetMargin( 2, 3, 2, 0 );
m_SliderReplayRatio.SetRange(0, 5000);
m_SliderReplayRatio.SetPos(0);
// 获取窗口句柄
g_ReplayDlgHwnd = GetSafeHwnd();
// 工作模式
((CComboBox*)GetDlgItem(IDC_COMBOX_PLAYTYPE))->AddString("回放");
((CComboBox*)GetDlgItem(IDC_COMBOX_PLAYTYPE))->AddString("实时");
((CComboBox*)GetDlgItem(IDC_COMBOX_PLAYTYPE))->SetCurSel(1);
OnCbnSelchangeComboxPlaytype();
// 设置界面按钮
// 打开文件
m_Btn_OpenFile.SubclassDlgItem(IDC_BTN_OPENFILE, this);
m_Btn_OpenFile.SetIcon(IDI_ICON_OPENFILE);
m_Btn_OpenFile.DrawTransparent(TRUE);
m_Btn_OpenFile.SetTooltipText("文件");
m_Btn_OpenFile.DrawBorder(FALSE);
// 开始/暂停
m_Btn_PlayPause.SubclassDlgItem(IDC_BTN_FILEPLAYPAUSE, this);
m_Btn_PlayPause.SetIcon(IDI_ICON_PLAY);
m_Btn_PlayPause.DrawTransparent(TRUE);
m_Btn_PlayPause.SetTooltipText("开始/暂停");
m_Btn_PlayPause.DrawBorder(FALSE);
// 停止
m_Btn_Stop.SubclassDlgItem(IDC_BTN_FILESTOP, this);
m_Btn_Stop.SetIcon(IDI_ICON_STOP);
m_Btn_Stop.DrawTransparent(TRUE);
m_Btn_Stop.SetTooltipText("停止");
m_Btn_Stop.DrawBorder(FALSE);
// 加速
m_Btn_SpeedUp.SubclassDlgItem(IDC_BTN_FILEFAST, this);
m_Btn_SpeedUp.SetIcon(IDI_ICON_SPEEDUP);
m_Btn_SpeedUp.DrawTransparent(TRUE);
m_Btn_SpeedUp.SetTooltipText("加速");
m_Btn_SpeedUp.DrawBorder(FALSE);
// 减速
m_Btn_SpeedDown.SubclassDlgItem(IDC_BTN_FILESLOW, this);
m_Btn_SpeedDown.SetIcon(IDI_ICON_SPEEDDOWN);
m_Btn_SpeedDown.DrawTransparent(TRUE);
m_Btn_SpeedDown.SetTooltipText("减速");
m_Btn_SpeedDown.DrawBorder(FALSE);
// 设置播放比率初始值
GetDlgItem(IDC_STATIC_REPLAY_RATIO)->SetWindowText(_T("0%"));
return TRUE;
}
// 打开回放视频文件
void CShowReplayDlg::OnBnClickedBtnOpenfile()
{
// 首先停止播放视频
OnBnClickedBtnFilestop();
// 打开文件夹
CFileDialog Dialog(
TRUE,
NULL,
NULL,
OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
_T("Video Files (*.tx) |*.tx| All Files (*.*) |*.*||"),
NULL);
Dialog.m_ofn.lpstrTitle = _T("Open Files");
if (Dialog.DoModal()!=IDOK)
{
return;
}
if (m_bIsPlay == FALSE)
{
m_HFfilePath = Dialog.GetPathName();
// 显示文件路径
GetDlgItem(IDC_STATIC_HF_FILE_PATH)->SetWindowText(g_str_FilePath + m_HFfilePath);
}
else
{
}
}
//启动定时器——多媒体定时器,与
void CShowReplayDlg::StartTimer()
{
// 启动定时器回调函数TimerPlayFunc固定格式只需编译回调函数TimerPlayFunc
m_TimerID = timeSetEvent(m_TimerPeriod, 1, TimerPlayFunc, (DWORD_PTR)this, TIME_PERIODIC);
}
//停止定时器
void CShowReplayDlg::StopTimer()
{
if (m_TimerID != 0)
{
timeKillEvent(m_TimerID);
m_TimerID = 0;
}
}
// 播放及暂停视频
void CShowReplayDlg::OnBnClickedBtnFileplaypause()
{
if (m_bFileOpen == FALSE)
{
// 显示文件名之后打开文件,获取文件长度,文件内容当前进度以及文件
if (m_ReplayFile.Open(m_HFfilePath, CFile::modeRead) == TRUE)
{
m_bFileOpen = TRUE;
m_FileInfo.FileTotalLen = m_ReplayFile.GetLength(); // 获取文件长度
m_FileInfo.curFilePos = 0; //获取文件当前内容位置为0
m_FileInfo.FrameLen = 1024;//1024; //设定读取一帧的字节大小10KB
}
else
{
return;
}
}
if (m_bFileOpen == TRUE)
{
//如果没有播放
if (m_bIsPlay == FALSE)
{
// 如果上一次定时器(或者其他情况下)处于意外没有停止,则停止当前定时器
if (m_TimerID != 0)
{
timeKillEvent(m_TimerID);
m_TimerID = 0;
}
m_bIsPlay = TRUE;
//设定新的定时器,并用定时器调用读取每一帧进行播放
StartTimer();
//GetDlgItem(IDC_BTN_FILEPLAYPAUSE)->SetWindowTextA("暂停");
m_Btn_PlayPause.SetIcon(IDI_ICON_PAUSE);
}
//如果正在播放,则暂停
else
{
if (m_TimerID != 0)
{
timeKillEvent(m_TimerID);
m_TimerID = 0;
}
m_bIsPlay = FALSE;
g_bEOImgUpdate = FALSE;
g_bIRImgUpdate = FALSE;
//GetDlgItem(IDC_BTN_FILEPLAYPAUSE)->SetWindowTextA("播放");
m_Btn_PlayPause.SetIcon(IDI_ICON_PLAY);
}
}
g_bReplayPlay = m_bIsPlay;
}
//读文件并播放在TimerPlayFunc中调用
void CShowReplayDlg::ReadAndPlay()
{
//如果正在播放且滑动条没有暂停相应
if(m_bIsPlay == TRUE && m_bPauseSliderReflect == FALSE)
{
if (m_bFileOpen == FALSE)
{
return;
}
int readLen = 0;
//时钟设定之后,每次调用函数,每次顺次读一下文件
readLen = m_ReplayFile.Read(m_FileInfo.Buffer, m_FileInfo.FrameLen);
//当前文件位置
m_FileInfo.curFilePos += readLen;
// 判断是否已到文件结尾
if(m_FileInfo.curFilePos < m_FileInfo.FileTotalLen)
{
// 输出原始数据
ReplayInputData(m_FileInfo.Buffer, readLen);
// 输出播放百分比
double ratio = 0.0;
ratio = m_FileInfo.curFilePos * 1.0 / m_FileInfo.FileTotalLen;
int rangeMax = m_SliderReplayRatio.GetRangeMax();
int currentPos = static_cast<int>(ratio * rangeMax + 0.5); // int类型强制转换为向下取整加上0.5可以保证取整时四舍五入
m_bPauseSliderReflect = TRUE; // 暂停滑动条响应
m_SliderReplayRatio.SetPos(currentPos);
CString str;
str.Format("%.1f", ratio * 100);
str = str + "%";
/* UpdateData(TRUE);*/
GetDlgItem(IDC_STATIC_REPLAY_RATIO)->SetWindowText(str);
m_bPauseSliderReflect = FALSE; // 所有关于输出百分比设置的事情结束之后,开始滑动条响应
}
else
{
}
}
}
// 设置回放进度
void CShowReplayDlg::SetFileReplayRatio(double ratio)
{
if (ratio < 0 || ratio > 1)
{
return;
}
else
{
if (m_bFileOpen == TRUE)
{
// 计算文件大小
m_FileInfo.curFilePos = ULONGLONG(m_FileInfo.FileTotalLen * ratio);
m_ReplayFile.Seek(LONGLONG(m_FileInfo.curFilePos), CFile::begin);
}
}
}
// 拖动滑动条响应函数
LRESULT CShowReplayDlg::OnBitmapSliderMoving(WPARAM wParam, LPARAM lParam)
{
if (m_bPauseSliderReflect == FALSE)
{
// 滑动条暂停响应
m_bPauseSliderReflect = TRUE;
// 确定当前读取文件位置
int pos = m_SliderReplayRatio.GetPos();
int rangeMax = m_SliderReplayRatio.GetRangeMax();
double ratio = pos * 1.0 / rangeMax;
SetFileReplayRatio(ratio);
// 滑动条开始响应
m_bPauseSliderReflect = FALSE;
}
return 0;
}
// 停止播放
void CShowReplayDlg::OnBnClickedBtnFilestop()
{
if (g_bWorkMode == true)
{
StopTimer();
// 读取图像缓存清零
if (m_bFileOpen == TRUE)
{
m_ReplayFile.Close();
m_bFileOpen = FALSE;
m_FileInfo.ClearStru();
}
m_bIsPlay = FALSE;
Sleep(20);
// 播放进度条复位
m_SliderReplayRatio.SetPos(0);
// 播放比率置零
GetDlgItem(IDC_STATIC_REPLAY_RATIO)->SetWindowText(_T("0%"));
//GetDlgItem(IDC_BTN_FILEPLAYPAUSE)->SetWindowTextA("播放");
m_Btn_PlayPause.SetIcon(IDI_ICON_PLAY);
// ::PostMessage(g_mainDlgHwnd, WM_SHOW_STOP, 0, 0);
}
}
// 减速——通过设定每帧字节的大小来控制播放的快慢
void CShowReplayDlg::OnBnClickedBtnFileslow()
{
if(m_bFileOpen == TRUE && m_bIsPlay == TRUE)
{
if ((m_FileInfo.FrameLen - 1024) >= g_MinReadLen)
{
m_FileInfo.FrameLen = m_FileInfo.FrameLen - 1024;
}
else
{
m_FileInfo.FrameLen = g_MinReadLen;
}
}
}
// 加速——通过设定每帧字节的大小来控制播放的快慢
void CShowReplayDlg::OnBnClickedBtnFilefast()
{
if(m_bFileOpen == TRUE && m_bIsPlay == TRUE)
{
if (m_FileInfo.FrameLen + 1024 <= g_MaxReadLen)
{
m_FileInfo.FrameLen = m_FileInfo.FrameLen + 1024;
}
else
{
m_FileInfo.FrameLen = g_MaxReadLen;
}
}
}
void CShowReplayDlg::OnCbnSelchangeComboxPlaytype()
{
int state = ((CComboBox*)GetDlgItem(IDC_COMBOX_PLAYTYPE))->GetCurSel();
// 视频回放功能
if (state == 0)
{
g_bWorkMode = true; // 回放
GetDlgItem(IDC_BTN_OPENFILE)->EnableWindow(TRUE);
GetDlgItem(IDC_BTN_FILEPLAYPAUSE)->EnableWindow(TRUE);
GetDlgItem(IDC_BTN_FILESTOP)->EnableWindow(TRUE);
GetDlgItem(IDC_BTN_FILESLOW)->EnableWindow(TRUE);
GetDlgItem(IDC_BTN_FILEFAST)->EnableWindow(TRUE);
}
// 实时接收数据显示功能
else
{
// 停止文件回放
OnBnClickedBtnFilestop();
GetDlgItem(IDC_BTN_OPENFILE)->EnableWindow(FALSE);
GetDlgItem(IDC_BTN_FILEPLAYPAUSE)->EnableWindow(FALSE);
GetDlgItem(IDC_BTN_FILESTOP)->EnableWindow(FALSE);
GetDlgItem(IDC_BTN_FILESLOW)->EnableWindow(FALSE);
GetDlgItem(IDC_BTN_FILEFAST)->EnableWindow(FALSE);
g_bWorkMode = false; // 实时
}
}
void CShowReplayDlg::OnDestroy()
{
CDialogEx::OnDestroy();
// 停止文件回放
OnBnClickedBtnFilestop();
}
// 判断进程是否正在运行函数 返回0说明没有运行
DWORD CShowReplayDlg::GetProcessIdFromName(LPCTSTR name)
{
PROCESSENTRY32 pe;
DWORD id = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe.dwSize = sizeof(PROCESSENTRY32);
if( !Process32First(hSnapshot,&pe) )
return 0;
while(1)
{
pe.dwSize = sizeof(PROCESSENTRY32);
if( Process32Next(hSnapshot,&pe)==FALSE )
break;
if(strcmp(pe.szExeFile,name) == 0)
{
id = pe.th32ProcessID;
break;
}
}
CloseHandle(hSnapshot);
return id;
}
LRESULT CShowReplayDlg::ReturnPayloadTypeWarning(WPARAM wParam, LPARAM lParam)
{
UpdateData(FALSE);
return 0;
}