瀏覽代碼

#IQBX #comment libimgplayer 编译通过

80374374 1 年之前
父節點
當前提交
577eec381b

+ 375 - 0
Other/win/libimgplayer/CImgPlayerDlg.cpp

@@ -0,0 +1,375 @@
+
+// CImgPlayerDlg.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "libimgplayer.h"
+#include "CImgPlayerDlg.h"
+#include "afxdialogex.h"
+#include <io.h>
+
+#define TIMERID 8
+
+CImgPlayerDlg::CImgPlayerDlg(CWnd* pParent /*=NULL*/)
+	: CDialogEx(CImgPlayerDlg::IDD, pParent), m_pConfig(NULL)
+{
+	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+	m_bInit = false;
+	m_bTimer = false;
+	m_hMonitor = NULL;
+
+	m_nPicInx = 0;
+	m_nPlayCnt = 0;
+
+	m_pMemDC = new CDC();
+	m_pMemBitmap = new CBitmap();
+	m_pOldBitmap = NULL;
+}
+
+CImgPlayerDlg::CImgPlayerDlg(CImgPlayConfig *pConfig, CWnd* pParent /*= NULL*/)
+	: CDialogEx(CImgPlayerDlg::IDD, pParent), m_pMemDC(NULL), m_pMemBitmap(NULL)
+{
+	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+	m_bInit = false;
+	m_bTimer = false;
+	m_hMonitor = NULL;
+	m_pConfig = pConfig;
+
+	m_nPicInx = 0;
+	m_nPlayCnt = 0;
+
+	m_pMemDC = new CDC();
+	m_pMemBitmap = new CBitmap();
+	m_pOldBitmap = NULL;
+}
+
+CImgPlayerDlg::~CImgPlayerDlg()
+{
+	delete m_pMemBitmap; m_pMemBitmap = NULL;
+	delete m_pMemDC;  m_pMemBitmap = NULL;
+}
+
+void CImgPlayerDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+void CImgPlayerDlg::ShowImage(CImage& img, UINT ID)
+{	
+	// 获得显示控件的DC
+	CDC* pDC = m_pMemDC;
+	// 获取HDC(设备句柄)来进行绘图操作
+	HDC hDC = pDC->GetSafeHdc();
+
+	CRect rect;
+	GetDlgItem(ID)->GetClientRect(&rect);
+	// 读取图片控件的宽和高
+	int rw = rect.right-rect.left;
+	int rh = rect.bottom-rect.top;
+	// 设置图片控件背景色为黑色
+	CBrush brush(RGB(0,0,0));
+	pDC->FillRect(CRect(0, 0, rw, rh), &brush);
+
+	// 读取图片的宽和高
+	int iw = img.GetWidth();
+	int ih = img.GetHeight();
+	// 图片左上角在图片控件中的坐标
+	int tx = 0;
+	int ty = 0;
+	// 图片绘制时的宽和高
+	int nw = iw;
+	int nh = ih;
+
+	if (iw <= rw && ih <= rh)
+	{
+		float scale_x = (float) rw / iw;
+		float scale_y = (float) rh / ih;
+		float scale = scale_x - scale_y >= 1e-6? scale_y : scale_x;
+
+		nw = (int)(iw * scale);
+		nh = (int)(ih * scale);
+
+		tx = (scale_x-scale_y >= 1e-6) ? (int)(rw-nw)/2 : 0;
+		ty = (scale_x-scale_y >= 1e-6) ? 0 : (int)(rw-nw)/2;
+	}
+	else
+	{
+		// 计算横向和纵向缩放因子
+		float scale_x = (float)iw / rw;
+		float scale_y = (float)ih / rh;
+		float scale;
+		if (scale_x-scale_y >= 1e-6)
+			scale = scale_x;
+		else
+			scale = scale_y;
+		
+		// 缩放后图片的宽和高
+		nw = (int)(iw/scale);
+		nh = (int)(ih/scale);
+		
+		// 缩放后的图片在m_Image的正中部位绘制,计算图片左上角在m_Image中的坐标
+		tx = (scale_x-scale_y >= 1e-6) ? 0 : (int)(rw-nw)/2;
+		ty = (scale_x-scale_y >= 1e-6) ? (int)(rh-nh)/2 : 0;
+	}
+
+	SetRect(&rect, tx, ty, tx+nw, ty+nh);
+	// 将图片绘制到显示控件的指定区域
+	SetStretchBltMode(hDC, HALFTONE); // 保持原有图片质量
+	SetBrushOrgEx(hDC, 0, 0, NULL);	// 设置刷子的起始点
+	img.Draw(hDC,rect);
+
+	brush.DeleteObject();
+	//ReleaseDC(pDC);
+
+
+	m_Image.Destroy(); //主动释放位图资源 相当于对Detach返回的结果执行DeleteObject
+
+	pDC = GetDlgItem(ID)->GetDC();
+	GetDlgItem(ID)->GetClientRect(&rect);
+	pDC->BitBlt(0, 0, rect.Width(), rect.Height(), m_pMemDC, 0, 0, SRCCOPY);
+	//DeleteObject(m_pMemBitmap);
+	ReleaseDC(pDC);
+}
+
+BEGIN_MESSAGE_MAP(CImgPlayerDlg, CDialogEx)
+	ON_WM_PAINT()
+	ON_WM_QUERYDRAGICON()
+	ON_WM_SIZE()
+	ON_WM_CLOSE()
+	ON_WM_TIMER()
+	ON_WM_ERASEBKGND()
+END_MESSAGE_MAP()
+
+
+// CImgPlayerDlg 消息处理程序
+
+BOOL CImgPlayerDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
+	//  执行此操作
+	SetIcon(m_hIcon, TRUE);			// 设置大图标
+	SetIcon(m_hIcon, FALSE);		// 设置小图标
+
+	long ScreenWidth = GetSystemMetrics(SM_CXSCREEN);  //主屏幕宽度
+	long ScreenHeight = GetSystemMetrics(SM_CYSCREEN); //主屏幕高度
+		
+	MONITORINFOEX mix;
+	mix.cbSize = sizeof(mix);
+	if (m_pConfig->bPrimMonitor == false) // 默认情况,在副屏显示
+	{
+		POINT pt;
+		pt.x = ScreenWidth+5;
+		pt.y = 5;
+		m_hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL); //尝试获取副屏的句柄
+		if (m_hMonitor != NULL)
+		{
+			GetMonitorInfo(m_hMonitor, (LPMONITORINFO)&mix);
+			SetRect(&m_monitorRect, mix.rcMonitor.left, mix.rcMonitor.top, mix.rcMonitor.right, mix.rcMonitor.bottom);
+		}
+		else
+		{
+			OnCancel();
+			return FALSE;
+		}
+	}
+	else // 在主屏显示
+	{
+		m_hMonitor = MonitorFromWindow(this->GetSafeHwnd(), MONITOR_DEFAULTTONULL);
+		GetMonitorInfo(m_hMonitor, (LPMONITORINFO)&mix);
+		SetRect(&m_monitorRect, mix.rcMonitor.left, mix.rcMonitor.top, mix.rcMonitor.right, mix.rcMonitor.bottom);
+	}
+
+	// TODO: 在此添加额外的初始化代码
+	m_bInit = true;
+
+	// 去掉标题栏和边框
+	ModifyStyle(WS_CAPTION, 0, 0);
+	ModifyStyleEx(WS_EX_DLGMODALFRAME, 0, 0);
+
+	if (m_pConfig->bFullScreen == true)
+	{
+		//ShowWindow(SW_MAXIMIZE);	// 设置窗口最大化
+		::SetWindowPos(this->GetSafeHwnd(),HWND_TOP,m_monitorRect.left,m_monitorRect.top,
+			m_monitorRect.Width(),m_monitorRect.Height(),SWP_SHOWWINDOW); //设置窗口的位置和大小
+	}
+	else
+	{
+		if (m_pConfig->nWndWidth > m_monitorRect.Width())
+		{
+			m_pConfig->nWndWidth = m_monitorRect.Width();
+		}
+		if (m_pConfig->nWndHeight > m_monitorRect.Height())
+		{
+			m_pConfig->nWndHeight = m_monitorRect.Height();
+		}
+		::SetWindowPos(this->GetSafeHwnd(),HWND_TOP,m_monitorRect.left+m_pConfig->nWndX,m_monitorRect.top+m_pConfig->nWndY,
+			m_pConfig->nWndWidth,m_pConfig->nWndHeight,SWP_SHOWWINDOW); //设置窗口的位置和大小
+	}
+
+	CRect rect;
+
+	this->GetClientRect(&rect);
+	
+	//使PictureControl填充整个窗口,超出窗口并增加宽高各1个像素,以隐藏PictureControl的边框(注意控件是相对于窗口的)
+	::SetWindowPos(GetDlgItem(IDC_ShowImg)->GetSafeHwnd(),HWND_TOP,-1,-1,
+		rect.Width()+2,rect.Height()+2,SWP_SHOWWINDOW);
+	
+	::GetWindowRect(GetDlgItem(IDC_ShowImg)->GetSafeHwnd(), &rect); // 计算PictureControl的屏幕坐标
+	//this->ScreenToClient(&rect); // 转换到相对于Dialog客户区的坐标
+	//int borderWidth = -rect.left; // 计算边框的厚度
+
+	// 双缓冲机制
+	int x = rect.Width();
+	int y = rect.Height();
+	CDC *pDC = GetDlgItem(IDC_ShowImg)->GetDC();
+	m_pMemDC->CreateCompatibleDC(pDC); // 依附图片控件DC创建兼容内存DC
+	m_pMemBitmap->CreateCompatibleBitmap(pDC, x, y); // 创建兼容位图
+	m_pOldBitmap = m_pMemDC->SelectObject(m_pMemBitmap); // 将位图选进内存DC,原位图保存到m_pOldBitmap
+	ReleaseDC(pDC);
+	DeleteObject(m_pOldBitmap);
+
+	// 加载并显示第一张图片
+	if (m_pConfig->nFileCnt > 0)
+	{
+		CString imgPath;
+		imgPath.Format(_T("%s%s"),m_pConfig->strRootPath,m_pConfig->strFileNames[0]);
+		// 判断文件是否存在
+		if (_access(LPCTSTR(imgPath), 0) != -1)
+		{
+			HRESULT hRet = m_Image.Load(LPCTSTR(imgPath));
+			if (S_OK == hRet){
+				ShowImage(m_Image, IDC_ShowImg);
+			}
+		}
+	}
+
+	// 每m_nPlayInterval毫秒显示下一张图片
+	if (m_pConfig->nFileCnt > 1)
+	{
+		if (m_pConfig->nPlayInterval <= 1000)
+		{
+			m_pConfig->nPlayInterval = 1000;
+		}
+		SetTimer(TIMERID, m_pConfig->nPlayInterval, 0);
+		m_bTimer = true;
+	}
+
+	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
+}
+
+// 如果向对话框添加最小化按钮,则需要下面的代码
+//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
+//  这将由框架自动完成。
+
+void CImgPlayerDlg::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();
+	}
+}
+
+//当用户拖动最小化窗口时系统调用此函数取得光标
+//显示。
+HCURSOR CImgPlayerDlg::OnQueryDragIcon()
+{
+	return static_cast<HCURSOR>(m_hIcon);
+}
+
+void CImgPlayerDlg::OnSize(UINT nType, int cx, int cy)
+{
+	if (m_bInit == FALSE)
+		return;
+	CDialogEx::OnSize(nType, cx, cy);
+
+	// TODO: 在此处添加消息处理程序代码
+	GetDlgItem(IDC_ShowImg)->MoveWindow(0, 0, cx, cy);
+}
+
+void CImgPlayerDlg::OnClose()
+{
+	// TODO: 在此添加消息处理程序代码和/或调用默认值	
+	CDialogEx::OnClose();
+	EndPlay();
+}
+
+
+void CImgPlayerDlg::OnTimer(UINT_PTR nIDEvent)
+{
+	// TODO: 在此添加消息处理程序代码和/或调用默认值
+	if (nIDEvent == TIMERID)
+	{
+		m_nPicInx = (m_nPicInx+1)%m_pConfig->nFileCnt;
+		if (m_pConfig->nPlayCnt != 0) // 非循环播放
+		{
+			if (m_nPicInx == 0)
+			{
+				m_nPlayCnt++;
+			}
+			if (m_nPlayCnt == m_pConfig->nPlayCnt)//播放次数到了
+			{
+				// 结束播放
+				EndPlay();
+				return;
+			}
+		}
+		CString imgPath;
+		imgPath.Format(_T("%s%s"),m_pConfig->strRootPath,m_pConfig->strFileNames[m_nPicInx]);
+		// 判断文件是否存在
+		if (_access((LPCTSTR)imgPath, 0) != -1)
+		{
+			HRESULT hRet = m_Image.Load(LPCTSTR(imgPath));
+			if (S_OK == hRet){
+				ShowImage(m_Image, IDC_ShowImg);
+			}
+		}
+	}
+	CDialogEx::OnTimer(nIDEvent);
+}
+
+// 屏蔽背景刷新
+BOOL CImgPlayerDlg::OnEraseBkgnd(CDC* pDC)
+{
+	// TODO: 在此添加消息处理程序代码和/或调用默认值
+	return TRUE;
+	//return CDialogEx::OnEraseBkgnd(pDC);
+}
+
+BOOL CImgPlayerDlg::EndPlay()
+{
+	// 停止定时器
+	if (m_bTimer)
+	{
+		KillTimer(TIMERID);
+		m_bTimer = false;
+
+		// 释放绘图对象
+		DeleteObject(m_pMemBitmap);
+		ReleaseDC(m_pMemDC);
+
+	}
+
+	// 关闭窗口
+	EndDialog(IDCANCEL);
+
+	return TRUE;
+}

