Răsfoiți Sursa

1、关闭ChildFrame的系统菜单,需要在PreCreateWindow中处理:cs.style &= ~WS_SYSMENU;
2、对接完成UB530视频采集卡到CSATHelperView中;

scbc.sat2 5 ani în urmă
părinte
comite
e6c64063cf

+ 39 - 0
SATHelper/SATHelper/ChildFrm.cpp

@@ -31,6 +31,7 @@ BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWndEx)
 	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CChildFrame::OnFilePrint)
 	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CChildFrame::OnFilePrintPreview)
 	ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_PREVIEW, &CChildFrame::OnUpdateFilePrintPreview)
+	ON_WM_CREATE()
 END_MESSAGE_MAP()
 
 // CChildFrame 构造/析构
@@ -51,6 +52,12 @@ BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
 	if( !CMDIChildWndEx::PreCreateWindow(cs) )
 		return FALSE;
 
+	// 只去掉最大化最小化按钮;
+	//cs.style &= ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX |WS_THICKFRAME);
+
+	// 去掉整个菜单(最大化、最小化、关闭……),此时GetSystemMenu(FALSE)返回NULL;
+	cs.style &= ~WS_SYSMENU;
+
 	return TRUE;
 }
 
@@ -90,3 +97,35 @@ void CChildFrame::OnUpdateFilePrintPreview(CCmdUI* pCmdUI)
 {
 	pCmdUI->SetCheck(m_dockManager.IsPrintPreviewValid());
 }
+
+
+BOOL CChildFrame::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CMDIFrameWnd* pParentWnd, CCreateContext* pContext)
+{
+	// TODO: 在此添加专用代码和/或调用基类
+	
+	return CMDIChildWndEx::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, pContext);
+}
+
+
+int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+	if (CMDIChildWndEx::OnCreate(lpCreateStruct) == -1)
+		return -1;
+
+	// TODO:  在此添加您专用的创建代码
+#if 0
+ 	CMenu* pSysMenu = GetSystemMenu(FALSE);
+ 	ASSERT(pSysMenu != NULL);
+ 	VERIFY(pSysMenu->RemoveMenu(SC_CLOSE, MF_BYCOMMAND));
+#endif
+
+	return 0;
+}
+
+
+void CChildFrame::ActivateFrame(int nCmdShow)
+{
+	// TODO: 在此添加专用代码和/或调用基类
+	nCmdShow = SW_MAXIMIZE;
+	CMDIChildWndEx::ActivateFrame(nCmdShow);
+}

+ 4 - 0
SATHelper/SATHelper/ChildFrm.h

@@ -45,4 +45,8 @@ protected:
 	afx_msg void OnFilePrintPreview();
 	afx_msg void OnUpdateFilePrintPreview(CCmdUI* pCmdUI);
 	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW, const RECT& rect = rectDefault, CMDIFrameWnd* pParentWnd = NULL, CCreateContext* pContext = NULL);
+	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+	virtual void ActivateFrame(int nCmdShow = -1);
 };

+ 65 - 1
SATHelper/SATHelper/MainFrm.cpp

@@ -44,6 +44,8 @@ BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
 	ON_MESSAGE(WM_MY_TRAY_NOTIFICATION, OnTrayNotification)
 	ON_REGISTERED_MESSAGE(WM_TASKBARCREATED, OnTaskBarCreated)
 #endif
+	ON_COMMAND(ID_TRAYMENU_EXIT, &CMainFrame::OnTraymenuExit)
+	ON_MESSAGE(MSG_STATUS_BAR, &CMainFrame::OnMsgStatusBar)
 END_MESSAGE_MAP()
 
 // CMainFrame 构造/析构
@@ -114,7 +116,7 @@ void CMainFrame::TrayRight()
 	if (!menu.LoadMenu(IDR_MAINFRAME))
 		return;
 
-	CMenu* pSubMenu = menu.GetSubMenu(4);
+	CMenu* pSubMenu = menu.GetSubMenu(3);
 	if (!pSubMenu)
 		return;
 
@@ -266,6 +268,9 @@ BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
 	// TODO: 在此处通过修改
 	//  CREATESTRUCT cs 来修改窗口类或样式
 
+	//不把子框架标题添加到主框架标题(主框架中就不会再处理WM_SETTEXT消息)
+	cs.style &= ~FWS_ADDTOTITLE;
+
 	return TRUE;
 }
 
@@ -581,3 +586,62 @@ void CMainFrame::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
 #endif
 #endif
 }
+
+LRESULT CMainFrame::OnMsgStatusBar(WPARAM wParam, LPARAM lParam)
+{
+	CString strMSG = *(CString*)wParam;
+	int uId = lParam;
+
+	SetRibbonStatusBarText(strMSG, uId);
+
+	return LRESULT();
+}
+
+void CMainFrame::OnTraymenuExit()
+{
+	// TODO: 在此添加命令处理程序代码
+	//GetActiveView();
+	CFrameWnd::OnClose();
+}
+
+
+void CMainFrame::OnClose()
+{
+	// TODO: 在此添加消息处理程序代码和/或调用默认值
+#ifndef _DEBUG
+	ShowWindow(SW_HIDE);
+	m_bNoticeTray = FALSE;
+#else
+	CFrameWnd::OnClose();
+#endif
+}
+
+
+BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
+{
+	// TODO: 在此添加专用代码和/或调用基类
+	static BOOL bTopWnd = FALSE;
+	if (pMsg->message == WM_KEYDOWN)
+	{
+		switch (pMsg->wParam)
+		{
+		case VK_F3:
+			if (bTopWnd == FALSE)
+			{
+				SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);//窗口置顶
+				SetWindowText(_T("视频采集卡-前置窗口(请按F3取消或开启前置)"));
+			}
+			else
+			{
+				SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);//取消窗口置顶	
+				SetWindowText(_T("视频采集卡-取消前置(请按F3取消或开启前置)"));
+			}
+			bTopWnd = !bTopWnd;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return CMDIFrameWndEx::PreTranslateMessage(pMsg);
+}

+ 4 - 0
SATHelper/SATHelper/MainFrm.h

@@ -91,6 +91,9 @@ protected:
 	afx_msg void OnUpdateViewCaptionBar(CCmdUI* pCmdUI);
 	afx_msg void OnOptions();
 	afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
+	afx_msg LRESULT OnMsgStatusBar(WPARAM wParam, LPARAM lParam);
+	afx_msg void OnClose();
+	void OnTraymenuExit();
 	DECLARE_MESSAGE_MAP()
 
 #if __DOCKINGBAR__
@@ -151,6 +154,7 @@ public:
 			}
 		}
 	}
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
 };
 
 

+ 119 - 117
SATHelper/SATHelper/Resource.h

@@ -1,124 +1,126 @@
 //{{NO_DEPENDENCIES}}
-// 生成的 Microsoft Visual C++ 包含文件。
-//  SATHelper.rc 使用
+// Microsoft Visual C++ 生成的包含文件。
+//  SATHelper.rc 使用
 //
-#define IDR_PASTE_MENU				151
-#define IDR_WINDOWS_MENU			152
-#define IDD_ABOUTBOX				100
-#define IDP_OLE_INIT_FAILED			100
-#define ID_WRITE_PASTEASHYPERLINK	32770
-#define IDB_WRITESMALL				110
-#define IDB_WRITELARGE				111
-#define IDB_MAIN					112
-#define IDB_BUTTONS					113
-#define IDB_FILELARGE				114
-#define IDB_FILESMALL				115
-#define IDR_POPUP_EDIT				119
-#define ID_STATUSBAR_PANE1			120
-#define ID_STATUSBAR_PANE2			121
-#define IDS_STATUS_PANE1			122
-#define IDS_STATUS_PANE2			123
-#define IDR_MAINFRAME				128
-#define IDR_MAINFRAME_256			129
-#define IDR_SATHelperTYPE				130
-#define ID_WINDOW_MANAGER			131
-#define ID_VIEW_FILEVIEW			133
-#define ID_VIEW_CLASSVIEW			134
-#define ID_PROPERTIES				135
-#define ID_OPEN						136
-#define ID_OPEN_WITH				137
-#define ID_DUMMY_COMPILE			138
-#define ID_CLASS_ADD_MEMBER_FUNCTION	139
-#define ID_CLASS_ADD_MEMBER_VARIABLE	140
-#define ID_CLASS_DEFINITION			141
-#define ID_CLASS_PROPERTIES			142
-#define ID_NEW_FOLDER				143
-#define ID_SORT_MENU				144
-#define ID_SORTING_GROUPBYTYPE		145
-#define ID_SORTING_SORTALPHABETIC	146
-#define ID_SORTING_SORTBYTYPE		147
-#define ID_SORTING_SORTBYACCESS		148
-#define ID_VIEW_OUTPUTWND			149
-#define ID_VIEW_PROPERTIESWND		150
-#define ID_SORTPROPERTIES			151
-#define ID_PROPERTIES1				152
-#define ID_PROPERTIES2				153
-#define ID_EXPAND_ALL				154
-#define IDS_FILE_VIEW				155
-#define IDS_CLASS_VIEW				156
-#define IDS_OUTPUT_WND				157
-#define IDS_PROPERTIES_WND			158
-#define IDI_FILE_VIEW				161
-#define IDI_FILE_VIEW_HC			162
-#define IDI_CLASS_VIEW				163
-#define IDI_CLASS_VIEW_HC			164
-#define IDI_OUTPUT_WND				165
-#define IDI_OUTPUT_WND_HC			166
-#define IDI_PROPERTIES_WND			167
-#define IDI_PROPERTIES_WND_HC		168
-#define IDR_EXPLORER				169
-#define IDB_EXPLORER_24				170
-#define IDR_SORT					171
-#define IDB_SORT_24					172
-#define IDR_POPUP_SORT				173
-#define IDR_POPUP_EXPLORER			174
-#define IDB_FILE_VIEW				175
-#define IDB_FILE_VIEW_24			176
-#define IDB_CLASS_VIEW				177
-#define IDB_CLASS_VIEW_24			178
-#define IDR_MENU_IMAGES				179
-#define IDB_MENU_IMAGES_24			180
-#define ID_TOOLS_MACRO				181
-#define IDR_OUTPUT_POPUP			182
-#define IDR_PROPERTIES				183
-#define IDB_PROPERTIES_HC			184
-#define ID_VIEW_NAVIGATION			185
-#define IDB_NAVIGATION_LARGE		186
-#define IDB_NAVIGATION_LARGE_HC		187
-#define IDB_PAGES					188
-#define IDB_PAGES_HC				189
-#define IDB_PAGES_SMALL				190
-#define IDB_PAGES_SMALL_HC			191
-#define IDR_THEME_MENU				200
-#define ID_SET_STYLE				201
-#define ID_VIEW_APPLOOK_WIN_2000	205
-#define ID_VIEW_APPLOOK_OFF_XP		206
-#define ID_VIEW_APPLOOK_WIN_XP		207
-#define ID_VIEW_APPLOOK_OFF_2003	208
-#define ID_VIEW_APPLOOK_VS_2005		209
-#define ID_VIEW_APPLOOK_VS_2008		210
-#define ID_VIEW_APPLOOK_OFF_2007_BLUE	215
-#define ID_VIEW_APPLOOK_OFF_2007_BLACK	216
-#define ID_VIEW_APPLOOK_OFF_2007_SILVER	217
-#define ID_VIEW_APPLOOK_OFF_2007_AQUA	218
-#define ID_VIEW_APPLOOK_WINDOWS_7	219
-#define ID_TOOLS_OPTIONS			220
-#define ID_VIEW_CAPTION_BAR			221
-#define IDB_INFO					230
-#define IDS_CAPTION_BUTTON			231
-#define IDS_CAPTION_BUTTON_TIP		232
-#define IDS_CAPTION_TEXT			233
-#define IDS_CAPTION_IMAGE_TIP		234
-#define IDS_CAPTION_IMAGE_TEXT		235
-#define IDS_MYCALENDARS				250
-#define IDS_CALENDAR				251
-#define IDS_SHORTCUTS				252
-#define IDS_FOLDERS					253
-#define IDS_OUTLOOKBAR				258
-#define IDS_BUILD_TAB				300
-#define IDS_DEBUG_TAB				301
-#define IDS_FIND_TAB				302
-#define IDS_EXPLORER				305
-#define IDS_EDIT_MENU				306
-#define IDR_RIBBON             			307
+#define IDD_ABOUTBOX                    100
+#define IDP_OLE_INIT_FAILED             100
+#define IDB_WRITESMALL                  110
+#define IDB_WRITELARGE                  111
+#define IDB_MAIN                        112
+#define IDB_BUTTONS                     113
+#define IDB_FILELARGE                   114
+#define IDB_FILESMALL                   115
+#define IDR_POPUP_EDIT                  119
+#define ID_STATUSBAR_PANE1              120
+#define ID_STATUSBAR_PANE2              121
+#define IDS_STATUS_PANE1                122
+#define IDS_STATUS_PANE2                123
+#define IDR_MAINFRAME                   128
+#define IDR_MAINFRAME_256               129
+#define IDR_SATHelperTYPE               130
+#define ID_WINDOW_MANAGER               131
+#define ID_VIEW_FILEVIEW                133
+#define ID_VIEW_CLASSVIEW               134
+#define ID_PROPERTIES                   135
+#define ID_OPEN                         136
+#define ID_OPEN_WITH                    137
+#define ID_DUMMY_COMPILE                138
+#define ID_CLASS_ADD_MEMBER_FUNCTION    139
+#define ID_CLASS_ADD_MEMBER_VARIABLE    140
+#define ID_CLASS_DEFINITION             141
+#define ID_CLASS_PROPERTIES             142
+#define ID_NEW_FOLDER                   143
+#define ID_SORT_MENU                    144
+#define ID_SORTING_GROUPBYTYPE          145
+#define ID_SORTING_SORTALPHABETIC       146
+#define ID_SORTING_SORTBYTYPE           147
+#define ID_SORTING_SORTBYACCESS         148
+#define ID_VIEW_OUTPUTWND               149
+#define ID_VIEW_PROPERTIESWND           150
+#define IDR_PASTE_MENU                  151
+#define ID_SORTPROPERTIES               151
+#define IDR_WINDOWS_MENU                152
+#define ID_PROPERTIES1                  152
+#define ID_PROPERTIES2                  153
+#define ID_EXPAND_ALL                   154
+#define IDS_FILE_VIEW                   155
+#define IDS_CLASS_VIEW                  156
+#define IDS_OUTPUT_WND                  157
+#define IDS_PROPERTIES_WND              158
+#define IDI_FILE_VIEW                   161
+#define IDI_FILE_VIEW_HC                162
+#define IDI_CLASS_VIEW                  163
+#define IDI_CLASS_VIEW_HC               164
+#define IDI_OUTPUT_WND                  165
+#define IDI_OUTPUT_WND_HC               166
+#define IDI_PROPERTIES_WND              167
+#define IDI_PROPERTIES_WND_HC           168
+#define IDR_EXPLORER                    169
+#define IDB_EXPLORER_24                 170
+#define IDR_SORT                        171
+#define IDB_SORT_24                     172
+#define IDR_POPUP_SORT                  173
+#define IDR_POPUP_EXPLORER              174
+#define IDB_FILE_VIEW                   175
+#define IDB_FILE_VIEW_24                176
+#define IDB_CLASS_VIEW                  177
+#define IDB_CLASS_VIEW_24               178
+#define IDR_MENU_IMAGES                 179
+#define IDB_MENU_IMAGES_24              180
+#define ID_TOOLS_MACRO                  181
+#define IDR_OUTPUT_POPUP                182
+#define IDR_PROPERTIES                  183
+#define IDB_PROPERTIES_HC               184
+#define ID_VIEW_NAVIGATION              185
+#define IDB_NAVIGATION_LARGE            186
+#define IDB_NAVIGATION_LARGE_HC         187
+#define IDB_PAGES                       188
+#define IDB_PAGES_HC                    189
+#define IDB_PAGES_SMALL                 190
+#define IDB_PAGES_SMALL_HC              191
+#define IDR_THEME_MENU                  200
+#define ID_SET_STYLE                    201
+#define ID_VIEW_APPLOOK_WIN_2000        205
+#define ID_VIEW_APPLOOK_OFF_XP          206
+#define ID_VIEW_APPLOOK_WIN_XP          207
+#define ID_VIEW_APPLOOK_OFF_2003        208
+#define ID_VIEW_APPLOOK_VS_2005         209
+#define ID_VIEW_APPLOOK_VS_2008         210
+#define ID_VIEW_APPLOOK_OFF_2007_BLUE   215
+#define ID_VIEW_APPLOOK_OFF_2007_BLACK  216
+#define ID_VIEW_APPLOOK_OFF_2007_SILVER 217
+#define ID_VIEW_APPLOOK_OFF_2007_AQUA   218
+#define ID_VIEW_APPLOOK_WINDOWS_7       219
+#define ID_TOOLS_OPTIONS                220
+#define ID_VIEW_CAPTION_BAR             221
+#define IDB_INFO                        230
+#define IDS_CAPTION_BUTTON              231
+#define IDS_CAPTION_BUTTON_TIP          232
+#define IDS_CAPTION_TEXT                233
+#define IDS_CAPTION_IMAGE_TIP           234
+#define IDS_CAPTION_IMAGE_TEXT          235
+#define IDS_MYCALENDARS                 250
+#define IDS_CALENDAR                    251
+#define IDS_SHORTCUTS                   252
+#define IDS_FOLDERS                     253
+#define IDS_OUTLOOKBAR                  258
+#define IDS_BUILD_TAB                   300
+#define IDS_DEBUG_TAB                   301
+#define IDS_FIND_TAB                    302
+#define IDS_EXPLORER                    305
+#define IDS_EDIT_MENU                   306
+#define IDR_RIBBON                      307
+#define ID_WRITE_PASTEASHYPERLINK       32770
+#define ID_TRAYMENU_RECONNECT			32771
+#define ID_TRAYMENU_EXIT                32772
 