+ 56 - 0
Other/win/libimgplayer/CImgPlayerDlg.h

@@ -0,0 +1,56 @@
+
+// CImgPlayerDlg.h : 头文件
+//
+
+#pragma once
+#include "libimgplayer.h"
+#include "resource.h"
+
+// CImgPlayerDlg 对话框
+class CImgPlayerDlg : public CDialogEx
+{
+// 构造
+public:
+	CImgPlayerDlg(CWnd* pParent = NULL);	// 标准构造函数
+	CImgPlayerDlg(CImgPlayConfig *pConfig, CWnd* pParent = NULL);
+	~CImgPlayerDlg();
+private:
+	BOOL EndPlay();
+
+// 对话框数据
+	enum { IDD = IDD_IMGPLAYER_DIALOG };
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
+	void ShowImage(CImage& img, UINT ID);
+
+
+// 实现
+protected:
+	HICON m_hIcon;
+	bool m_bInit;//OnInitDialog是否执行结束
+	bool m_bTimer;//计时器是否在执行
+	CImage m_Image;//图像工具
+	HMONITOR m_hMonitor;//图片显示所在的屏幕句柄
+	CRect m_monitorRect;//图片显示所在的屏幕位置和大小
+	CImgPlayConfig *m_pConfig;
+	
+	int m_nPlayCnt; // 已重复播放次数(多张图片顺序播完一次算重复播一次)
+	int m_nPicInx; // 当前图片序号	
+
+	// 双缓冲机制
+	CBitmap* m_pOldBitmap;
+	CBitmap* m_pMemBitmap; //声明内存中承载临时图象的位图
+	CDC* m_pMemDC;   //声明用于缓冲作图的内存DC
+
+	// 生成的消息映射函数
+	virtual BOOL OnInitDialog();
+	afx_msg void OnPaint();
+	afx_msg HCURSOR OnQueryDragIcon();
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnSize(UINT nType, int cx, int cy);	
+	afx_msg void OnClose();
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+};

+ 42 - 0
Other/win/libimgplayer/CMakeLists.txt

@@ -0,0 +1,42 @@
+set(MODULE_NAME "libimgplayer")
+set(MODULE_PREFIX "LIB_IMAGPLAYER_FUNC")
+
+add_definitions(-D_AFXDLL)
+
+if(MSVC)
+    set(STDAFXCPP ${RVC_COMMON_INCLUDE_DIR}/stdafx.cpp)
+else()
+	 set(STDAFXCPP )
+endif(MSVC)
+
+set(${MODULE_PREFIX}_SRCS
+    ClibimgplayerApp.cpp
+    libimgplayer.cpp
+	CImgPlayerDlg.cpp
+	${STDAFXCPP}
+)
+
+add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS})
+
+message(STATUS "RVC_COMMON_INCLUDE_DIR ${RVC_COMMON_INCLUDE_DIR}")
+
+target_include_directories(${MODULE_NAME} PRIVATE
+	${RVC_COMMON_INCLUDE_DIR}
+	${CONAN_RVCFRAMEWORK_ROOT}/include
+	)
+
+target_compile_definitions(${MODULE_NAME} PUBLIC "LIBIMAGPLAYER_EXPORTS")
+
+if(MSVC)
+	install(TARGETS ${MODULE_NAME} 
+    RUNTIME DESTINATION "${RVC_RUNTIME_PATH}" COMPONENT libraries
+    ARCHIVE DESTINATION "${RVC_LIBRARY_PATH}" COMPONENT develops EXCLUDE_FROM_ALL
+    LIBRARY DESTINATION "${RVC_LIBRARY_PATH}" COMPONENT libraries
+    )
+else()
+install(TARGETS ${MODULE_NAME} 
+    RUNTIME DESTINATION "${RVC_RUNTIME_PATH}"
+    ARCHIVE DESTINATION "${RVC_LIBRARY_PATH}"
+    LIBRARY DESTINATION "${RVC_RUNTIME_PATH}"
+    COMPONENT libraries)
+endif(MSVC)