-// 新对象的下一组默认值
-//
+// Next default values for new objects
+// 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE	310
-#define _APS_NEXT_CONTROL_VALUE		1000
-#define _APS_NEXT_SYMED_VALUE		310
-#define _APS_NEXT_COMMAND_VALUE		32771
+#define _APS_NEXT_RESOURCE_VALUE        310
+#define _APS_NEXT_COMMAND_VALUE         32773
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           310
 #endif
 #endif

+ 48 - 1
SATHelper/SATHelper/SATHelper.cpp

@@ -23,6 +23,8 @@
 #include "SATHelperDoc.h"
 #include "SATHelperView.h"
 
+#include "IOCPModel.h"
+
 #ifdef _DEBUG
 #define new DEBUG_NEW
 #endif
@@ -69,6 +71,9 @@ CSATHelperApp theApp;
 
 
 // CSATHelperApp 初始化
+CIOCPModel g_iocp;
+HANDLE g_hMutex = NULL;	// 全局互斥量;
+ULONG_PTR CSATHelperApp::m_gdiplusToken = 0;
 
 BOOL CSATHelperApp::InitInstance()
 {
@@ -100,6 +105,47 @@ BOOL CSATHelperApp::InitInstance()
 	EnableTaskbarInteraction(FALSE);
 #endif
 
+#if 1
+	g_hMutex = ::CreateMutex(NULL, FALSE, _T("UB530"));
+	if (GetLastError() == ERROR_ALREADY_EXISTS)
+	{
+		::MessageBox(NULL, _T("UB530采集卡程序已经打开!"), _T("温馨提示"), MB_ICONINFORMATION);
+		return FALSE;
+	}
+
+	GdiplusStartupInput gdiplusStartupInput;
+	GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
+
+	// 获取模块的目录;
+	TCHAR szDrive[MAX_PATH] = { 0 };
+	TCHAR szDir[MAX_PATH] = { 0 };
+	TCHAR szExt[MAX_PATH] = { 0 };
+	::GetModuleFileName(NULL, Global::g_szCurModulePath, sizeof(Global::g_szCurModulePath) / sizeof(TCHAR));
+	_tsplitpath_s(Global::g_szCurModulePath, szDrive, szDir, Global::g_szFna, szExt);
+	::GetCurrentDirectory(MAX_PATH, Global::g_szCurModuleDir);
+	_tcscat_s(Global::g_szCurModuleDir, _T("\\"));
+#endif
+
+#if 1
+	Global::GetConfig();
+	Global::WriteTextLog("程序启动");
+
+	CDevice* pdev = new CDevice();
+	pdev->m_iBaudrate = 115200;
+	pdev->m_iDatabit = 8;
+	pdev->m_iPort = 3;
+	pdev->m_iParitybit = 0;
+	pdev->m_iStopbit = 1;
+	pdev->m_iID = 1;
+	pdev->m_strDeviceName = "Chroma22293";
+	pdev->m_iDeviceType = 1;
+	pdev->Open();
+
+	g_dmap.insert(std::pair<int, CDevice*>(pdev->m_iID, pdev));
+
+	g_iocp.LoadSocketLib();
+	g_iocp.Start(5566);
+#endif
 	// 使用 RichEdit 控件需要 AfxInitRichEdit2()
 	// AfxInitRichEdit2();
 
@@ -167,7 +213,8 @@ int CSATHelperApp::ExitInstance()
 {
 	//TODO: 处理可能已添加的附加资源
 	AfxOleTerm(FALSE);
-
+	Gdiplus::GdiplusShutdown(m_gdiplusToken);
+	g_iocp.Stop();
 	return CWinAppEx::ExitInstance();
 }
 

+ 1 - 0
SATHelper/SATHelper/SATHelper.h

@@ -38,6 +38,7 @@ public:
 // 实现
 	UINT  m_nAppLook;
 	BOOL  m_bHiColorIcons;
+	static ULONG_PTR m_gdiplusToken;
 
 	virtual void PreLoadState();
 	virtual void LoadCustomState();

+ 264 - 158
SATHelper/SATHelper/SATHelper.rc

@@ -1,4 +1,4 @@
-//Microsoft Visual C++ 生成的资源脚本。
+// Microsoft Visual C++ generated resource script.
 //
 #pragma code_page(65001)
 
@@ -7,7 +7,7 @@
 #define APSTUDIO_READONLY_SYMBOLS
 /////////////////////////////////////////////////////////////////////////////
 //
-// 从 TEXTINCLUDE 2 资源生成。
+// Generated from the TEXTINCLUDE 2 resource.
 //
 #ifndef APSTUDIO_INVOKED
 #include "targetver.h"
@@ -18,19 +18,24 @@
 /////////////////////////////////////////////////////////////////////////////
 #undef APSTUDIO_READONLY_SYMBOLS
 
-#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+// 中文(简体,中国) resources
 
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+
+#ifdef APSTUDIO_INVOKED
 /////////////////////////////////////////////////////////////////////////////
 //
 // TEXTINCLUDE
 //
 
-1 TEXTINCLUDE
+1 TEXTINCLUDE 
 BEGIN
     "resource.h\0"
 END
 
-2 TEXTINCLUDE
+2 TEXTINCLUDE 
 BEGIN
     "#ifndef APSTUDIO_INVOKED\r\n"
     "#include ""targetver.h""\r\n"
@@ -40,7 +45,7 @@ BEGIN
     "\0"
 END
 
-3 TEXTINCLUDE
+3 TEXTINCLUDE 
 BEGIN
     "#define _AFX_NO_OLE_RESOURCES\r\n"
     "#define _AFX_NO_TRACKER_RESOURCES\r\n"
@@ -48,11 +53,11 @@ BEGIN
     "\r\n"
     "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
     "LANGUAGE 4, 2\r\n"
-    "#include ""res\\SATHelper.rc2""  // 非 Microsoft Visual C++ 编辑的资源\r\n"
-    "#include ""l.CHS\\afxres.rc""      // 标准组件\r\n"
-    "#include ""l.CHS\\afxprint.rc""    // 打印/打印预览资源\r\n"
+    "#include ""res\\SATHelper.rc2""  // 闈?Microsoft Visual C++ 缂栬緫鐨勮祫婧?\n"
+    "#include ""l.CHS\\afxres.rc""      // 鏍囧噯缁勪欢\r\n"
+    "#include ""l.CHS\\afxprint.rc""    // 鎵撳嵃/鎵撳嵃棰勮璧勬簮\r\n"
     "#if !defined(_AFXDLL)\r\n"
-    "#include ""l.CHS\\afxribbon.rc""        // MFC 功能区和控制条资源\r\n"
+    "#include ""l.CHS\\afxribbon.rc""        // MFC 鍔熻兘鍖哄拰鎺у埗鏉¤祫婧?\n"
     "#endif\r\n"
     "#endif\r\n"
     "\0"
@@ -63,62 +68,95 @@ END
 
 /////////////////////////////////////////////////////////////////////////////
 //
-// 图标
+// Icon
 //
 
-// ID 值最低的图标放在最前面,以确保应用程序图标
-// 在所有系统中保持一致。
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME           ICON                    "res\\SATHelper.ico"
+
+IDR_SATHelperTYPE       ICON                    "res\\SATHelperDoc.ico"
+
+IDI_FILE_VIEW           ICON                    "res\\file_view.ico"
+
+IDI_FILE_VIEW_HC        ICON                    "res\\file_view_hc.ico"
+
+IDI_CLASS_VIEW          ICON                    "res\\class_view.ico"
+
+IDI_CLASS_VIEW_HC       ICON                    "res\\class_view_hc.ico"
+
+IDI_OUTPUT_WND          ICON                    "res\\output_wnd.ico"
+
+IDI_OUTPUT_WND_HC       ICON                    "res\\output_wnd_hc.ico"
+
+IDI_PROPERTIES_WND      ICON                    "res\\properties_wnd.ico"
+
+IDI_PROPERTIES_WND_HC   ICON                    "res\\properties_wnd_hc.ico"
 
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
-LANGUAGE 4, 2
-IDR_MAINFRAME           ICON         "res\\SATHelper.ico"
-IDR_SATHelperTYPE         ICON         "res\\SATHelperDoc.ico"
-#endif
-IDI_FILE_VIEW           ICON         "res\\file_view.ico"
-IDI_FILE_VIEW_HC        ICON         "res\\file_view_hc.ico"
-IDI_CLASS_VIEW          ICON         "res\\class_view.ico"
-IDI_CLASS_VIEW_HC       ICON         "res\\class_view_hc.ico"
-IDI_OUTPUT_WND          ICON         "res\\output_wnd.ico"
-IDI_OUTPUT_WND_HC       ICON         "res\\output_wnd_hc.ico"
-IDI_PROPERTIES_WND      ICON         "res\\properties_wnd.ico"
-IDI_PROPERTIES_WND_HC   ICON         "res\\properties_wnd_hc.ico"
 
 /////////////////////////////////////////////////////////////////////////////
 //
-// 位图
+// Bitmap
 //
 
 IDR_MAINFRAME           BITMAP                  "res\\Toolbar.bmp"
+
 IDR_MAINFRAME_256       BITMAP                  "res\\Toolbar256.bmp"
+
 IDB_MAIN                BITMAP                  "res\\main.bmp"
+
 IDB_FILELARGE           BITMAP                  "res\\filelarge.bmp"
+
 IDB_FILESMALL           BITMAP                  "res\\filesmall.bmp"
+
 IDB_WRITELARGE          BITMAP                  "res\\writelarge.bmp"
+
 IDB_WRITESMALL          BITMAP                  "res\\writesmall.bmp"
+
 IDB_BUTTONS             BITMAP                  "res\\buttons.bmp"
+
 IDR_SORT                BITMAP                  "res\\sort.bmp"
+
 IDB_SORT_24             BITMAP                  "res\\sort_hc.bmp"
+
 IDB_FILE_VIEW           BITMAP                  "res\\fileview.bmp"
+
 IDB_FILE_VIEW_24        BITMAP                  "res\\fileview_hc.bmp"
+
 IDB_CLASS_VIEW          BITMAP                  "res\\classview.bmp"
+
 IDB_CLASS_VIEW_24       BITMAP                  "res\\classview_hc.bmp"
+
 IDR_EXPLORER            BITMAP                  "res\\explorer.bmp"
+
 IDB_EXPLORER_24         BITMAP                  "res\\explorer_hc.bmp"
+
 IDR_MENU_IMAGES         BITMAP                  "res\\menuimages.bmp"
+
 IDB_MENU_IMAGES_24      BITMAP                  "res\\menuimages_hc.bmp"
+
 IDR_PROPERTIES          BITMAP                  "res\\properties.bmp"
+
 IDB_PROPERTIES_HC       BITMAP                  "res\\properties_hc.bmp"
+
 IDB_NAVIGATION_LARGE    BITMAP                  "res\\nav_large.bmp"
+
 IDB_NAVIGATION_LARGE_HC BITMAP                  "res\\nav_large_hc.bmp"
+
 IDB_PAGES               BITMAP                  "res\\pages.bmp"
+
 IDB_PAGES_HC            BITMAP                  "res\\pages_hc.bmp"
+
 IDB_PAGES_SMALL         BITMAP                  "res\\pages_small.bmp"
+
 IDB_PAGES_SMALL_HC      BITMAP                  "res\\pages_small_hc.bmp"
+
 IDB_INFO                BITMAP                  "res\\info.bmp"
 
+
 /////////////////////////////////////////////////////////////////////////////
 //
-// 工具栏
+// Toolbar
 //
 
 IDR_MAINFRAME TOOLBAR 16, 15
@@ -149,7 +187,6 @@ BEGIN
     BUTTON      ID_APP_ABOUT
 END
 
-
 IDR_SORT TOOLBAR 16, 15
 BEGIN
     BUTTON      ID_SORT_MENU
@@ -181,52 +218,56 @@ BEGIN
     BUTTON      ID_PROPERTIES1
     BUTTON      ID_PROPERTIES2
 END
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
-LANGUAGE 4, 2
+
 
 /////////////////////////////////////////////////////////////////////////////
 //
-// 菜单
+// Menu
 //
 
 IDR_MAINFRAME MENU
 BEGIN
     POPUP "文件(&F)"
     BEGIN
-        MENUITEM "新建(&N)\tCtrl+N",                ID_FILE_NEW
-        MENUITEM "打开(&O)...\tCtrl+O",            ID_FILE_OPEN
+        MENUITEM "新建(&N)\tCtrl+N",              ID_FILE_NEW
+        MENUITEM "打开(&O)...\tCtrl+O",           ID_FILE_OPEN
         MENUITEM "关闭(&C)",                      ID_FILE_CLOSE
         MENUITEM SEPARATOR
-        MENUITEM "打印设置(&R)...",             ID_FILE_PRINT_SETUP
+        MENUITEM "打印设置(&R)...",                 ID_FILE_PRINT_SETUP
         MENUITEM SEPARATOR
-        MENUITEM "最近的文件",                 ID_FILE_MRU_FILE1,GRAYED
+        MENUITEM "最近的文件",                       ID_FILE_MRU_FILE1, GRAYED
         MENUITEM SEPARATOR
-        MENUITEM "退出(&X)",                       ID_APP_EXIT
+        MENUITEM "退出(&X)",                      ID_APP_EXIT
     END
     POPUP "视图(&V)"
     BEGIN
-        MENUITEM "状态栏(&S)",                 ID_VIEW_STATUS_BAR
-        MENUITEM "标题栏(&C)",                ID_VIEW_CAPTION_BAR
+        MENUITEM "状态栏(&S)",                     ID_VIEW_STATUS_BAR
+        MENUITEM "标题栏(&C)",                     ID_VIEW_CAPTION_BAR
         POPUP "应用程序外观(&A)"
         BEGIN
-            MENUITEM "Windows 2000(&2)",           ID_VIEW_APPLOOK_WIN_2000
-            MENUITEM "Office XP(&X)",              ID_VIEW_APPLOOK_OFF_XP
-            MENUITEM "Windows XP(&W)",             ID_VIEW_APPLOOK_WIN_XP
-            MENUITEM "Office 2003(&3)",            ID_VIEW_APPLOOK_OFF_2003
-            MENUITEM "Visual Studio 200&5",     ID_VIEW_APPLOOK_VS_2005
-            MENUITEM "Visual Studio 200&8",     ID_VIEW_APPLOOK_VS_2008
+            MENUITEM "Windows 2000(&2)",            ID_VIEW_APPLOOK_WIN_2000
+            MENUITEM "Office XP(&X)",               ID_VIEW_APPLOOK_OFF_XP
+            MENUITEM "Windows XP(&W)",              ID_VIEW_APPLOOK_WIN_XP
+            MENUITEM "Office 2003(&3)",             ID_VIEW_APPLOOK_OFF_2003
+            MENUITEM "Visual Studio 200&5",         ID_VIEW_APPLOOK_VS_2005
+            MENUITEM "Visual Studio 200&8",         ID_VIEW_APPLOOK_VS_2008
             POPUP "Office 2007(&7)"
             BEGIN
-                MENUITEM "蓝色样式(&B)",         ID_VIEW_APPLOOK_OFF_2007_BLUE
-                MENUITEM "黑色样式(&L)",        ID_VIEW_APPLOOK_OFF_2007_BLACK
-                MENUITEM "银色样式(&S)",       ID_VIEW_APPLOOK_OFF_2007_SILVER
-                MENUITEM "水绿色样式(&A)",         ID_VIEW_APPLOOK_OFF_2007_AQUA
+                MENUITEM "蓝色样式(&B)",                    ID_VIEW_APPLOOK_OFF_2007_BLUE
+                MENUITEM "黑色样式(&L)",                    ID_VIEW_APPLOOK_OFF_2007_BLACK
+                MENUITEM "银色样式(&S)",                    ID_VIEW_APPLOOK_OFF_2007_SILVER
+                MENUITEM "水绿色样式(&A)",                   ID_VIEW_APPLOOK_OFF_2007_AQUA
             END
         END
     END
     POPUP "帮助(&H)"
     BEGIN
-        MENUITEM "关于 SATHelper(&A)...",          ID_APP_ABOUT
+        MENUITEM "关于 SATHelper(&A)...",         ID_APP_ABOUT
+    END
+    POPUP "TrayMenu"
+    BEGIN
+        MENUITEM "重连",						  ID_TRAYMENU_RECONNECT
+        MENUITEM "退出",						  ID_TRAYMENU_EXIT
     END
 END
 
@@ -234,85 +275,82 @@ IDR_SATHelperTYPE MENU
 BEGIN
     POPUP "文件(&F)"
     BEGIN
-        MENUITEM "新建(&N)\tCtrl+N",                ID_FILE_NEW
-        MENUITEM "打开(&O)...\tCtrl+O",            ID_FILE_OPEN
+        MENUITEM "新建(&N)\tCtrl+N",              ID_FILE_NEW
+        MENUITEM "打开(&O)...\tCtrl+O",           ID_FILE_OPEN
         MENUITEM "关闭(&C)",                      ID_FILE_CLOSE
-        MENUITEM "保存(&S)\tCtrl+S",               ID_FILE_SAVE
-        MENUITEM "另存为(&A)...",                 ID_FILE_SAVE_AS
+        MENUITEM "保存(&S)\tCtrl+S",              ID_FILE_SAVE
+        MENUITEM "另存为(&A)...",                  ID_FILE_SAVE_AS
         MENUITEM SEPARATOR
         MENUITEM "打印(&P)...\tCtrl+P",           ID_FILE_PRINT
-        MENUITEM "打印预览(&V)",              ID_FILE_PRINT_PREVIEW
-        MENUITEM "打印设置(&R)...",             ID_FILE_PRINT_SETUP
+        MENUITEM "打印预览(&V)",                    ID_FILE_PRINT_PREVIEW
+        MENUITEM "打印设置(&R)...",                 ID_FILE_PRINT_SETUP
         MENUITEM SEPARATOR
-        MENUITEM "最近的文件",                 ID_FILE_MRU_FILE1,GRAYED
+        MENUITEM "最近的文件",                       ID_FILE_MRU_FILE1, GRAYED
         MENUITEM SEPARATOR
-        MENUITEM "退出(&X)",                       ID_APP_EXIT
+        MENUITEM "退出(&X)",                      ID_APP_EXIT
     END
     POPUP "编辑(&E)"
     BEGIN
-        MENUITEM "撤消(&U)\tCtrl+Z",               ID_EDIT_UNDO
+        MENUITEM "撤消(&U)\tCtrl+Z",              ID_EDIT_UNDO
         MENUITEM SEPARATOR
-        MENUITEM "剪切(&T)\tCtrl+X",                ID_EDIT_CUT
-        MENUITEM "复制(&C)\tCtrl+C",               ID_EDIT_COPY
+        MENUITEM "剪切(&T)\tCtrl+X",              ID_EDIT_CUT
+        MENUITEM "复制(&C)\tCtrl+C",              ID_EDIT_COPY
         MENUITEM "粘贴(&P)\tCtrl+V",              ID_EDIT_PASTE
     END
     POPUP "视图(&V)"
     BEGIN
-        MENUITEM "状态栏(&S)",                 ID_VIEW_STATUS_BAR
-        MENUITEM "标题栏(&C)",                ID_VIEW_CAPTION_BAR
+        MENUITEM "状态栏(&S)",                     ID_VIEW_STATUS_BAR
+        MENUITEM "标题栏(&C)",                     ID_VIEW_CAPTION_BAR
         POPUP "应用程序外观(&A)"
         BEGIN
-            MENUITEM "Windows 2000(&2)",           ID_VIEW_APPLOOK_WIN_2000
-            MENUITEM "Office XP(&X)",              ID_VIEW_APPLOOK_OFF_XP
-            MENUITEM "Windows XP(&W)",             ID_VIEW_APPLOOK_WIN_XP
-            MENUITEM "Office 2003(&3)",            ID_VIEW_APPLOOK_OFF_2003
-            MENUITEM "Visual Studio 200&5",     ID_VIEW_APPLOOK_VS_2005
-            MENUITEM "Visual Studio 200&8",     ID_VIEW_APPLOOK_VS_2008
+            MENUITEM "Windows 2000(&2)",            ID_VIEW_APPLOOK_WIN_2000
+            MENUITEM "Office XP(&X)",               ID_VIEW_APPLOOK_OFF_XP
+            MENUITEM "Windows XP(&W)",              ID_VIEW_APPLOOK_WIN_XP
+            MENUITEM "Office 2003(&3)",             ID_VIEW_APPLOOK_OFF_2003
+            MENUITEM "Visual Studio 200&5",         ID_VIEW_APPLOOK_VS_2005
+            MENUITEM "Visual Studio 200&8",         ID_VIEW_APPLOOK_VS_2008
             POPUP "Office 2007(&7)"
             BEGIN
-                MENUITEM "蓝色样式(&B)",         ID_VIEW_APPLOOK_OFF_2007_BLUE
-                MENUITEM "黑色样式(&L)",        ID_VIEW_APPLOOK_OFF_2007_BLACK
-                MENUITEM "银色样式(&S)",       ID_VIEW_APPLOOK_OFF_2007_SILVER
-                MENUITEM "水绿色样式(&A)",         ID_VIEW_APPLOOK_OFF_2007_AQUA
+                MENUITEM "蓝色样式(&B)",                    ID_VIEW_APPLOOK_OFF_2007_BLUE
+                MENUITEM "黑色样式(&L)",                    ID_VIEW_APPLOOK_OFF_2007_BLACK
+                MENUITEM "银色样式(&S)",                    ID_VIEW_APPLOOK_OFF_2007_SILVER
+                MENUITEM "水绿色样式(&A)",                   ID_VIEW_APPLOOK_OFF_2007_AQUA
             END
         END
     END
     POPUP "窗口(&W)"
     BEGIN
-        MENUITEM "新建窗口(&N)",                 ID_WINDOW_NEW
+        MENUITEM "新建窗口(&N)",                    ID_WINDOW_NEW
     END
     POPUP "帮助(&H)"
     BEGIN
-        MENUITEM "关于 SATHelper(&A)...",          ID_APP_ABOUT
+        MENUITEM "关于 SATHelper(&A)...",         ID_APP_ABOUT
     END
 END
 
-
-
-
 IDR_POPUP_EDIT MENU
 BEGIN
-	POPUP "编辑"
-	BEGIN
-		MENUITEM "剪切(&T)\tCtrl+X",            ID_EDIT_CUT
-		MENUITEM "复制(&C)\tCtrl+C",           ID_EDIT_COPY
-		MENUITEM "粘贴(&P)\tCtrl+V",          ID_EDIT_PASTE
+    POPUP "编辑"
+    BEGIN
+        MENUITEM "剪切(&T)\tCtrl+X",              ID_EDIT_CUT
+        MENUITEM "复制(&C)\tCtrl+C",              ID_EDIT_COPY
+        MENUITEM "粘贴(&P)\tCtrl+V",              ID_EDIT_PASTE
     END
 END
 
 IDR_WINDOWS_MENU MENU
 BEGIN
-    MENUITEM "新建窗口(&N)",                 ID_WINDOW_NEW
+    MENUITEM "新建窗口(&N)",                    ID_WINDOW_NEW
 END
 
 IDR_POPUP_SORT MENU
 BEGIN
     POPUP "排序"
     BEGIN
-        MENUITEM "按字母顺序排序(&S)",         ID_SORTING_SORTALPHABETIC
-        MENUITEM "按类型排序(&T)",               ID_SORTING_SORTBYTYPE
-        MENUITEM "按访问排序(&E)",             ID_SORTING_SORTBYACCESS
-        MENUITEM "按类型分组(&Y)",              ID_SORTING_GROUPBYTYPE
+        MENUITEM "按字母顺序排序(&S)",                 ID_SORTING_SORTALPHABETIC
+        MENUITEM "按类型排序(&T)",                   ID_SORTING_SORTBYTYPE
+        MENUITEM "按访问排序(&E)",                   ID_SORTING_SORTBYACCESS
+        MENUITEM "按类型分组(&Y)",                   ID_SORTING_GROUPBYTYPE
     END
 END
 
@@ -320,16 +358,16 @@ IDR_POPUP_EXPLORER MENU
 BEGIN
     POPUP "资源管理器"
     BEGIN
-        MENUITEM "打开(&O)",                       ID_OPEN
-        MENUITEM "打开方式(&W)....",              ID_OPEN_WITH
+        MENUITEM "打开(&O)",                      ID_OPEN
+        MENUITEM "打开方式(&W)....",                ID_OPEN_WITH
         MENUITEM SEPARATOR
-        MENUITEM "编译(&C)",                    ID_DUMMY_COMPILE
+        MENUITEM "编译(&C)",                      ID_DUMMY_COMPILE
         MENUITEM SEPARATOR
-        MENUITEM "剪切(&T)\tCtrl+X",                ID_EDIT_CUT
-        MENUITEM "复制(&C)\tCtrl+C",               ID_EDIT_COPY
-        MENUITEM "移除(&R)",                     ID_EDIT_CLEAR
+        MENUITEM "剪切(&T)\tCtrl+X",              ID_EDIT_CUT
+        MENUITEM "复制(&C)\tCtrl+C",              ID_EDIT_COPY
+        MENUITEM "移除(&R)",                      ID_EDIT_CLEAR
         MENUITEM SEPARATOR
-        MENUITEM "属性(&P)...",              ID_PROPERTIES
+        MENUITEM "属性(&P)...",                   ID_PROPERTIES
     END
 END
 
@@ -337,62 +375,61 @@ IDR_OUTPUT_POPUP MENU
 BEGIN
     POPUP "弹出项"
     BEGIN
-        MENUITEM "复制(&C)",                       ID_EDIT_COPY
+        MENUITEM "复制(&C)",                      ID_EDIT_COPY
         MENUITEM "清除(&C)",                      ID_EDIT_CLEAR
         MENUITEM SEPARATOR
-        MENUITEM "隐藏(&H)",                       ID_VIEW_OUTPUTWND
+        MENUITEM "隐藏(&H)",                      ID_VIEW_OUTPUTWND
     END
 END
 
 IDR_HELP_MENU MENU
 BEGIN
-    MENUITEM "关于 SATHelper(&A)...",          ID_APP_ABOUT
+    MENUITEM "关于 SATHelper(&A)...",         ID_APP_ABOUT
 END
 
 IDR_THEME_MENU MENU
 BEGIN
-    MENUITEM "Office 2007 (蓝色样式)(&B)",       ID_VIEW_APPLOOK_OFF_2007_BLUE
+    MENUITEM "Office 2007 (蓝色样式)(&B)",      ID_VIEW_APPLOOK_OFF_2007_BLUE
     MENUITEM "Office 2007 (黑色样式)(&L)",      ID_VIEW_APPLOOK_OFF_2007_BLACK
-    MENUITEM "Office 2007 (银色样式)(&S)",     ID_VIEW_APPLOOK_OFF_2007_SILVER
-    MENUITEM "Office 2007 (水绿色样式)(&A)",       ID_VIEW_APPLOOK_OFF_2007_AQUA
-    MENUITEM "Windows 7(&D)",                      ID_VIEW_APPLOOK_WINDOWS_7
+    MENUITEM "Office 2007 (银色样式)(&S)",      ID_VIEW_APPLOOK_OFF_2007_SILVER
+    MENUITEM "Office 2007 (水绿色样式)(&A)",     ID_VIEW_APPLOOK_OFF_2007_AQUA
+    MENUITEM "Windows 7(&D)",               ID_VIEW_APPLOOK_WINDOWS_7
 END
 
+
 /////////////////////////////////////////////////////////////////////////////
 //
-// 加速器
+// Accelerator
 //
 
 IDR_MAINFRAME ACCELERATORS
 BEGIN
-    "N",            ID_FILE_NEW,            VIRTKEY,CONTROL
-    "O",            ID_FILE_OPEN,           VIRTKEY,CONTROL
-    "S",            ID_FILE_SAVE,           VIRTKEY,CONTROL
-    "P",            ID_FILE_PRINT,          VIRTKEY,CONTROL
-	"Z",            ID_EDIT_UNDO,           VIRTKEY,CONTROL
-	"X",            ID_EDIT_CUT,            VIRTKEY,CONTROL
-	"C",            ID_EDIT_COPY,           VIRTKEY,CONTROL
-	"V",            ID_EDIT_PASTE,          VIRTKEY,CONTROL
-    VK_BACK,        ID_EDIT_UNDO,           VIRTKEY,ALT
-    VK_DELETE,      ID_EDIT_CUT,            VIRTKEY,SHIFT
-    VK_INSERT,      ID_EDIT_COPY,           VIRTKEY,CONTROL
-    VK_INSERT,      ID_EDIT_PASTE,          VIRTKEY,SHIFT
-    VK_F6,          ID_NEXT_PANE,           VIRTKEY
-    VK_F6,          ID_PREV_PANE,           VIRTKEY,SHIFT
+    "N",            ID_FILE_NEW,            VIRTKEY, CONTROL
+    "O",            ID_FILE_OPEN,           VIRTKEY, CONTROL
+    "S",            ID_FILE_SAVE,           VIRTKEY, CONTROL
+    "P",            ID_FILE_PRINT,          VIRTKEY, CONTROL
+    "Z",            ID_EDIT_UNDO,           VIRTKEY, CONTROL
+    "X",            ID_EDIT_CUT,            VIRTKEY, CONTROL
+    "C",            ID_EDIT_COPY,           VIRTKEY, CONTROL
+    "V",            ID_EDIT_PASTE,          VIRTKEY, CONTROL
+    VK_BACK,        ID_EDIT_UNDO,           VIRTKEY, ALT
+    VK_DELETE,      ID_EDIT_CUT,            VIRTKEY, SHIFT
+    VK_INSERT,      ID_EDIT_COPY,           VIRTKEY, CONTROL
+    VK_INSERT,      ID_EDIT_PASTE,          VIRTKEY, SHIFT
+    VK_F6,          ID_NEXT_PANE,           VIRTKEY 
+    VK_F6,          ID_PREV_PANE,           VIRTKEY, SHIFT
 END
 
 
-
-
 /////////////////////////////////////////////////////////////////////////////
 //
-// 对话框
+// Dialog
 //
 
 IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "关于 SATHelper"
-FONT 9, "MS Shell Dlg"
+FONT 9, "MS Shell Dlg", 0, 0, 0x1
 BEGIN
     ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20
     LTEXT           "SATHelper,版本 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX
@@ -401,24 +438,23 @@ BEGIN
 END
 
 
-
 /////////////////////////////////////////////////////////////////////////////
 //
-// 版本
+// Version
 //
 
-VS_VERSION_INFO     VERSIONINFO
-  FILEVERSION       1,0,0,1
-  PRODUCTVERSION    1,0,0,1
- FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
- FILEFLAGS VS_FF_DEBUG
+ FILEFLAGS 0x1L
 #else
  FILEFLAGS 0x0L
 #endif
- FILEOS VOS_NT_WINDOWS32
- FILETYPE VFT_APP
- FILESUBTYPE VFT2_UNKNOWN
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
 BEGIN
     BLOCK "StringFileInfo"
     BEGIN
@@ -426,20 +462,21 @@ BEGIN
         BEGIN
             VALUE "CompanyName", "TODO:  <公司名>"
             VALUE "FileDescription", "SATHelper"
-            VALUE "FileVersion",     "1.0.0.1"
-            VALUE "InternalName",    "SATHelper.exe"
+            VALUE "FileVersion", "1.0.0.1"
+            VALUE "InternalName", "SATHelper.exe"
             VALUE "LegalCopyright", "TODO:  (C) <公司名>。  保留所有权利。"
-            VALUE "OriginalFilename","SATHelper.exe"
+            VALUE "OriginalFilename", "SATHelper.exe"
             VALUE "ProductName", "TODO:  <产品名>"
-            VALUE "ProductVersion",  "1.0.0.1"
+            VALUE "ProductVersion", "1.0.0.1"
         END
     END
     BLOCK "VarFileInfo"
     BEGIN
-        VALUE "Translation", 0x0804, 1200
+        VALUE "Translation", 0x804, 1200
     END
 END
 
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // DESIGNINFO
@@ -458,26 +495,38 @@ BEGIN
 END
 #endif    // APSTUDIO_INVOKED
 
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Ribbon
+//
+
+IDR_RIBBON              RT_RIBBON_XML           "res\\ribbon.mfcribbon-ms"
+
+
 /////////////////////////////////////////////////////////////////////////////
 //
-// 字符串表
+// String Table
 //
 
 STRINGTABLE
 BEGIN
-    IDP_OLE_INIT_FAILED       "OLE 初始化失败。  请确保 OLE 库是正确的版本。"
+    IDP_OLE_INIT_FAILED     "OLE 初始化失败。  请确保 OLE 库是正确的版本。"
 END
+
 STRINGTABLE
 BEGIN
-// 非 Mac 应用程序将移除额外的两个子字符串
     IDR_MAINFRAME           "SATHelper"
-    IDR_SATHelperTYPE         "\nSATHelper\nSATHelper\n\n\nSATHelper.Document\nSATHelper.Document"
+    IDR_SATHelperTYPE       "\nSATHelper\nSATHelper\n\n\nSATHelper.Document\nSATHelper.Document"
+    ID_WINDOW_MANAGER       "窗口(&W)..."
 END
+
 STRINGTABLE
 BEGIN
     AFX_IDS_APP_TITLE       "SATHelper"
     AFX_IDS_IDLEMESSAGE     "就绪"
 END
+
 STRINGTABLE
 BEGIN
     ID_INDICATOR_EXT        "EXT"
@@ -487,6 +536,7 @@ BEGIN
     ID_INDICATOR_OVR        "OVR"
     ID_INDICATOR_REC        "REC"
 END
+
 STRINGTABLE
 BEGIN
     ID_FILE_NEW             "创建新文档\n新建"
@@ -496,11 +546,19 @@ BEGIN
     ID_FILE_SAVE_AS         "用新名称保存活动文档\n另存为"
     ID_FILE_PAGE_SETUP      "更改打印选项\n页面设置"
     ID_FILE_PRINT_SETUP     "更改打印机选项和打印选项\n打印设置"
-    ID_FILE_PRINT_DIRECT    "使用当前选项打印活动文档\n快速打印"
     ID_FILE_PRINT           "打印活动文档\n打印"
+    ID_FILE_PRINT_DIRECT    "使用当前选项打印活动文档\n快速打印"
     ID_FILE_PRINT_PREVIEW   "显示整页\n打印预览"
+END
+
+STRINGTABLE
+BEGIN
     ID_APP_ABOUT            "显示程序信息、版本号和版权信息\n关于"
     ID_APP_EXIT             "退出应用程序;提示保存文档\n退出"
+END
+
+STRINGTABLE
+BEGIN
     ID_FILE_MRU_FILE1       "打开此文档"
     ID_FILE_MRU_FILE2       "打开此文档"
     ID_FILE_MRU_FILE3       "打开此文档"
@@ -517,14 +575,26 @@ BEGIN
     ID_FILE_MRU_FILE14      "打开此文档"
     ID_FILE_MRU_FILE15      "打开此文档"
     ID_FILE_MRU_FILE16      "打开此文档"
+END
+
+STRINGTABLE
+BEGIN
     ID_NEXT_PANE            "切换到下一个窗格\n下一窗格"
     ID_PREV_PANE            "切换回上一个窗格\n上一窗格"
+END
+
+STRINGTABLE
+BEGIN
     ID_WINDOW_NEW           "为活动文档打开另一个窗口\n新建窗口"
     ID_WINDOW_ARRANGE       "在窗口底部排列图标\n排列图标"
     ID_WINDOW_CASCADE       "以重叠方式排列窗口\n层叠窗口"
     ID_WINDOW_TILE_HORZ     "以不重叠的平铺方式排列窗口\n平铺窗口"
     ID_WINDOW_TILE_VERT     "以不重叠的平铺方式排列窗口\n平铺窗口"
     ID_WINDOW_SPLIT         "将活动窗口拆分为多个窗格\n拆分"
+END
+
+STRINGTABLE
+BEGIN
     ID_EDIT_CLEAR           "清除所选内容\n清除"
     ID_EDIT_CLEAR_ALL       "清除全部内容\n全部清除"
     ID_EDIT_COPY            "复制所选内容,将其放入剪贴板\n复制"
@@ -536,8 +606,16 @@ BEGIN
     ID_EDIT_SELECT_ALL      "选定整个文档\n全选"
     ID_EDIT_UNDO            "撤消上一操作\n撤消"
     ID_EDIT_REDO            "重做上次撤消的操作\n重做"
+END
+
+STRINGTABLE
+BEGIN
     ID_VIEW_TOOLBAR         "显示或隐藏工具栏\n切换工具栏"
     ID_VIEW_STATUS_BAR      "显示或隐藏状态栏\n切换状态栏"
+END
+
+STRINGTABLE
+BEGIN
     ID_VIEW_CAPTION_BAR     "显示或隐藏标题栏\n切换标题栏"
 END
 
@@ -550,65 +628,93 @@ BEGIN
     AFX_IDS_SCNEXTWINDOW    "切换到下一个文档窗口"
     AFX_IDS_SCPREVWINDOW    "切换到上一个文档窗口"
     AFX_IDS_SCCLOSE         "关闭活动窗口并提示保存文档"
+END
+
+STRINGTABLE
+BEGIN
     AFX_IDS_SCRESTORE       "将窗口恢复到正常大小"
     AFX_IDS_SCTASKLIST      "激活任务列表"
     AFX_IDS_MDICHILD        "激活此窗口"
-    AFX_IDS_PREVIEW_CLOSE   "关闭打印预览模式\n取消预览"
 END
 
+STRINGTABLE
+BEGIN
+    AFX_IDS_PREVIEW_CLOSE   "关闭打印预览模式\n取消预览"
+END
 
 STRINGTABLE
 BEGIN
     IDS_STATUS_PANE1        "窗格 1"
     IDS_STATUS_PANE2        "窗格 2"
-    ID_WINDOW_MANAGER       "窗口(&W)..."
+END
+
+STRINGTABLE
+BEGIN
     IDS_FILE_VIEW           "文件视图"
     IDS_CLASS_VIEW          "类视图"
-    IDS_EXPLORER            "资源管理器"
     IDS_OUTPUT_WND          "输出"
+    IDS_PROPERTIES_WND      "属性"
+END
+
+STRINGTABLE
+BEGIN
+    IDS_EXPLORER            "资源管理器"
+    IDS_EDIT_MENU           "编辑"
+END
+
+STRINGTABLE
+BEGIN
     IDS_BUILD_TAB           "生成"
     IDS_DEBUG_TAB           "调试"
     IDS_FIND_TAB            "查找"
-    IDS_PROPERTIES_WND      "属性"
+END
+
+STRINGTABLE
+BEGIN
     IDS_MYCALENDARS         "我的日历"
     IDS_CALENDAR            "日历"
     IDS_SHORTCUTS           "快捷方式"
     IDS_FOLDERS             "文件夹"
+END
+
+STRINGTABLE
+BEGIN
     IDS_OUTLOOKBAR          "Outlook 栏"
+END
+
+STRINGTABLE
+BEGIN
     IDS_CAPTION_BUTTON      "选项..."
     IDS_CAPTION_BUTTON_TIP  "单击此处查看其他选项"
     IDS_CAPTION_TEXT        "这是标题栏,可在其中向用户显示消息。"
     IDS_CAPTION_IMAGE_TIP   "重要事项"
     IDS_CAPTION_IMAGE_TEXT  "这是向用户显示的信息性消息。"
-    IDS_EDIT_MENU           "编辑"
 END
 
+#endif    // 中文(简体,中国) resources
 /////////////////////////////////////////////////////////////////////////////
-//
-// 功能区
-//
 
-IDR_RIBBON             RT_RIBBON_XML           "res\\ribbon.mfcribbon-ms"
 
-#endif
 
 #ifndef APSTUDIO_INVOKED
 /////////////////////////////////////////////////////////////////////////////
 //
-// 从 TEXTINCLUDE 3 资源生成。
+// Generated from the TEXTINCLUDE 3 resource.
 //
-
 #define _AFX_NO_OLE_RESOURCES
 #define _AFX_NO_TRACKER_RESOURCES
 #define _AFX_NO_PROPERTY_RESOURCES
 
 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
 LANGUAGE 4, 2
-#include "res\\SATHelper.rc2"  // 非 Microsoft Visual C++ 编辑的资源
-#include "l.CHS\\afxres.rc"      // 标准组件
-#include "l.CHS\\afxprint.rc"  // 打印/打印预览资源
+#include "res\SATHelper.rc2"  // 闈?Microsoft Visual C++ 缂栬緫鐨勮祫婧?
+#include "l.CHS\afxres.rc"      // 鏍囧噯缁勪欢
+#include "l.CHS\afxprint.rc"    // 鎵撳嵃/鎵撳嵃棰勮璧勬簮
 #if !defined(_AFXDLL)
-#include "l.CHS\\afxribbon.rc"        // MFC 功能区和控件条资源
+#include "l.CHS\afxribbon.rc"        // MFC 鍔熻兘鍖哄拰鎺у埗鏉¤祫婧?
 #endif
 #endif
-#endif    // 不是 APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

+ 846 - 2
SATHelper/SATHelper/SATHelperView.cpp

@@ -22,12 +22,223 @@
 
 #include "SATHelperDoc.h"
 #include "SATHelperView.h"
+#include "MainFrm.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
 #endif
 
 
+CMemoryClient g_ub530;
+static CMainFrame* g_pMainFrame = NULL;
+
+
+VOID Dbg(CHAR* pszStr, ...)
+{
+	char szData[MAX_PATH] = "[SC] ";
+	va_list args;
+	va_start(args, pszStr);
+	_vsnprintf_s(szData + 5, MAX_PATH - 5, MAX_PATH - 6, pszStr, args);
+	va_end(args);
+	strcat_s(szData, "\n");
+	OutputDebugStringA(szData);
+}
+
+//  FORMAT CHANGED CALLBACK FUNCTION
+//
+QRETURN on_process_format_changed(PVOID pDevice, ULONG nVideoInput, ULONG nAudioInput, ULONG nVideoWidth, ULONG nVideoHeight, BOOL bVideoIsInterleaved, double dVideoFrameRate, ULONG nAudioChannels, ULONG nAudioBitsPerSample, ULONG nAudioSampleFrequency, PVOID pUserData)
+{
+	//Dbg("format changed Detected  \n");
+	CSATHelperView* pView = (CSATHelperView*)pUserData;
+	if (pView == NULL) { return QCAP_RT_OK; }
+	if (pView->GetSafeHwnd() == NULL) { return QCAP_RT_OK; }
+
+	pView->m_nVideoWidth = nVideoWidth;
+	pView->m_nVideoHeight = nVideoHeight;
+	pView->m_bVideoIsInterleaved = bVideoIsInterleaved;
+	pView->m_dVideoFrameRate = dVideoFrameRate;
+	pView->m_nAudioChannels = nAudioChannels;
+	pView->m_nAudioBitsPerSample = nAudioBitsPerSample;
+	pView->m_nAudioSampleFrequency = nAudioSampleFrequency;
+	// OUTPUT FORMAT CHANGED MESSAGE
+	//
+	CHAR strVideoInput[MAX_PATH] = { 0 };
+	CHAR strAudioInput[MAX_PATH] = { 0 };
+	CHAR strFrameType[MAX_PATH] = { 0 };
+	UINT nVH = 0;
+
+	if (nVideoInput == 0) { sprintf_s(strVideoInput, "COMPOSITE"); }
+	if (nVideoInput == 1) { sprintf_s(strVideoInput, "SVIDEO"); }
+	if (nVideoInput == 2) { sprintf_s(strVideoInput, "HDMI"); }
+	if (nVideoInput == 3) { sprintf_s(strVideoInput, "DVI_D"); }
+	if (nVideoInput == 4) { sprintf_s(strVideoInput, "COMPONENTS (YCBCR)"); }
+	if (nVideoInput == 5) { sprintf_s(strVideoInput, "DVI_A (RGB / VGA)"); }
+	if (nVideoInput == 6) { sprintf_s(strVideoInput, "SDI"); }
+	if (nVideoInput == 7) { sprintf_s(strVideoInput, "AUTO"); }
+	if (nAudioInput == 0) { sprintf_s(strAudioInput, "EMBEDDED_AUDIO"); }
+	if (nAudioInput == 1) { sprintf_s(strAudioInput, "LINE_IN"); }
+
+	if (bVideoIsInterleaved == TRUE) { nVH = nVideoHeight / 2; }
+	else { nVH = nVideoHeight; }
+
+	if (bVideoIsInterleaved == TRUE) { sprintf_s(strFrameType, " I "); }
+	else { sprintf_s(strFrameType, " P "); }
+
+	pView->m_strFormatChangedOutput.Format(
+		_T("INFO : %d x %d%s @%2.3f FPS , %d CH x %d BITS x %d HZ ,  VIDEO INPUT : %s ,  AUDIO INPUT : %s"),
+		nVideoWidth,
+		nVH,
+		strFrameType,
+		dVideoFrameRate,
+		nAudioChannels,
+		nAudioBitsPerSample,
+		nAudioSampleFrequency,
+		strVideoInput,
+		strAudioInput
+	);
+	Global::WriteTextLog(_T("采集卡格式变更:%d x %d%s @%2.3f FPS , %d CH x %d BITS x %d HZ ,  视频输入源 : %s ,  音频输入源 : %s"),
+		nVideoWidth,
+		nVH,
+		strFrameType,
+		dVideoFrameRate,
+		nAudioChannels,
+		nAudioBitsPerSample,
+		nAudioSampleFrequency,
+		strVideoInput,
+		strAudioInput);
+
+	::SendMessage(g_pMainFrame->m_hWnd, MSG_STATUS_BAR, (WPARAM)&pView->m_strFormatChangedOutput, ID_STATUSBAR_PANE1);
+
+	// NO SOURCE
+	//
+	if (nVideoWidth == 0 &&
+		nVideoHeight == 0 &&
+		dVideoFrameRate == 0.0 &&
+		nAudioChannels == 0 &&
+		nAudioBitsPerSample == 0 &&
+		nAudioSampleFrequency == 0)
+	{
+		pView->m_bNoSignal = TRUE;
+	}
+	else
+	{
+		pView->m_bNoSignal = FALSE;
+	}
+
+	pView->SetTimer(0x00000000, 1, NULL);
+
+	return QCAP_RT_OK;
+}
+
+// NO SIGNAL DETEACTED CALLBACK FUNCTION
+//
+QRETURN on_process_no_signal_detected(PVOID pDevice, ULONG nVideoInput, ULONG nAudioInput, PVOID pUserData)
+{
+	AFX_MANAGE_STATE(AfxGetStaticModuleState());
+	CSATHelperView* pView = (CSATHelperView*)pUserData;
+
+	//Dbg("No Signal Detected  \n");
+	if (pView == NULL) { return QCAP_RT_OK; }
+	if (pView->GetSafeHwnd() == NULL) { return QCAP_RT_OK; }
+
+	//pView->SetRibbonStatusBarText("当前采集卡无信号。", ID_STATUSBAR_PANE1);
+	Global::WriteTextLog(_T("当前采集卡无信号"));
+	::SendMessage(g_pMainFrame->m_hWnd, MSG_STATUS_BAR, (WPARAM)&CString("当前采集卡无信号"), ID_STATUSBAR_PANE1);
+
+	pView->m_bNoSignal = TRUE;
+	pView->SetTimer(0x00000000, 1, NULL);
+
+	return QCAP_RT_OK;
+}
+
+// SIGNAL REMOVED CALLBACK FUNCTION
+//
+QRETURN on_process_signal_removed(PVOID pDevice, ULONG nVideoInput, ULONG nAudioInput, PVOID pUserData)
+{
+	AFX_MANAGE_STATE(AfxGetStaticModuleState());
+	CSATHelperView* pView = (CSATHelperView*)pUserData;
+	if (pView == NULL) { return QCAP_RT_OK; }
+	if (pView->GetSafeHwnd() == NULL) { return QCAP_RT_OK; }
+
+	//pView->SetRibbonStatusBarText("当前采集卡信号被移除。", ID_STATUSBAR_PANE1);
+	Global::WriteTextLog(_T("当前采集卡信号被移除"));
+	::SendMessage(g_pMainFrame->m_hWnd, MSG_STATUS_BAR, (WPARAM)&CString("当前采集卡信号被移除"), ID_STATUSBAR_PANE1);
+
+	pView->m_bNoSignal = TRUE;
+	pView->SetTimer(0x00000000, 1, NULL);
+
+	return QCAP_RT_OK;
+}
+
+// PREVIEW VIDEO CALLBACK FUNCTION
+//
+QRETURN on_process_preview_video_buffer(PVOID pDevice, double dSampleTime, BYTE* pFrameBuffer, ULONG nFrameBufferLen, PVOID pUserData)
+{
+	CSATHelperView* pView = (CSATHelperView*)pUserData;
+	if (pView)
+	{
+		// 尝试加锁;
+		if (!pView->m_mut_cpature.try_lock())
+		{
+#ifdef DEBUG
+			OutputDebugStringA("!pView->m_mut_cpature.try_lock()\n");
+#endif
+			return QCAP_RT_OK;
+		}
+
+		// 是否触发截图;
+		if (pView->m_bCaptureImage)
+		{
+			// 加锁;
+			std::lock_guard<std::mutex> lk(pView->m_mut_thread);
+			// 复制数据;
+			pView->m_dwBufferLen = nFrameBufferLen;
+			pView->m_pBuffer = new BYTE[nFrameBufferLen];
+			memcpy(pView->m_pBuffer, pFrameBuffer, nFrameBufferLen);
+			// 通知线程保存图片;
+			pView->m_thread_cond.notify_one();
+			// 恢复截图标记,防止重复截图;
+			pView->m_bCaptureImage = FALSE;
+#ifdef DEBUG
+			OutputDebugStringA("preview_video_buffer:pView->m_bCaptureImage\n");
+#endif
+		}
+
+		// 解锁;
+		pView->m_mut_cpature.unlock();
+	}
+
+	return QCAP_RT_OK;
+}
+
+// PREVIEW AUDIO CALLBACK FUNCTION
+//
+QRETURN on_process_preview_audio_buffer(PVOID pDevice, double dSampleTime, BYTE* pFrameBuffer, ULONG nFrameBufferLen, PVOID pUserData)
+{
+	return QCAP_RT_OK;
+}
+
+// VIDEO HARDARE ENCODER CALLBACK FUNCTION
+//
+QRETURN on_process_hardware_encoder_video_buffer(PVOID pDevice, UINT iRecNum, double dSampleTime, BYTE* pFrameBuffer, ULONG nFrameBufferLen, BOOL bIsKeyFrame, PVOID pUserData)
+{
+	return QCAP_RT_OK;
+}
+
+QRETURN on_process_snapshot_done(PVOID pDevice, CHAR* pszFilePathName, PVOID pUserData)
+{
+	return QCAP_RT_OK;
+}
+
+QRETURN on_process_snapshot_stream(PVOID pDevice, CHAR* pszFilePathName, BYTE* pStreamBuffer, ULONG nStreamBufferLen, PVOID pUserData)
+{
+	// 注意:在调用本回调函数前,已经保存了图片!
+	CSATHelperView* pView = (CSATHelperView*)pUserData;
+	if (pView->m_bHoriontal || pView->m_bVertically)
+		Global::SaveImgByRotate(pszFilePathName, pStreamBuffer, nStreamBufferLen, pView->m_bHoriontal, pView->m_bVertically);
+
+	return QCAP_RT_OK;
+}
 // CSATHelperView
 
 IMPLEMENT_DYNCREATE(CSATHelperView, CView)
@@ -39,6 +250,7 @@ BEGIN_MESSAGE_MAP(CSATHelperView, CView)
 	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CSATHelperView::OnFilePrintPreview)
 	ON_WM_CONTEXTMENU()
 	ON_WM_RBUTTONUP()
+	ON_WM_CREATE()
 END_MESSAGE_MAP()
 
 // CSATHelperView 构造/析构
@@ -46,11 +258,24 @@ END_MESSAGE_MAP()
 CSATHelperView::CSATHelperView() noexcept
 {
 	// TODO: 在此处添加构造代码
-
+	m_hVideoDevice = NULL;
+	m_bIsRecord = FALSE;
+	m_bNoSignal = FALSE;
+	m_bVertically = FALSE;
+	m_bHoriontal = FALSE;
+	m_bAppQuit = FALSE;
+	m_pBuffer = NULL;
+	m_bCaptureImage = FALSE;
+	m_dwBufferLen = 0;
+	m_bIsMp4 = TRUE;
+	m_bSupportGPU = FALSE;
 }
 
 CSATHelperView::~CSATHelperView()
 {
+	g_ub530.EndOfThread();
+	m_bAppQuit = TRUE;
+	HwUninitialize();
 }
 
 BOOL CSATHelperView::PreCreateWindow(CREATESTRUCT& cs)
@@ -63,13 +288,48 @@ BOOL CSATHelperView::PreCreateWindow(CREATESTRUCT& cs)
 
 // CSATHelperView 绘图
 
-void CSATHelperView::OnDraw(CDC* /*pDC*/)
+void CSATHelperView::OnDraw(CDC* pDC)
 {
 	CSATHelperDoc* pDoc = GetDocument();
 	ASSERT_VALID(pDoc);
 	if (!pDoc)
 		return;
 
+	// TO FILL IN THE TEXT 
+	//
+	if (m_hVideoDevice == 0 || m_bNoSignal) {
+
+		CFont font;
+		ULONG nFontSize = 300;
+		font.CreatePointFont(nFontSize, TEXT("Arial"), NULL);
+		HFONT hOldFont = (HFONT)pDC->SelectObject(&font);
+		pDC->SetBkMode(TRANSPARENT);
+		pDC->SetTextColor(RGB(255, 255, 255));
+
+		CRect rect_client;
+		GetClientRect(&rect_client);
+
+		CString string = _T("");
+		if (m_hVideoDevice == 0)
+		{
+			CBrush brush_fill_rect(RGB(0, 0, 0));
+			pDC->FillRect(&rect_client, &brush_fill_rect);
+			string = TEXT("No Device");
+			//g_pMainFrame->SetRibbonStatusBarText("当前采集卡设备被移除。", ID_STATUSBAR_PANE1);
+		}
+		else if (m_bNoSignal)
+		{
+			CBrush brush_fill_rect(RGB(0, 0, 255));
+			pDC->FillRect(&rect_client, &brush_fill_rect);
+			string = TEXT("No Source");
+			//g_pMainFrame->SetRibbonStatusBarText("当前采集卡信号被移除。", ID_STATUSBAR_PANE1);
+		}
+		pDC->DrawText(string, &rect_client, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+
+		pDC->SelectObject(&hOldFont);
+		font.DeleteObject();
+	}
+
 	// TODO: 在此处为本机数据添加绘制代码
 }
 
@@ -136,3 +396,587 @@ CSATHelperDoc* CSATHelperView::GetDocument() const // 非调试版本是内联
 
 
 // CSATHelperView 消息处理程序
+
+BOOL CSATHelperView::HwInitialize()
+{
+	if (m_hVideoDevice != NULL)
+		return TRUE;
+
+	// CALLBACK FUNCTION       
+	PF_FORMAT_CHANGED_CALLBACK pFormatChangedCB = { 0 };
+	PF_VIDEO_PREVIEW_CALLBACK  pPreviewVideoCB = { 0 };
+	PF_AUDIO_PREVIEW_CALLBACK pPreviewAudioCB = { 0 };
+	PF_VIDEO_HARDWARE_ENCODER_CALLBACK pHardwareEncoderVideoCB = { 0 };
+	PF_NO_SIGNAL_DETECTED_CALLBACK pNoSignalDetectedCB = { 0 };
+	PF_SIGNAL_REMOVED_CALLBACK pSignalRemovedCB = { 0 };
+	PF_SNAPSHOT_DONE_CALLBACK pSnapShotDoneCB = { 0 };
+	PF_SNAPSHOT_STREAM_CALLBACK pSnapShotStreamCB = { 0 };
+	// CREATE CAPTURE DEVICE
+	//
+	if (m_hVideoDevice == NULL)
+		QCAP_CREATE("CY3014 USB", 0, m_hWnd, &m_hVideoDevice, 1);
+
+	if (m_hVideoDevice == NULL) {
+		return FALSE;
+	}
+
+	// REGISTER FORMAT CHANGED CALLBACK FUNCTION
+	pFormatChangedCB = on_process_format_changed;
+	QCAP_REGISTER_FORMAT_CHANGED_CALLBACK(m_hVideoDevice, pFormatChangedCB, this);
+
+	// REGISTER PREVIEW VIDEO CALLBACK FUNCTION
+	pPreviewVideoCB = on_process_preview_video_buffer;
+	QCAP_REGISTER_VIDEO_PREVIEW_CALLBACK(m_hVideoDevice, pPreviewVideoCB, this);
+
+	// REGISTER PREVIEW AUDIO CALLBACK FUNCTION
+	//pPreviewAudioCB = on_process_preview_audio_buffer;
+	//QCAP_REGISTER_AUDIO_PREVIEW_CALLBACK(m_hVideoDevice, pPreviewAudioCB, this);
+
+	// REGISTER HARDWARE ENCODER VIDEO CALLBACK FUNCTION
+	//pHardwareEncoderVideoCB = on_process_hardware_encoder_video_buffer;
+	//QCAP_REGISTER_VIDEO_HARDWARE_ENCODER_CALLBACK(m_hVideoDevice, 0, pHardwareEncoderVideoCB, this);
+
+	// REGISTER NO SIGNAL DETECTED CALLBACK FUNCTION
+	pNoSignalDetectedCB = on_process_no_signal_detected;
+	QCAP_REGISTER_NO_SIGNAL_DETECTED_CALLBACK(m_hVideoDevice, pNoSignalDetectedCB, this);
+
+	// REGISTER SIGNAL REMOVED CALLBACK FUNCTION
+	pSignalRemovedCB = on_process_signal_removed;
+	QCAP_REGISTER_SIGNAL_REMOVED_CALLBACK(m_hVideoDevice, pSignalRemovedCB, this);
+
+#if 1
+	// 
+	pSnapShotDoneCB = on_process_snapshot_done;
+	QCAP_REGISTER_SNAPSHOT_DONE_CALLBACK(m_hVideoDevice, pSnapShotDoneCB, this);
+
+	// 
+	pSnapShotStreamCB = on_process_snapshot_stream;
+	QCAP_REGISTER_SNAPSHOT_STREAM_CALLBACK(m_hVideoDevice, pSnapShotStreamCB, this);
+#endif
+
+	QCAP_SET_VIDEO_DEINTERLACE_TYPE(m_hVideoDevice, QCAP_SOFTWARE_DEINTERLACE_TYPE_BLENDING);
+
+	QCAP_SET_VIDEO_DEINTERLACE(m_hVideoDevice, 0);
+	QCAP_SET_AUDIO_VOLUME(m_hVideoDevice, 100);
+	QCAP_SET_VIDEO_HARDWARE_ENCODER_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_FORMAT_H264, QCAP_RECORD_MODE_CBR, 8000, 12 * 1024 * 1024, 30, 0, 0, QCAP_DOWNSCALE_MODE_OFF, 0, 0);
+
+	QCAP_SET_VIDEO_INPUT(m_hVideoDevice, QCAP_INPUT_TYPE_AUTO);
+	QCAP_RUN(m_hVideoDevice);
+
+	// 刷新区域;
+	Invalidate();
+
+	// UPDATE USER INTERFACE RESOURCE
+	if (m_hVideoDevice == 0) {
+		/*m_oSetupDialog.m_btnVideoInput.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnVideoQuality.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnAudioInput.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnSnapshot_bmp.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnSnapshot_jpg.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnRecordStart_1_1.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnRecordStop_1_1.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnRecordStart_1_2.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnRecordStop_1_2.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnRecordStart_1_3.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnRecordStop_1_3.EnableWindow(FALSE);
+		m_oSetupDialog.m_checkGPU_1_1.EnableWindow(FALSE);
+		m_oSetupDialog.m_checkGPU_1_1.SetCheck(0);
+		m_oSetupDialog.m_checkGPU_1_2.EnableWindow(FALSE);
+		m_oSetupDialog.m_checkGPU_1_2.SetCheck(0);
+		m_oSetupDialog.m_checkGPU_1_3.EnableWindow(FALSE);
+		m_oSetupDialog.m_checkGPU_1_3.SetCheck(0);
+		m_oSetupDialog.m_checkAutoDeinterlace.EnableWindow(FALSE);
+		m_oSetupDialog.m_checkAutoDeinterlace.SetCheck(0);*/
+	}
+	else {
+		/*m_oSetupDialog.m_btnSnapshot_bmp.EnableWindow(TRUE);
+		m_oSetupDialog.m_btnSnapshot_jpg.EnableWindow(TRUE);
+		m_oSetupDialog.m_btnRecordStart_1_1.EnableWindow(TRUE);
+		m_oSetupDialog.m_btnRecordStop_1_1.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnRecordStart_1_2.EnableWindow(TRUE);
+		m_oSetupDialog.m_btnRecordStop_1_2.EnableWindow(FALSE);
+		m_oSetupDialog.m_btnRecordStart_1_3.EnableWindow(TRUE);
+		m_oSetupDialog.m_btnRecordStop_1_3.EnableWindow(FALSE);
+		m_oSetupDialog.m_checkGPU_1_1.EnableWindow(FALSE);
+		m_oSetupDialog.m_checkGPU_1_1.SetCheck(0);
+		m_oSetupDialog.m_checkGPU_1_2.EnableWindow(TRUE);
+		m_oSetupDialog.m_checkGPU_1_2.SetCheck(0);
+		m_oSetupDialog.m_checkGPU_1_3.EnableWindow(TRUE);
+		m_oSetupDialog.m_checkGPU_1_3.SetCheck(0);
+		m_oSetupDialog.m_checkAutoDeinterlace.EnableWindow(TRUE);
+		m_oSetupDialog.m_checkAutoDeinterlace.SetCheck(0);*/
+	}
+
+	return TRUE;
+}
+
+BOOL CSATHelperView::HwUninitialize()
+{
+	if (m_hVideoDevice != 0) {
+		QCAP_STOP(m_hVideoDevice);
+		QCAP_DESTROY(m_hVideoDevice);
+		m_hVideoDevice = NULL;
+	}
+
+	return TRUE;
+}
+
+void CSATHelperView::CaptureSingleImage(LPTSTR lpszFileName, BOOL bIsJPG)
+{
+	if (m_hVideoDevice != NULL)
+	{
+		if (bIsJPG)
+		{
+			QCAP_SNAPSHOT_JPG(m_hVideoDevice, lpszFileName, 100, FALSE, 5000); //参数4:是否异步;
+		}
+		else
+		{
+			QCAP_SNAPSHOT_BMP(m_hVideoDevice, lpszFileName, FALSE, 5000);
+		}
+#ifdef _DEBUG
+		Global::WriteTextLog("完成:CaptureSingleImage");
+#endif
+	}
+}
+
+std::string CSATHelperView::CaptureSingleImageAutoName(LPCTSTR lpszDir, BOOL bIsJPG)
+{
+	if (m_hVideoDevice != NULL)
+	{
+		TCHAR szPath[MAX_PATH] = { 0 };
+		// 毫秒级;
+		time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
+		auto tt = std::chrono::system_clock::to_time_t(tp);
+		std::tm now = { 0 };
+		localtime_s(&now, &tt); // 时间戳转成本地时间;
+		int msc = tp.time_since_epoch().count() % 1000;
+		if (bIsJPG)
+		{
+			_stprintf_s(szPath, _T("%s%04d%02d%02d%02d%02d%02d%03d.jpg"),
+				lpszDir ? lpszDir : Global::g_szCurModuleDir,
+				now.tm_year + 1990,
+				now.tm_mon + 1,
+				now.tm_mday,
+				now.tm_hour,
+				now.tm_min,
+				now.tm_sec,
+				msc);
+			QCAP_SNAPSHOT_JPG(m_hVideoDevice, szPath, 100, FALSE, 5000);
+		}
+		else
+		{
+			_stprintf_s(szPath, _T("%s%04d%02d%02d%02d%02d%02d%03d.bmp"),
+				lpszDir ? lpszDir : Global::g_szCurModuleDir,
+				now.tm_year + 1990,
+				now.tm_mon + 1,
+				now.tm_mday,
+				now.tm_hour,
+				now.tm_min,
+				now.tm_sec,
+				msc);
+			QCAP_SNAPSHOT_BMP(m_hVideoDevice, szPath, FALSE, 5000);
+		}
+#ifdef _DEBUG
+		Global::WriteTextLog("完成:CaptureSingleImageAutoName");
+#endif
+		return std::string(szPath);
+	}
+
+	return std::string();
+}
+
+void CSATHelperView::CaptureMultiImage(LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime)
+{
+	std::thread t([&](CSATHelperView* p, LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime) {
+		// 连续截图;
+		TCHAR szDir[MAX_PATH] = { 0 };
+		TCHAR szPath[MAX_PATH] = { 0 };
+
+		_stprintf_s(szDir, lpszPrefix ? _T("%s%s-") : _T("%s%s"),
+			lpszDir ? lpszDir : Global::g_szCurModuleDir,
+			lpszPrefix ? lpszPrefix : _T(""));
+
+		auto start = system_clock::now();
+		while (true)
+		{
+			// C++11获取当前时间;
+			time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
+			if (bIsJPG)
+			{
+				_stprintf_s(szPath, _T("%s%lld.jpg"), szDir, tp.time_since_epoch().count());
+				QCAP_SNAPSHOT_JPG(m_hVideoDevice, szPath, 100, TRUE);
+				// 等待磁盘完成写入;
+				//Sleep(20);
+			}
+			else
+			{
+				_stprintf_s(szPath, _T("%s%lld.bmp"), szDir, tp.time_since_epoch().count());
+				QCAP_SNAPSHOT_BMP(m_hVideoDevice, szPath, TRUE);
+				// 等待磁盘完成写入;
+				//Sleep(530);
+			}
+
+			auto duration = duration_cast<milliseconds>(system_clock::now() - start);
+			if (duration.count() >= nDurationTime)
+				break;
+		}
+		}, this, lpszDir, lpszPrefix, bIsJPG, nDurationTime);
+	t.detach();
+}
+
+
+void CSATHelperView::CaptureSingleImageEx(LPTSTR lpszFileName, BOOL bIsJPG)
+{
+	{
+		// 加锁;
+		std::lock_guard<std::mutex> lk(m_mut_cpature);
+		// 标记截图;
+		m_bCaptureImage = TRUE;
+		// 初始化数据;
+		ZeroMemory(&m_CaptureInfo, sizeof(CaptureInfo));
+		m_CaptureInfo.bIsJPG = bIsJPG;
+		m_CaptureInfo.bSingle = TRUE;
+		m_CaptureInfo.IsAutoName = FALSE;
+		m_CaptureInfo.nCaputerCount = 0;
+		m_CaptureInfo.nKeepTime = 0;
+		memset(m_CaptureInfo.szPrefix, 0, 64);
+		//_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s"), lpszFileName);
+		_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s"), lpszFileName);
+		//m_strCaptureName = lpszFileName;
+	}
+
+	// 等待截图完成;
+	{
+		// 加锁;
+		std::unique_lock<std::mutex> lk(m_mut_cpature);
+		m_capture_cond.wait(lk, [&]() {return !m_pBuffer; });
+		// 解锁;
+		lk.unlock();
+	}
+}
+
+std::string CSATHelperView::CaptureSingleImageAutoNameEx(LPCTSTR lpszDir, BOOL bIsJPG)
+{
+	{
+		// 加锁;
+		std::lock_guard<std::mutex> lk(m_mut_cpature);
+		// 标记截图;
+		m_bCaptureImage = TRUE;
+		// 初始化数据;
+		ZeroMemory(&m_CaptureInfo, sizeof(CaptureInfo));
+		m_CaptureInfo.bIsJPG = bIsJPG;
+		m_CaptureInfo.bSingle = TRUE;
+		m_CaptureInfo.IsAutoName = FALSE;
+		m_CaptureInfo.nCaputerCount = 0;
+		m_CaptureInfo.nKeepTime = 0;
+		memset(m_CaptureInfo.szPrefix, 0, 64);
+		memset(m_CaptureInfo.szSaveDir, 0, MAX_PATH);
+
+		// 毫秒级;
+		time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
+		auto tt = std::chrono::system_clock::to_time_t(tp);
+		std::tm now = { 0 };
+		localtime_s(&now, &tt); // 时间戳转成本地时间;
+		int msc = tp.time_since_epoch().count() % 1000;
+		if (bIsJPG)
+		{
+			_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%04d%02d%02d%02d%02d%02d%03d.jpg"),
+				lpszDir ? lpszDir : Global::g_szCurModuleDir,
+				now.tm_year + 1990,
+				now.tm_mon + 1,
+				now.tm_mday,
+				now.tm_hour,
+				now.tm_min,
+				now.tm_sec,
+				msc);
+		}
+		else
+		{
+			_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%04d%02d%02d%02d%02d%02d%03d.bmp"),
+				lpszDir ? lpszDir : Global::g_szCurModuleDir,
+				now.tm_year + 1990,
+				now.tm_mon + 1,
+				now.tm_mday,
+				now.tm_hour,
+				now.tm_min,
+				now.tm_sec,
+				msc);
+		}
+
+#ifdef DEBUG
+		OutputDebugStringA(m_CaptureInfo.szSaveDir);
+		OutputDebugStringA("\tCVideoCaptureView::CaptureSingleImageAutoNameEx\n");
+#endif // DEBUG
+	}
+
+	// 等待截图完成;
+	{
+		// 加锁;
+		std::unique_lock<std::mutex> lk(m_mut_cpature);
+		m_capture_cond.wait(lk, [&]() {return !m_pBuffer; });
+		// 解锁;
+		lk.unlock();
+	}
+
+	return std::string(m_CaptureInfo.szSaveDir);
+}
+
+void CSATHelperView::CaptureMultiImageEx(LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime)
+{
+	std::thread t([&](CSATHelperView* p, LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime) {
+		// 连续截图;
+		TCHAR szDir[MAX_PATH] = { 0 };
+		_stprintf_s(szDir, lpszPrefix ? _T("%s%s-") : _T("%s%s"),
+			lpszDir ? lpszDir : Global::g_szCurModuleDir,
+			lpszPrefix ? lpszPrefix : _T(""));
+
+		auto start = system_clock::now();
+		while (true)
+		{
+			// C++11获取当前时间;
+			time_point<system_clock, ::chrono::milliseconds> tp = time_point_cast<std::chrono::milliseconds>(system_clock::now());
+
+			{
+				// 加锁;
+				std::lock_guard<std::mutex> lk(m_mut_cpature);
+				// 标记截图;
+				m_bCaptureImage = TRUE;
+				// 初始化数据;
+				ZeroMemory(&m_CaptureInfo, sizeof(CaptureInfo));
+				m_CaptureInfo.bIsJPG = bIsJPG;
+				m_CaptureInfo.bSingle = FALSE;
+				m_CaptureInfo.IsAutoName = TRUE;
+				m_CaptureInfo.nCaputerCount = 0;
+				m_CaptureInfo.nKeepTime = nDurationTime;
+				_stprintf_s(m_CaptureInfo.szPrefix, _T("%s"), lpszPrefix);
+				if (bIsJPG)
+				{
+					_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%lld.jpg"), szDir, tp.time_since_epoch().count());
+				}
+				else
+				{
+					_stprintf_s(m_CaptureInfo.szSaveDir, _T("%s%lld.bmp"), szDir, tp.time_since_epoch().count());
+				}
+			}
+
+			// 等待截图完成;
+			{
+				// 加锁;
+				std::unique_lock<std::mutex> lk(m_mut_cpature);
+				m_capture_cond.wait(lk, [&]() {return !m_pBuffer; });
+				// 解锁;
+				lk.unlock();
+			}
+
+			auto duration = duration_cast<milliseconds>(system_clock::now() - start);
+			if (duration.count() >= nDurationTime)
+				break;
+		}
+		}, this, lpszDir, lpszPrefix, bIsJPG, nDurationTime);
+	t.detach();
+}
+
+BOOL CSATHelperView::SaveImageByCaptureInfo(const CaptureInfo& capInfo)
+{
+	if (m_pBuffer == NULL)
+	{
+		return FALSE;
+	}
+
+	BOOL bRet = FALSE;
+	// 保存截图;
+	HGLOBAL hMemery = GlobalAlloc(GMEM_MOVEABLE, m_nVideoWidth * m_nVideoHeight * 4);
+	if (hMemery != NULL)
+	{
+		BYTE* pDstFrameBuffer = NULL;
+		pDstFrameBuffer = (BYTE*)GlobalLock(hMemery);
+		if (pDstFrameBuffer != NULL)
+		{
+			QRESULT QRet = QCAP_COLORSPACE_YUY2_TO_ABGR32(m_pBuffer,
+				m_nVideoWidth,
+				m_nVideoHeight,
+				0,
+				pDstFrameBuffer,
+				m_nVideoWidth,
+				m_nVideoHeight,
+				0);
+
+			Status stat = GenericError;
+			Bitmap* pImg = ::new Bitmap(
+				m_nVideoWidth,
+				m_nVideoHeight,
+				m_nVideoWidth * 4,
+				PixelFormat32bppRGB,
+				pDstFrameBuffer);
+
+			if (m_bHoriontal && !m_bVertically)
+				pImg->RotateFlip(RotateNoneFlipX);// 水平翻转;
+			else if (m_bHoriontal && m_bVertically)
+				pImg->RotateFlip(Rotate180FlipNone);// 270度;
+			else if (!m_bHoriontal && m_bVertically)
+				pImg->RotateFlip(Rotate180FlipX);// 垂直翻转;
+
+			CLSID encoderClsid = { 0 };
+			CString strFileName = m_CaptureInfo.szSaveDir;
+			// 需要判断路径是否存在,不存在创建目录;
+			int nIndex = strFileName.ReverseFind(_T('\\'));
+			if (nIndex != -1)
+			{
+				if (!PathFileExists(strFileName.Left(nIndex)))
+				{
+					// 如果文件夹不存在,创建;
+					SHCreateDirectoryEx(NULL, strFileName.Left(nIndex), NULL);
+				}
+			}
+
+			BSTR newfile = strFileName.AllocSysString();
+			if (!capInfo.bIsJPG)
+			{
+				Global::GetEncoderClsid(L"image/bmp", &encoderClsid);
+				stat = pImg->Save(newfile, &encoderClsid, NULL);
+			}
+			else
+			{
+				Global::GetEncoderClsid(L"image/jpeg", &encoderClsid);
+				EncoderParameters encoderParameters;
+				encoderParameters.Count = 1;
+				encoderParameters.Parameter[0].Guid = EncoderQuality;
+				encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
+				encoderParameters.Parameter[0].NumberOfValues = 1;
+				// Save the image as a JPEG with quality level 100.
+				ULONG uQuality = 100;
+				encoderParameters.Parameter[0].Value = &uQuality;
+				stat = pImg->Save(newfile, &encoderClsid, &encoderParameters);
+			}
+
+			if (pImg)
+				::delete pImg;
+			pImg = NULL;
+			SysFreeString(newfile);
+
+			bRet = (stat == 0 ? TRUE : FALSE);
+#ifdef DEBUG
+			if (bRet)
+			{
+				OutputDebugStringA(strFileName);
+				OutputDebugStringA("\tSave Image::Ok\n");
+			}
+#endif
+		}
+#ifdef DEBUG
+		else
+		{
+			OutputDebugStringA("pDstFrameBuffer == NULL\n");
+		}
+#endif
+
+		GlobalUnlock(hMemery);
+	}
+#ifdef DEBUG
+	else
+	{
+		DWORD dwError = GetLastError();
+		CString strError = _T("");
+		strError.Format(_T("hMemery == NULL分配内存出错:%ld\n"), dwError);
+		OutputDebugStringA(strError);
+	}
+#endif
+
+	if (m_pBuffer)
+		delete[]m_pBuffer;
+	m_pBuffer = NULL;
+
+	// 必须调用GlobalFree释放;
+	GlobalFree(hMemery);
+
+	return bRet;
+}
+
+void CSATHelperView::CaptureImageThread(CSATHelperView* pView)
+{
+	CString strFileName = _T("");
+	while (!pView->m_bAppQuit)
+	{
+		std::unique_lock<std::mutex> lk(pView->m_mut_thread);   // 这里使用unique_lock是为了后面方便解锁
+#if 1	// 避免线程虚假唤醒;
+		pView->m_thread_cond.wait(lk, [&]() {return pView->m_pBuffer; });
+#else
+		while (!pView->m_pBuffer)
+			pView->m_data_cond.wait(lk);
+#endif
+		// 保存截图;
+		pView->SaveImageByCaptureInfo(pView->m_CaptureInfo);
+		// 通知截图完成;
+		pView->m_capture_cond.notify_one();
+
+		// 解锁;
+		lk.unlock();
+
+		// sleep 10ms;
+		//this_thread::sleep_for(chrono::milliseconds(10));
+	}
+}
+
+void CSATHelperView::StartRecord(DWORD dwDuration, LPCTSTR lpSavePath)
+{
+	QRESULT QRet = QCAP_RS_SUCCESSFUL;
+	if (!m_bIsMp4) // 音频格式;
+	{
+		QRet = QCAP_SET_AUDIO_RECORD_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_TYPE_SOFTWARE, QCAP_ENCODER_FORMAT_PCM);
+		//_tcscat_s(szPath, _T(".avi"));
+	}
+	else
+	{
+		QRet = QCAP_SET_AUDIO_RECORD_PROPERTY(m_hVideoDevice, 0, QCAP_ENCODER_TYPE_SOFTWARE, QCAP_ENCODER_FORMAT_AAC);
+		//_tcscat_s(szPath, _T(".mp4"));
+	}
+
+	// 设置视频属性;
+	QRet = QCAP_SET_VIDEO_RECORD_PROPERTY(
+		m_hVideoDevice,
+		0,
+		m_bSupportGPU ? QCAP_ENCODER_TYPE_INTEL_MEDIA_SDK : QCAP_ENCODER_TYPE_SOFTWARE,
+		QCAP_ENCODER_FORMAT_H264,
+		QCAP_RECORD_MODE_CBR,
+		8000,
+		16 * 1024 * 1024, // 16最高质量;
+		30, // 每秒多少帧
+		0,
+		0,
+		QCAP_DOWNSCALE_MODE_OFF);
+
+	// 开始录屏;
+	QRet = QCAP_START_RECORD(m_hVideoDevice, 0, const_cast<CHAR*>(lpSavePath), QCAP_RECORD_FLAG_FULL, 0.0, 0.0, 0.0, 0, NULL);
+
+	m_bIsRecord = TRUE;
+}
+
+void CSATHelperView::StopRecord()
+{
+	QCAP_STOP_RECORD(m_hVideoDevice, 0);
+	m_bIsRecord = FALSE;
+}
+
+int CSATHelperView::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+	if (CView::OnCreate(lpCreateStruct) == -1)
+		return -1;
+
+	// TODO:  在此添加您专用的创建代码
+	// 初始化共享内存;
+	CMemoryClient::m_pView = this;
+	g_ub530.InitMemery();
+	g_ub530.StartThread();
+
+	g_pMainFrame = (CMainFrame*)this->GetParent();
+
+	// TODO:  在此添加您专用的创建代码
+	// 创建视频流,并关联指定显示窗口;
+	HwInitialize();
+
+	// 创建截图线程;
+	std::thread t(CaptureImageThread, this);
+	t.detach();
+
+	return 0;
+}