+ 37 - 0
Other/win/libimgplayer/ClibimgplayerApp.cpp

@@ -0,0 +1,37 @@
+#include "stdafx.h"
+#include "ClibimgplayerApp.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// ClibimgplayerApp
+
+BEGIN_MESSAGE_MAP(ClibimgplayerApp, CWinApp)
+	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// ClibimgplayerApp 构造
+
+ClibimgplayerApp::ClibimgplayerApp()
+{
+	// TODO: 在此处添加构造代码,
+	// 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的一个 ClibimgplayerApp 对象
+
+ClibimgplayerApp theApp;
+
+
+// ClibimgplayerApp 初始化
+
+BOOL ClibimgplayerApp::InitInstance()
+{
+	CWinApp::InitInstance();
+
+	return TRUE;
+}

+ 23 - 0
Other/win/libimgplayer/ClibimgplayerApp.h

@@ -0,0 +1,23 @@
+// ClibimgplayerApp.h : PROJECT_NAME 应用程序的主头文件
+//
+
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
+#endif
+
+class ClibimgplayerApp : public CWinApp
+{
+public:
+	ClibimgplayerApp();
+
+	// 重写
+public:
+	virtual BOOL InitInstance();
+
+	// 实现
+
+	DECLARE_MESSAGE_MAP()
+};

+ 67 - 0
Other/win/libimgplayer/ReadMe.txt

@@ -0,0 +1,67 @@
+================================================================================
+MICROSOFT 基础类库: PicturePlayer 项目概述
+===============================================================================
+
+应用程序向导已为您创建了这个 PicturePlayer 应用程序。此应用程序不仅演示 Microsoft 基础类的基本使用方法,还可作为您编写应用程序的起点。
+
+本文件概要介绍组成 PicturePlayer 应用程序的每个文件的内容。
+
+PicturePlayer.vcxproj
+这是使用应用程序向导生成的 VC++ 项目的主项目文件。 
+它包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
+
+PicturePlayer.vcxproj.filters
+    这是使用“应用程序向导”生成的 VC++ 项目筛选器文件。
+    它包含有关项目文件与筛选器之间的关联信息。在 IDE 中,通过这种关联,在特定节点下以分组形式显示具有相似扩展名的文件。例如,“.cpp”文件与“源文件”筛选器关联。
+
+PicturePlayer.h
+这是应用程序的主要头文件。它包括其他项目特定的头文件(包括 Resource.h),并声明 CPicturePlayerApp 应用程序类。
+
+PicturePlayer.cpp
+这是包含应用程序类 CPicturePlayerApp 的主要应用程序源文件。
+
+PicturePlayer.rc
+这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ 中进行编辑。项目资源位于 2052 中。
+
+res\PicturePlayer.ico
+这是用作应用程序图标的图标文件。此图标包括在主要资源文件 PicturePlayer.rc 中。
+
+res\PicturePlayer.rc2
+此文件包含不在 Microsoft Visual C++ 中进行编辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+应用程序向导创建一个对话框类:
+
+PicturePlayerDlg.h,PicturePlayerDlg.cpp - 对话框
+这些文件包含 CPicturePlayerDlg 类。该类定义应用程序主对话框的行为。该对话框的模板位于 PicturePlayer.rc 中,该文件可以在 Microsoft Visual C++ 中进行编辑。
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+其他标准文件:
+
+StdAfx.h,StdAfx.cpp
+这些文件用于生成名为 PicturePlayer.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
+
+Resource.h
+这是标准头文件,它定义新的资源 ID。
+Microsoft Visual C++ 读取并更新此文件。
+
+PicturePlayer.manifest
+	应用程序清单文件供 Windows XP 用来描述应用程序
+	对特定版本并行程序集的依赖性。加载程序使用此
+	信息从程序集缓存加载适当的程序集或
+	从应用程序加载私有信息。应用程序清单可能为了重新分发而作为
+	与应用程序可执行文件安装在相同文件夹中的外部 .manifest 文件包括,
+	也可能以资源的形式包括在该可执行文件中。 
+/////////////////////////////////////////////////////////////////////////////
+
+其他注释:
+
+应用程序向导使用“TODO:”指示应添加或自定义的源代码部分。
+
+如果应用程序在共享的 DLL 中使用 MFC,则需要重新发布这些 MFC DLL;如果应用程序所用的语言与操作系统的当前区域设置不同,则还需要重新发布对应的本地化资源 MFC100XXX.DLL。有关这两个主题的更多信息,请参见 MSDN 文档中有关 Redistributing Visual C++ applications (重新发布 Visual C++ 应用程序)的章节。
+
+/////////////////////////////////////////////////////////////////////////////

+ 178 - 0
Other/win/libimgplayer/libimgplayer.cpp

@@ -0,0 +1,178 @@
+
+// libimgplayer.cpp : 定义应用程序的类行为。
+//
+
+#include "stdafx.h"
+#include "libimgplayer.h"
+#include "CImgPlayerDlg.h"
+
+
+class libimgplayer_impl
+{
+private:
+	CImgPlayerDlg *m_pDlg;
+	HANDLE m_hPlayThread;
+	DWORD m_nPlaythreadId;
+	BOOL m_bIsPlay;
+	CImgPlayConfig m_stPlayConfig;
+	CImgHostApi *m_pHostApi;
+
+	VOID PlayDlg()
+	{
+		if (m_stPlayConfig.nWndX < 0 || m_stPlayConfig.nWndY < 0 || m_stPlayConfig.nWndWidth < 0 
+			|| m_stPlayConfig.nWndHeight < 0 || m_stPlayConfig.nPlayCnt < 0 
+			|| m_stPlayConfig.nPlayInterval < 0|| m_stPlayConfig.nFileCnt <= 0)
+			return;
+		if (m_pDlg != NULL)
+			return;
+		AFX_MANAGE_STATE(AfxGetStaticModuleState());
+		m_pDlg = new CImgPlayerDlg(&m_stPlayConfig);
+		//m_pHostApi->ImgDebug("Ok to initialize CImgDlg!");
+		INT_PTR nResponse = m_pDlg->DoModal();
+
+		delete m_pDlg;
+		m_pDlg = NULL;
+
+		if (nResponse == IDCANCEL){
+			// 表示是执行OnCancel或OnClose或StopPlay关闭的
+			CloseHandle(m_hPlayThread);
+			m_hPlayThread = NULL;
+		}
+	}
+
+	static unsigned int __stdcall ImgPlayThread(LPVOID param)
+	{
+		int i = 0;
+		CoInitialize(NULL);
+		libimgplayer_impl *p = (libimgplayer_impl *)param;
+		p->PlayDlg();
+
+		CoUninitialize();
+		return 0;
+	}
+public:
+	libimgplayer_impl(CImgHostApi *pHostApi)
+		: m_pDlg(NULL), m_hPlayThread(NULL), m_nPlaythreadId(0), m_bIsPlay(FALSE)
+	{
+		m_pHostApi = pHostApi;
+		memset(&m_stPlayConfig, 0, sizeof(m_stPlayConfig));
+	}
+
+	~libimgplayer_impl()
+	{
+		m_pHostApi = NULL;
+	}
+
+	BOOL isStop(){ return !m_bIsPlay; }
+
+	BOOL CheckIsPlay(HANDLE &playThread)
+	{
+		if (NULL == m_hPlayThread) {
+			return FALSE;
+		}
+
+		DWORD exitCode = 0;
+		if (GetExitCodeThread(m_hPlayThread, &exitCode) && STILL_ACTIVE == exitCode){
+			playThread = m_hPlayThread;
+			return TRUE;
+		}
+		else {
+			return FALSE;
+		}
+	}
+
+	BOOL StartPlayMedia(CImgPlayConfig &config)
+	{
+		if (m_bIsPlay){
+			if (m_pDlg != NULL) {
+				return TRUE;
+			}
+		}
+		else {
+			m_bIsPlay = TRUE;
+		}
+
+		memcpy(&m_stPlayConfig, &config, sizeof(CImgPlayConfig));
+		m_hPlayThread = (HANDLE)_beginthreadex(NULL, 0, ImgPlayThread, (LPVOID)this, 0, (unsigned int*)&m_nPlaythreadId);
+		return TRUE;
+	}
+
+	BOOL StartPlay(int nCfgInx, int nWndX, int nWndY, int nWndWidth, int nWndHeight)
+	{
+		if (m_bIsPlay){
+			if (m_pDlg != NULL) {
+				return TRUE;
+			}
+		}
+		else {
+			m_bIsPlay = TRUE;
+		}
+			
+		m_stPlayConfig.nWndX = nWndX;
+		m_stPlayConfig.nWndY = nWndY;
+		m_stPlayConfig.nWndWidth = nWndWidth;
+		m_stPlayConfig.nWndHeight = nWndHeight;
+		BOOL bRet = m_pHostApi->LoadPlayConfig(m_stPlayConfig, nCfgInx);
+		if (!bRet){
+			m_pHostApi->ImgDebug("Load ImgConfiguration failed!");
+			return FALSE;
+		}
+		else{
+			m_pHostApi->ImgDebug("Load ImgConfiguration succeeded while play local image!");
+			m_pHostApi->ImgDebug("m_stPlayConfig.strRootPath: %s", m_stPlayConfig.strRootPath);
+		}
+
+		m_hPlayThread = (HANDLE)_beginthreadex(NULL, 0, ImgPlayThread, (LPVOID)this, 0, (unsigned int*)&m_nPlaythreadId);		
+		return TRUE;
+	}
+
+	BOOL StopPlay()
+	{
+		if (m_pDlg != NULL){
+			if (m_hPlayThread != NULL){
+				::PostMessage(m_pDlg->GetSafeHwnd(), WM_CLOSE, NULL, NULL);
+				WaitForSingleObject(m_hPlayThread, INFINITE);
+			}
+		}
+
+		m_bIsPlay = FALSE;
+
+		return TRUE;
+	}
+};
+
+Clibimgplayer::Clibimgplayer(CImgHostApi *pHostApi)
+{
+	m_pImpl = new libimgplayer_impl(pHostApi);
+	return;
+}
+
+Clibimgplayer::~Clibimgplayer()
+{
+	delete m_pImpl;
+	m_pImpl = NULL;
+}
+
+VOID Clibimgplayer::Play(int nCfgInx, int nWndX, int nWndY, int nWndWidth, int nWndHeight)
+{
+	m_pImpl->StartPlay(nCfgInx, nWndX, nWndY, nWndWidth, nWndHeight);
+}
+
+VOID Clibimgplayer::PlayMedia(CImgPlayConfig &config)
+{
+	m_pImpl->StartPlayMedia(config);
+}
+
+BOOL Clibimgplayer::checkIsStop(){
+	return m_pImpl->isStop();
+}
+
+BOOL Clibimgplayer::checkIsPlay(HANDLE &curThread)
+{
+	return m_pImpl->CheckIsPlay(curThread);
+}
+
+VOID Clibimgplayer::Close()
+{
+	m_pImpl->StopPlay();
+}

+ 47 - 0
Other/win/libimgplayer/libimgplayer.h

@@ -0,0 +1,47 @@
+#pragma once
+
+#ifdef LIBIMGPLAYER_EXPORTS
+#define LIBIMGPLAYER_API __declspec(dllexport)
+#else
+#define LIBIMGPLAYER_API __declspec(dllimport)
+#endif
+
+#define MAX_FILECOUNT 32
+
+struct CImgPlayConfig
+{	
+	bool bFullScreen;                           // 是否全屏
+	bool bPrimMonitor;                          // 是否主屏显示
+	int nWndX;                                  // 窗口X坐标
+	int nWndY;                                  // 窗口Y坐标
+	int nWndWidth;                              // 窗口宽度
+	int nWndHeight;                             // 窗口高度
+	int nFileCnt;		                        // 文件个数
+	int nPlayCnt;		                        // 播放次数
+	int nPlayInterval;		                    // 播放时间间隔
+	char strRootPath[MAX_PATH];		            // 根目录
+	char strFileNames[MAX_FILECOUNT][MAX_PATH]; // 文件名数组
+};
+
+struct __declspec(novtable) CImgHostApi
+{
+	virtual BOOL LoadPlayConfig(CImgPlayConfig &config, int CfgInx = 0) = 0;
+	virtual void ImgDebug(const char *fmt, ...) = 0;
+};
+
+class libimgplayer_impl; // 桥接
+
+class LIBIMGPLAYER_API Clibimgplayer
+{
+public:
+	Clibimgplayer(CImgHostApi *pHostApi);
+	~Clibimgplayer();
+
+	VOID Play(int nCfgInx, int nWndX, int nWndY, int nWndWidth, int nWndHeight);
+	VOID PlayMedia(CImgPlayConfig &config);
+	BOOL checkIsStop();
+	BOOL checkIsPlay(HANDLE &curThread);
+	VOID Close();
+private:
+	libimgplayer_impl *m_pImpl;
+};

二進制
Other/win/libimgplayer/libimgplayer.rc


二進制
Other/win/libimgplayer/res/libimgplayer.ico


二進制
Other/win/libimgplayer/res/libimgplayer.rc2


二進制
Other/win/libimgplayer/resource.h


+ 8 - 0
Other/win/libimgplayer/stdafx.cpp

@@ -0,0 +1,8 @@
+
+// stdafx.cpp : 只包括标准包含文件的源文件
+// PicturePlayer.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+

+ 55 - 0
Other/win/libimgplayer/stdafx.h

@@ -0,0 +1,55 @@
+
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+
+#pragma once
+
+#ifndef _SECURE_ATL
+#define _SECURE_ATL 1
+#endif
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的
+
+// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h>         // MFC 核心组件和标准组件
+#include <afxext.h>         // MFC 扩展
+
+
+
+
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h>           // MFC 对 Internet Explorer 4 公共控件的支持
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>             // MFC 对 Windows 公共控件的支持
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <afxcontrolbars.h>     // 功能区和控件条的 MFC 支持
+
+
+
+
+
+
+
+
+
+#ifdef _UNICODE
+#if defined _M_IX86
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_X64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#else
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#endif
+#endif

+ 8 - 0
Other/win/libimgplayer/targetver.h

@@ -0,0 +1,8 @@
+#pragma once
+
+// 包括 SDKDDKVer.h 将定义最高版本的可用 Windows 平台。
+
+// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
+// WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
+
+#include <SDKDDKVer.h>