+ 118 - 0
SATHelper/SATHelper/SATHelperView.h

@@ -14,7 +14,25 @@
 
 #pragma once
 #include "SATHelperDoc.h"
+#include "MemoryClient.h"
 
+typedef struct __CAPTURE_INFO__
+{
+	// 是否是jpg;
+	BOOL bIsJPG;
+	// 持续时间;
+	int nKeepTime;
+	// 每秒抓取张数;
+	int nCaputerCount;
+	// 保存路径;
+	TCHAR szSaveDir[MAX_PATH];
+	// 文件名前缀;
+	TCHAR szPrefix[64];
+	// 是否自动命名;
+	BOOL IsAutoName;
+	// 是否单张截图;
+	BOOL bSingle;
+}CaptureInfo, * pCaptureInfo;
 
 class CSATHelperView : public CView
 {
@@ -54,6 +72,106 @@ protected:
 	afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
 	afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
 	DECLARE_MESSAGE_MAP()
+
+	//////////////////////////////////////////////////////////////////////////////////////////
+
+public:
+	// 设备句柄;
+	PVOID 				m_hVideoDevice;
+	// 是否有信号;
+	BOOL				m_bNoSignal;
+	// 是否在录频;
+	BOOL				m_bIsRecord;
+	// 录频格式;
+	BOOL				m_bIsMp4; // FALSE= AVI
+	//////////////////////////////////////////////////////////////////////////
+	// VIDEO PROPERTIES
+	// 是否支持GPU;
+	BOOL				m_bSupportGPU;
+	// 视频流宽度;
+	ULONG				m_nVideoWidth;
+	// 视频流高度;
+	ULONG				m_nVideoHeight;
+
+	BOOL				m_bVideoIsInterleaved;
+
+	double				m_dVideoFrameRate;
+
+	BOOL				m_bVideoDeinterlaceEnable;
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// AUDIO PROPERTIES
+
+	ULONG				m_nAudioChannels;
+
+	ULONG				m_nAudioBitsPerSample;
+
+	ULONG				m_nAudioSampleFrequency;
+
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// QUALITY PROPERTIES
+
+	ULONG				m_nSharpness;
+
+	ULONG				m_nSaturation;
+
+	ULONG				m_nHue;
+
+	ULONG				m_nConstrast;
+
+	ULONG				m_nBrightness;
+
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RECORD & FILE PROPERTIES
+
+	// 截图路径;
+	CString				m_strSnapshotPath;
+	//
+	CString				m_strFormatChangedOutput;
+	// 垂直镜像;
+	BOOL				m_bVertically;
+	// 水平镜像;
+	BOOL				m_bHoriontal;
+
+	// 程序退出;
+	BOOL				m_bAppQuit;
+
+public:
+	// 初始化设备;
+	BOOL HwInitialize();
+	// 释放设备;
+	BOOL HwUninitialize();
+
+	// 单次截图;
+	void CaptureSingleImage(LPTSTR lpszFileName, BOOL bIsJPG = TRUE);
+	// 单次截图并自动命名;
+	std::string CaptureSingleImageAutoName(LPCTSTR lpszDir, BOOL bIsJPG = TRUE);
+	// 连续截图;//默认持续1000ms;
+	void CaptureMultiImage(LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime = 1000);
+
+	//////////////////////////////////////////////////////////////////////////
+	// ->预览截图;
+	CaptureInfo m_CaptureInfo;
+	BOOL m_bCaptureImage;
+	std::mutex m_mut_cpature;
+	std::condition_variable m_capture_cond;
+	// 单次截图;
+	void CaptureSingleImageEx(LPTSTR lpszFileName, BOOL bIsJPG = TRUE);
+	// 单次截图并自动命名;
+	std::string CaptureSingleImageAutoNameEx(LPCTSTR lpszDir, BOOL bIsJPG = TRUE);
+	// 连续截图;//默认持续1000ms;
+	void CaptureMultiImageEx(LPCTSTR lpszDir, LPCTSTR lpszPrefix, BOOL bIsJPG, int nDurationTime = 1000);
+	// 截图;
+	BOOL SaveImageByCaptureInfo(const CaptureInfo& capInfo);
+
+	// 截图线程;
+	BYTE* m_pBuffer;
+	DWORD m_dwBufferLen;
+
+	std::mutex m_mut_thread;
+	std::condition_variable m_thread_cond; //使用std::condition_variable等待数据
+	static void CaptureImageThread(CSATHelperView* pView);
+
+	// 录屏;
+	void StartRecord(DWORD dwDuration, LPCTSTR lpSavePath);
+	void StopRecord();
+	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
 };
 
 #ifndef _DEBUG  // SATHelperView.cpp 中的调试版本

BIN
SATHelper/SATHelper/res/checked.bmp


Fișier diff suprimat deoarece este prea mare
+ 0 - 462
SATHelper/SATHelper/res/ribbon.mfcribbon-ms


BIN
SATHelper/SATHelper/res/unchecked.bmp


Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff