From 5471abe440f1b449293a3c93b3a638396682617a Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期三, 13 十一月 2024 09:57:06 +0800
Subject: [PATCH] 1.初始导入;

---
 SourceCode/Bond/BondEq/Servo.h                                            |   11 
 SourceCode/Bond/GangBond2860Emulator/Model.h                              |   21 
 SourceCode/Bond/RxWindows1.0/include/RxWindowsLib.h                       |   22 
 SourceCode/Bond/BEQDemo/ColorStatic.cpp                                   |   22 
 SourceCode/Bond/BondEq/HorizontalLine.cpp                                 |  203 
 SourceCode/Bond/x64/Debug/Res/Run_Gray_32.ico                             |    0 
 SourceCode/Bond/BLControlsSDK/include/InPlaceEdit.h                       |   59 
 SourceCode/Bond/BEQLibrary/Equipment.cpp                                  |  935 ++
 SourceCode/Bond/BondEq/LogEdit.cpp                                        |   87 
 SourceCode/Bond/BEQLibrary/SocketServer.h                                 |   39 
 SourceCode/Bond/BondEq/stdafx.cpp                                         |    8 
 SourceCode/Bond/x64/Debug/Res/small_close0.ico                            |    0 
 SourceCode/Bond/x64/Debug/Res/Run_High_32.ico                             |    0 
 SourceCode/Bond/GangBond2860Emulator/GangBond2860EmulatorDlg.h            |   56 
 SourceCode/Bond/BEQDemo/BEQDemo.cpp                                       |  113 
 SourceCode/Bond/BEQLibrary/BEQLibrary.def                                 |    6 
 SourceCode/Bond/x64/Release/Res/small_close3.ico                          |    0 
 SourceCode/Bond/GangBond2860Emulator/GangBond2860EmulatorDlg.cpp          |  274 
 SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj.user    |    4 
 SourceCode/Bond/BondEq/ReadMe.txt                                         |   67 
 SourceCode/Bond/BondEq/SetPage2.cpp                                       |   62 
 SourceCode/Bond/BondEq/ApredTreeCtrl.cpp                                  |  466 +
 SourceCode/Bond/BEQLibrary/IEquipment.h                                   |   41 
 SourceCode/Bond/BondEq/HorizontalLine.h                                   |   86 
 SourceCode/Bond/BEQDemo/res/application.exe.manifest                      |   20 
 SourceCode/Bond/BondEq/res/BondServo.ico                                  |    0 
 SourceCode/Bond/BondEq/BondEq.vcxproj                                     |  290 
 SourceCode/Bond/x64/Debug/Res/Operator_Gray_32.ico                        |    0 
 SourceCode/Bond/BLControlsSDK/include/BLButton.h                          |   82 
 SourceCode/Bond/BLControlsSDK/include/FontStatic.h                        |   69 
 SourceCode/Bond/BondEq/CRemoteEqUnitView.h                                |   32 
 SourceCode/Bond/x64/Debug/Res/indicator_check_24.ico                      |    0 
 SourceCode/Bond/BondEq/TopToolbar.cpp                                     |  189 
 SourceCode/Bond/x64/Debug/Res/Operator_High_32.ico                        |    0 
 SourceCode/Bond/BEQLibrarySDK/Include/IRemoteEquipment.h                  |   35 
 SourceCode/Bond/x64/Debug/Res/indicator_check_28.ico                      |    0 
 SourceCode/Bond/BondEq/CRemoteEqView.h                                    |   46 
 SourceCode/Bond/x64/Debug/Res/logcat_include.ico                          |    0 
 SourceCode/Bond/RxWindows1.0/include/IObservableEmitter.h                 |    8 
 SourceCode/Bond/BondEq/View/LoginDlg.cpp                                  |  116 
 SourceCode/Bond/x64/Debug/Res/indicator_check_32.ico                      |    0 
 SourceCode/Bond/BLControlsSDK/include/CellCtrl.h                          |  304 
 SourceCode/Bond/BondEq/CRemoteEqUnitView.cpp                              |   68 
 SourceCode/Bond/BondEq/View/LoginDlg.h                                    |   32 
 SourceCode/Bond/BEQDemo/BEQDemoDlg.cpp                                    |  481 +
 SourceCode/Bond/GangBond2860Emulator/targetver.h                          |    8 
 SourceCode/Bond/BondEq/Configuration.h                                    |   31 
 SourceCode/Bond/BondEq/Log.h                                              |   61 
 SourceCode/Bond/GangBond2860Emulator/PageEquipment.h                      |   26 
 SourceCode/Bond/x64/Release/configuration.ini                             |  122 
 SourceCode/Bond/BondEq/View/ChangePasswordDlg.h                           |   37 
 SourceCode/Bond/BondEq/res/application.exe.manifest                       |   20 
 SourceCode/Bond/RxWindows1.0/include/IRxObject.h                          |   11 
 SourceCode/Bond/x64/Debug/AlarmList.txt                                   |  227 
 SourceCode/Bond/x64/Debug/Res/arrow_down.ico                              |    0 
 SourceCode/Bond/x64/Release/Res/small_close2.ico                          |    0 
 SourceCode/Bond/BEQDemo/resource.h                                        |    0 
 SourceCode/Bond/GangBond2860Emulator/res/application.exe.manifest         |   20 
 SourceCode/Bond/BEQLibrary/SocketClient.h                                 |   20 
 SourceCode/Bond/BEQDemo/targetver.h                                       |    8 
 SourceCode/Bond/BLControlsSDK/include/BLListCtrlExt.h                     |  137 
 SourceCode/Bond/RxWindows1.0/include/IObservable.h                        |    9 
 SourceCode/Bond/BondEq/CHomeDialog.cpp                                    |  155 
 SourceCode/Bond/x64/Debug/Res/indicator_check_32_dark.ico                 |    0 
 SourceCode/Bond/x64/Debug/Res/small_close1.ico                            |    0 
 SourceCode/Bond/BEQDemo/BEQDemo.h                                         |   33 
 SourceCode/Bond/BondEq/AccordionWnd.h                                     |  129 
 SourceCode/Bond/BondEq/LogEdit.h                                          |   21 
 SourceCode/Bond/GangBond2860Emulator/res/GangBond2860Emulator.rc2         |    0 
 SourceCode/Bond/BEQDemo/BEQDemo.vcxproj.filters                           |   72 
 SourceCode/Bond/BEQLibrary/res/BEQLibrary.rc2                             |    0 
 SourceCode/Bond/BondEq/BaseSetPage.h                                      |   26 
 SourceCode/Bond/BEQLibrary/SocketServer.cpp                               |   78 
 SourceCode/Bond/BondEq/BondServoDlg.h                                     |   76 
 SourceCode/Bond/BondEq/Model.cpp                                          |  357 
 SourceCode/Bond/BEQLibrary/BEQLibrary.cpp                                 |   63 
 SourceCode/Bond/BondEq/BondServo.h                                        |   44 
 .gitignore                                                                |   18 
 SourceCode/Bond/BEQDemo/BEQDemo.vcxproj.user                              |    6 
 SourceCode/Bond/BEQLibrary/RemoteEquipment.cpp                            | 1061 ++
 SourceCode/Bond/BondEq/res/BondServo.rc2                                  |    0 
 SourceCode/Bond/BondEq/CMainContainer.cpp                                 |  110 
 SourceCode/Bond/BEQDemo/BEQDemoDlg.h                                      |   56 
 SourceCode/Bond/BEQLibrarySDK/Include/IServo.h                            |   30 
 SourceCode/Bond/RxWindows1.0/include/IThrowable.h                         |    9 
 SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.cpp             |  137 
 SourceCode/Bond/BEQDemo/ReadMe.txt                                        |   67 
 SourceCode/Bond/BLControlsSDK/include/BLJogBtn2Parent.h                   |    7 
 SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj         |  236 
 SourceCode/Bond/BondEq/TopToolbar.h                                       |   54 
 SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.h               |   43 
 SourceCode/Bond/BEQLibrary/ReadMe.txt                                     |   45 
 SourceCode/Bond/x64/Release/Res/arrow_right.ico                           |    0 
 SourceCode/Bond/BondEq/BlButton.cpp                                       |  448 +
 SourceCode/Bond/BondEq/Common.h                                           |   89 
 SourceCode/Bond/GangBond2860Emulator/HmTab.h                              |  130 
 SourceCode/Bond/BEQLibrary/Data.h                                         |   22 
 SourceCode/Bond/BondEq/HmVerticalTab.cpp                                  |  576 +
 SourceCode/Bond/GangBond2860Emulator/Model.cpp                            |   84 
 SourceCode/Bond/BEQLibrary/BEQMain.cpp                                    |  216 
 SourceCode/Bond/BondEq/VerticalLine.h                                     |   94 
 SourceCode/Bond/BondEq/DBManager/UserManager.cpp                          |  484 +
 SourceCode/Bond/BEQLibrary/RemoteEquipment.h                              |  147 
 SourceCode/Bond/BEQLibrary/BEQCommon.h                                    |   84 
 SourceCode/Bond/BLControlsSDK/include/BLLabel.h                           |   77 
 SourceCode/Bond/x64/Release/AlarmList.txt                                 |  227 
 SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj.filters |   90 
 SourceCode/Bond/BondEq/CPageAlarm.cpp                                     |  116 
 SourceCode/Bond/BEQDemo/ColorStatic.h                                     |   15 
 SourceCode/Bond/x64/Release/Res/small_close1.ico                          |    0 
 SourceCode/Bond/BEQLibrary/Unit.h                                         |  112 
 SourceCode/Bond/BEQLibrary/Action.cpp                                     |   66 
 SourceCode/Bond/BondEq/CProjectPageRemoteEqs.cpp                          |  211 
 SourceCode/Bond/BondEq/AccordionWnd.cpp                                   |  777 ++
 SourceCode/Bond/BEQLibrary/stdafx.h                                       |   39 
 SourceCode/Bond/GangBond2860Emulator/stdafx.h                             |   54 
 SourceCode/Bond/BondEq/Configuration.cpp                                  |  105 
 SourceCode/Bond/BLControlsSDK/include/DefectMap.h                         |  124 
 SourceCode/Bond/DatabaseSDK/include/SQLiteDatabase.h                      |   25 
 SourceCode/Bond/BEQLibrary/Servo.h                                        |   39 
 SourceCode/Bond/BondEq/Log.cpp                                            |  214 
 SourceCode/Bond/x64/Debug/Config/BondServo.db                             |    0 
 SourceCode/Bond/BLControlsSDK/include/GradientStatic.h                    |  149 
 SourceCode/Bond/BLControlsSDK/include/StaticMap.h                         |  149 
 SourceCode/Bond/BondEq/SetPage2.h                                         |   32 
 SourceCode/Bond/DatabaseSDK/include/MySQLDatabase.h                       |   25 
 SourceCode/Bond/GangBond2860Emulator/PageEquipment.cpp                    |   97 
 SourceCode/Bond/BLControlsSDK/include/XTabCtrl.h                          |   90 
 SourceCode/Bond/BLControlsSDK/include/LogCtrl.h                           |  213 
 SourceCode/Bond/BEQLibrary/IUnit.h                                        |   56 
 SourceCode/Bond/BEQLibrary/stdafx.cpp                                     |    7 
 SourceCode/Bond/BEQLibrary/AcceptClient.h                                 |   37 
 SourceCode/Bond/BEQLibrary/IRemoteEquipment.h                             |   35 
 SourceCode/Bond/BondEq/CPageAlarm.h                                       |   37 
 SourceCode/Bond/x64/Debug/Res/small_close2.ico                            |    0 
 SourceCode/Bond/BEQDemo/res/BEQDemo.ico                                   |    0 
 SourceCode/Bond/x64/Debug/Res/remote_eq_light_32.ico                      |    0 
 SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj.filters                     |  130 
 SourceCode/Bond/GangBond2860Emulator/res/GangBond2860Emulator.ico         |    0 
 SourceCode/Bond/x64/Release/Res/arrow_down.ico                            |    0 
 SourceCode/Bond/BondEq/Resource.h                                         |    0 
 SourceCode/Bond/BondEq/CPanelProject.cpp                                  |  154 
 SourceCode/Bond/BondEq/CBaseView.h                                        |   73 
 SourceCode/Bond/BondEq/CProjectPageRemoteEqs.h                            |   46 
 SourceCode/Bond/BEQLibrary/Data.cpp                                       |   49 
 SourceCode/Bond/x64/Debug/Res/remote_eq_dark_32.ico                       |    0 
 SourceCode/Bond/GangBond2860Emulator/Resource.h                           |    0 
 SourceCode/Bond/BondEq/CRemoteEqView.cpp                                  |  206 
 SourceCode/Bond/GangBond2860Emulator/ReadMe.txt                           |   67 
 SourceCode/Bond/BEQLibrary/BEQLibrary.h                                   |   27 
 SourceCode/Bond/BondEq/HmTab.h                                            |  130 
 SourceCode/Bond/BEQLibrary/Action.h                                       |   33 
 SourceCode/Bond/BondEq/SetPage1.h                                         |   26 
 SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.rc              |    0 
 SourceCode/Bond/BLControlsSDK/include/SortClass.h                         |   40 
 SourceCode/Bond/BondEq/stdafx.h                                           |   78 
 SourceCode/Bond/BondEq/CPageLogcat.h                                      |   56 
 SourceCode/Bond/BEQDemo/stdafx.cpp                                        |    8 
 SourceCode/Bond/GangBond2860Emulator/PageUnit.cpp                         |  406 +
 SourceCode/Bond/x64/Debug/Res/Stop_High_32.ico                            |    0 
 SourceCode/Bond/BondEq/ToolUnits.cpp                                      |  147 
 SourceCode/Bond/BondEq/BondServoDlg.cpp                                   |  627 +
 SourceCode/Bond/x64/Debug/Res/arrow_right.ico                             |    0 
 SourceCode/Bond/BEQLibrary/IServo.h                                       |   30 
 SourceCode/Bond/GangBond2860.sln                                          |   61 
 SourceCode/Bond/x64/Debug/Res/Stop_Gray_32.ico                            |    0 
 SourceCode/Bond/BondEq/SettingsDlg.cpp                                    |  191 
 SourceCode/Bond/x64/Release/Res/small_close0.ico                          |    0 
 SourceCode/Bond/BondEq/DBManager/UserManager.h                            |  116 
 SourceCode/Bond/BEQLibrary/BEQLib.h                                       |   74 
 SourceCode/Bond/BondEq/CMainContainer.h                                   |   38 
 SourceCode/Bond/BondEq/ToolUnits.h                                        |   24 
 SourceCode/Bond/BondEq/CPageLogcat.cpp                                    |  300 
 SourceCode/Bond/BEQDemo/BEQDemo.vcxproj                                   |  230 
 SourceCode/Bond/x64/Debug/Res/Settings_High_32.ico                        |    0 
 SourceCode/Bond/BondEq/Servo.cpp                                          |   17 
 SourceCode/Bond/BondEq/View/ChangePasswordDlg.cpp                         |  114 
 SourceCode/Bond/BEQDemo/res/BEQDemo.rc2                                   |    0 
 SourceCode/Bond/BondEq/BondServo.cpp                                      |  148 
 SourceCode/Bond/BEQLibrary/AcceptClient.cpp                               |   58 
 SourceCode/Bond/BondEq/HmVerticalTab.h                                    |  136 
 SourceCode/Bond/BLControlsSDK/include/BLJogButton.h                       |   63 
 SourceCode/Bond/BLControlsSDK/include/InPlaceComboBox.h                   |   51 
 SourceCode/Bond/BEQLibrarySDK/Include/IUnit.h                             |   56 
 SourceCode/Bond/BEQLibrary/SocketClient.cpp                               |   15 
 SourceCode/Bond/BondEq/ApredTreeCtrl.h                                    |   66 
 SourceCode/Bond/BondEq/VerticalLine.cpp                                   |  310 
 SourceCode/Bond/BondEq/CBaseView.cpp                                      |  415 +
 SourceCode/Bond/BEQLibrary/targetver.h                                    |    8 
 SourceCode/Bond/x64/Debug/Res/Settings_Gray_32.ico                        |    0 
 SourceCode/Bond/RxWindows1.0/include/IRxWindows.h                         |   34 
 SourceCode/Bond/x64/Debug/Res/small_close3.ico                            |    0 
 SourceCode/Bond/RxWindows1.0/include/IObserver.h                          |    9 
 SourceCode/Bond/BEQLibrary/BEQLibrary.rc                                  |    0 
 SourceCode/Bond/BEQLibrary/Servo.cpp                                      |  177 
 SourceCode/Bond/BEQDemo/stdafx.h                                          |   54 
 SourceCode/Bond/BondEq/SettingsDlg.h                                      |   47 
 SourceCode/Bond/BondEq/HmTab.cpp                                          |  529 +
 SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj                             |  265 
 SourceCode/Bond/BEQLibrary/Unit.cpp                                       |  425 +
 SourceCode/Bond/RxWindows1.0/include/IAny.h                               |   34 
 SourceCode/Bond/BLControlsSDK/include/HeadCtrl.h                          |  104 
 SourceCode/Bond/BondEq/SetPage1.cpp                                       |   45 
 SourceCode/Bond/BondEq/BaseSetPage.cpp                                    |   55 
 SourceCode/Bond/BLControlsSDK/include/BLListBoxLog.h                      |   96 
 SourceCode/Bond/BondEq/BlButton.h                                         |   88 
 SourceCode/Bond/BondEq/Model.h                                            |   50 
 SourceCode/Bond/x64/Debug/Res/indicator_check_32_dark2.ico                |    0 
 SourceCode/Bond/BEQLibrary/Resource.h                                     |   16 
 SourceCode/Bond/DatabaseSDK/include/Database.h                            |   25 
 SourceCode/Bond/GangBond2860Emulator/HmTab.cpp                            |  529 +
 SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj.user                        |    4 
 SourceCode/Bond/BEQLibrary/Equipment.h                                    |   82 
 SourceCode/Bond/BLControlsSDK/include/WKButton.h                          |  119 
 SourceCode/Bond/BLControlsSDK/include/ColorButton.h                       |  101 
 SourceCode/Bond/BondEq/BondSEq.vcxproj.filters                            |  255 
 SourceCode/Bond/BEQLibrarySDK/Include/BEQLib.h                            |   74 
 SourceCode/Bond/BEQLibrarySDK/Include/IEquipment.h                        |   41 
 SourceCode/Bond/GangBond2860Emulator/PageUnit.h                           |   55 
 SourceCode/Bond/BEQDemo/BEQDemo.rc                                        |    0 
 SourceCode/Bond/BLControlsSDK/include/BLFolderScheduling.h                |   92 
 SourceCode/Bond/BondEq/CPanelProject.h                                    |   49 
 SourceCode/Bond/GangBond2860Emulator/stdafx.cpp                           |    8 
 SourceCode/Bond/BondEq/BondServo.rc                                       |    0 
 SourceCode/Bond/BondEq/CHomeDialog.h                                      |   45 
 SourceCode/Bond/BondEq/targetver.h                                        |    8 
 226 files changed, 21,955 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore
index 0def275..be16749 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,21 @@
 *.exe
 *.out
 *.app
+*.opensdf
+*.sdf
+SourceCode/Bond/.vs/GangBond2860/v14/.suo
+*.aps
+SourceCode/Bond/BEQDemo/x64/
+SourceCode/Bond/BEQLibrary/x64/
+*.pdb
+SourceCode/Bond/BondEq/x64/
+SourceCode/Bond/GangBond2860Emulator/x64/
+*.ipch
+*.log
+*.ipdb
+SourceCode/Bond/x64/Debug/configuration.ini
+*.ilk
+SourceCode/Bond/x64/Debug/BEQ.exp
+SourceCode/Bond/x64/Debug/Bonder.dat
+SourceCode/Bond/x64/Release/BEQ.exp
+SourceCode/Bond/x64/Release/Bonder.dat
diff --git a/SourceCode/Bond/BEQDemo/BEQDemo.cpp b/SourceCode/Bond/BEQDemo/BEQDemo.cpp
new file mode 100644
index 0000000..ee22c4d
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/BEQDemo.cpp
@@ -0,0 +1,113 @@
+
+// BEQDemo.cpp : 定义应用程序的类行为。
+//
+
+#include "stdafx.h"
+#include "BEQDemo.h"
+#include "BEQDemoDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CBEQDemoApp
+
+BEGIN_MESSAGE_MAP(CBEQDemoApp, CWinApp)
+	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CBEQDemoApp 构造
+
+CBEQDemoApp::CBEQDemoApp()
+{
+	// 支持重新启动管理器
+	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
+
+	// TODO: 在此处添加构造代码,
+	// 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的一个 CBEQDemoApp 对象
+
+CBEQDemoApp theApp;
+
+
+// CBEQDemoApp 初始化
+
+BOOL CBEQDemoApp::InitInstance()
+{
+	// 如果一个运行在 Windows XP 上的应用程序清单指定要
+	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
+	//则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
+	INITCOMMONCONTROLSEX InitCtrls;
+	InitCtrls.dwSize = sizeof(InitCtrls);
+	// 将它设置为包括所有要在应用程序中使用的
+	// 公共控件类。
+	InitCtrls.dwICC = ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&InitCtrls);
+
+	CWinApp::InitInstance();
+
+
+	AfxEnableControlContainer();
+
+	// 创建 shell 管理器,以防对话框包含
+	// 任何 shell 树视图控件或 shell 列表视图控件。
+	CShellManager *pShellManager = new CShellManager;
+
+	// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
+	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
+
+	// 标准初始化
+	// 如果未使用这些功能并希望减小
+	// 最终可执行文件的大小,则应移除下列
+	// 不需要的特定初始化例程
+	// 更改用于存储设置的注册表项
+	// TODO: 应适当修改该字符串,
+	// 例如修改为公司或组织名
+	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
+
+
+	// 初始化BEQ库
+	BEQ_Initialize();
+
+
+	CBEQDemoDlg dlg;
+	m_pMainWnd = &dlg;
+	INT_PTR nResponse = dlg.DoModal();
+	if (nResponse == IDOK)
+	{
+		// TODO: 在此放置处理何时用
+		//  “确定”来关闭对话框的代码
+	}
+	else if (nResponse == IDCANCEL)
+	{
+		// TODO: 在此放置处理何时用
+		//  “取消”来关闭对话框的代码
+	}
+	else if (nResponse == -1)
+	{
+		TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
+		TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
+	}
+
+	// 删除上面创建的 shell 管理器。
+	if (pShellManager != NULL)
+	{
+		delete pShellManager;
+	}
+
+	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
+	//  而不是启动应用程序的消息泵。
+	return FALSE;
+}
+
+int CBEQDemoApp::ExitInstance()
+{
+	BEQ_Term();
+
+	return CWinApp::ExitInstance();
+}
diff --git a/SourceCode/Bond/BEQDemo/BEQDemo.h b/SourceCode/Bond/BEQDemo/BEQDemo.h
new file mode 100644
index 0000000..6179871
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/BEQDemo.h
@@ -0,0 +1,33 @@
+
+// BEQDemo.h : PROJECT_NAME 应用程序的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
+#endif
+
+#include "resource.h"		// 主符号
+
+
+// CBEQDemoApp: 
+// 有关此类的实现,请参阅 BEQDemo.cpp
+//
+
+class CBEQDemoApp : public CWinApp
+{
+public:
+	CBEQDemoApp();
+
+// 重写
+public:
+	virtual BOOL InitInstance();
+
+// 实现
+
+	DECLARE_MESSAGE_MAP()
+	virtual int ExitInstance();
+};
+
+extern CBEQDemoApp theApp;
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQDemo/BEQDemo.rc b/SourceCode/Bond/BEQDemo/BEQDemo.rc
new file mode 100644
index 0000000..122bac1
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/BEQDemo.rc
Binary files differ
diff --git a/SourceCode/Bond/BEQDemo/BEQDemo.vcxproj b/SourceCode/Bond/BEQDemo/BEQDemo.vcxproj
new file mode 100644
index 0000000..fdb7344
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/BEQDemo.vcxproj
@@ -0,0 +1,230 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{E374F8A0-F864-49F4-AF5C-F751AAC5F133}</ProjectGuid>
+    <RootNamespace>BEQDemo</RootNamespace>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+    <Keyword>MFCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="BEQDemo.h" />
+    <ClInclude Include="BEQDemoDlg.h" />
+    <ClInclude Include="ColorStatic.h" />
+    <ClInclude Include="Resource.h" />
+    <ClInclude Include="stdafx.h" />
+    <ClInclude Include="targetver.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="BEQDemo.cpp" />
+    <ClCompile Include="BEQDemoDlg.cpp" />
+    <ClCompile Include="ColorStatic.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="BEQDemo.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\BEQDemo.rc2" />
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\BEQDemo.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <Manifest Include="res\application.exe.manifest" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+  <ProjectExtensions>
+    <VisualStudio>
+      <UserProperties RESOURCE_FILE="BEQDemo.rc" />
+    </VisualStudio>
+  </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQDemo/BEQDemo.vcxproj.filters b/SourceCode/Bond/BEQDemo/BEQDemo.vcxproj.filters
new file mode 100644
index 0000000..af2fafd
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/BEQDemo.vcxproj.filters
@@ -0,0 +1,72 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="婧愭枃浠�">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="澶存枃浠�">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="璧勬簮鏂囦欢">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="stdafx.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Resource.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="BEQDemo.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="BEQDemoDlg.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="ColorStatic.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="BEQDemo.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="BEQDemoDlg.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="ColorStatic.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="BEQDemo.rc">
+      <Filter>璧勬簮鏂囦欢</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\BEQDemo.rc2">
+      <Filter>璧勬簮鏂囦欢</Filter>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\BEQDemo.ico">
+      <Filter>璧勬簮鏂囦欢</Filter>
+    </Image>
+  </ItemGroup>
+  <ItemGroup>
+    <Manifest Include="res\application.exe.manifest" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQDemo/BEQDemo.vcxproj.user b/SourceCode/Bond/BEQDemo/BEQDemo.vcxproj.user
new file mode 100644
index 0000000..dae2451
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/BEQDemo.vcxproj.user
@@ -0,0 +1,6 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <RESOURCE_FILE>BEQDemo.rc</RESOURCE_FILE>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQDemo/BEQDemoDlg.cpp b/SourceCode/Bond/BEQDemo/BEQDemoDlg.cpp
new file mode 100644
index 0000000..832b835
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/BEQDemoDlg.cpp
@@ -0,0 +1,481 @@
+
+// BEQDemoDlg.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "BEQDemo.h"
+#include "BEQDemoDlg.h"
+#include "afxdialogex.h"
+#include <map>
+#include <chrono>
+#include <sstream>
+#include <iomanip>
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
+
+class CAboutDlg : public CDialogEx
+{
+public:
+	CAboutDlg();
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_ABOUTBOX };
+#endif
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+// 实现
+protected:
+	DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+
+// CBEQDemoDlg 对话框
+
+
+
+CBEQDemoDlg::CBEQDemoDlg(CWnd* pParent /*=NULL*/)
+	: CDialogEx(IDD_BEQDEMO_DIALOG, pParent)
+{
+	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void CBEQDemoDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_EDIT_LOG, m_editLog);
+	DDX_Control(pDX, IDC_STATIC_DOOR1, m_staticDoor1);
+	DDX_Control(pDX, IDC_STATIC_DOOR2, m_staticDoor2);
+	DDX_Control(pDX, IDC_STATIC_DOOR3, m_staticDoor3);
+	DDX_Control(pDX, IDC_STATIC_DOOR4, m_staticDoor4);
+	DDX_Control(pDX, IDC_STATIC_DOOR5, m_staticDoor5);
+}
+
+BEGIN_MESSAGE_MAP(CBEQDemoDlg, CDialogEx)
+	ON_WM_SYSCOMMAND()
+	ON_WM_PAINT()
+	ON_WM_QUERYDRAGICON()
+	ON_BN_CLICKED(IDC_BUTTON_TEST1, &CBEQDemoDlg::OnBnClickedButtonTest1)
+	ON_BN_CLICKED(IDC_BUTTON_TEST2, &CBEQDemoDlg::OnBnClickedButtonTest2)
+	ON_BN_CLICKED(IDC_BUTTON_TEST3, &CBEQDemoDlg::OnBnClickedButtonTest3)
+	ON_BN_CLICKED(IDC_BUTTON_SET_STATE, &CBEQDemoDlg::OnBnClickedButtonSetState)
+	ON_BN_CLICKED(IDC_BUTTON_SET_STATE2, &CBEQDemoDlg::OnBnClickedButtonSetState2)
+	ON_BN_CLICKED(IDC_BUTTON_SERVO_TEST1, &CBEQDemoDlg::OnBnClickedButtonServoTest1)
+	ON_BN_CLICKED(IDC_BUTTON_SERVO_TEST2, &CBEQDemoDlg::OnBnClickedButtonServoTest2)
+	ON_BN_CLICKED(IDC_BUTTON_SERVO_TEST3, &CBEQDemoDlg::OnBnClickedButtonServoTest3)
+END_MESSAGE_MAP()
+
+
+// CBEQDemoDlg 消息处理程序
+
+BOOL CBEQDemoDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// 将“关于...”菜单项添加到系统菜单中。
+
+	// IDM_ABOUTBOX 必须在系统命令范围内。
+	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+	ASSERT(IDM_ABOUTBOX < 0xF000);
+
+	CMenu* pSysMenu = GetSystemMenu(FALSE);
+	if (pSysMenu != NULL)
+	{
+		BOOL bNameValid;
+		CString strAboutMenu;
+		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
+		ASSERT(bNameValid);
+		if (!strAboutMenu.IsEmpty())
+		{
+			pSysMenu->AppendMenu(MF_SEPARATOR);
+			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+		}
+	}
+
+	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
+	//  执行此操作
+	SetIcon(m_hIcon, TRUE);			// 设置大图标
+	SetIcon(m_hIcon, FALSE);		// 设置小图标
+
+	// TODO: 在此添加额外的初始化代码
+
+	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
+}
+
+void CBEQDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+	{
+		CAboutDlg dlgAbout;
+		dlgAbout.DoModal();
+	}
+	else
+	{
+		CDialogEx::OnSysCommand(nID, lParam);
+	}
+}
+
+// 如果向对话框添加最小化按钮,则需要下面的代码
+//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
+//  这将由框架自动完成。
+
+void CBEQDemoDlg::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 CBEQDemoDlg::OnQueryDragIcon()
+{
+	return static_cast<HCURSOR>(m_hIcon);
+}
+
+void CBEQDemoDlg::OnBnClickedButtonTest1()
+{
+	BEQ::IEquipment* pEuqipment = nullptr;
+	BEQ_CreateEquipment(pEuqipment, "BEQ001");
+}
+
+void CBEQDemoDlg::OnBnClickedButtonTest2()
+{
+	BEQ::IEquipment* pEuqipment = nullptr;
+	BEQ_GetEquipment(pEuqipment, "BEQ001");
+	if (pEuqipment != nullptr) {
+		pEuqipment->setVersion("1.0.2");
+		BEQ::IUnit* pUnit1 = pEuqipment->addUnit("U1", 5);
+		pEuqipment->runOnServerMode(8080);
+
+		char szName[256];
+		pUnit1->getName(szName, 256);
+		AfxMessageBox(szName);
+		pUnit1->setState(BEQ::EQ_STATE::IDLE);
+	}
+}
+
+void CBEQDemoDlg::OnBnClickedButtonTest3()
+{
+	BEQ::IEquipment* pEuqipment = nullptr;
+	BEQ_GetEquipment(pEuqipment, "Test1");
+	if (pEuqipment != nullptr) {
+		BEQ_DestroyEquipment(pEuqipment);
+	}
+}
+
+void CBEQDemoDlg::OnBnClickedButtonSetState()
+{
+	BEQ::IUnit* pUnit = nullptr;
+	BEQ::IEquipment* pEuqipment = nullptr;
+	BEQ_GetEquipment(pEuqipment, "BEQ001");
+	if (pEuqipment != nullptr) {
+		pUnit = pEuqipment->getUnit("U1");
+	}
+
+	if (pUnit != nullptr) {
+		// pUnit->setState(BEQ::EQ_STATE::E_TIME);
+		// pUnit->setDoorState(BEQ::DOOR_STATE::CLOSE);
+		pUnit->setAlarm(0, 0, "");
+	}
+}
+
+void CBEQDemoDlg::OnBnClickedButtonSetState2()
+{
+	BEQ::IUnit* pUnit = nullptr;
+	BEQ::IEquipment* pEuqipment = nullptr;
+	BEQ_GetEquipment(pEuqipment, "BEQ001");
+	if (pEuqipment != nullptr) {
+		pUnit = pEuqipment->getUnit("U1");
+	}
+
+	if (pUnit != nullptr) {
+		// pUnit->setState(BEQ::EQ_STATE::RUN);
+		// pUnit->setDoorState(BEQ::DOOR_STATE::OPEN);
+		// pUnit->setAlarm(206, 1, "A单元-上腔体Z轴1异常");
+
+		/*
+		static int i = 0;
+		i++;
+		if (i % 6 == 1) {
+			pUnit->stepIdle();
+		}
+		if (i % 6 == 2) {
+			pUnit->stepMaterialReceived("A12345");
+		}
+		if (i % 6 == 3) {
+			pUnit->stepProcessingStarted("A12345");
+		}
+		if (i % 6 == 4) {
+			pUnit->stepProcessing("A12345", 15, 1);
+		}
+		if (i % 6 == 5) {
+			pUnit->stepMaterialRemoved("A12345");
+		}
+		if (i % 6 == 0) {
+			pUnit->stepProcessingCompleted("A12345");
+		}
+		*/
+
+
+		/*
+		auto now = std::chrono::system_clock::now();
+		auto duration_in_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
+		uint64_t timestamp = duration_in_milliseconds.count();
+		pUnit->setDataTimeAndResetData(timestamp);
+
+		static int i = 0;
+		i++;
+		if (i < 6) {
+			pUnit->addData("TMP", "1.1,2.1,3.2,4.3,5.4,6.6,7.7,8.8,9.9,10.1,11.1,12.1", false);
+			pUnit->addData("AIR", "112.19", false);
+			pUnit->addData("PRE", "151,152.3,153.4,154.5,155.6", true);
+		}
+		else {
+			pUnit->addData("TMP", "81.1,2.1,3.2,4.3,5.4,6.6,7.7,8.8,9.9,10.1,11.1,12.1", false);
+			pUnit->addData("AIR", "8112.19", false);
+			pUnit->addData("PRE", "8151,152.3,153.4,154.5,155.6", true);
+		}*/
+
+		pUnit->addRecipe(1001, "RECIPE_1001", false);
+		pUnit->addRecipe(1002, "RECIPE_1002", false);
+		pUnit->addRecipe(1003, "RECIPE_1003", false);
+		pUnit->addRecipe(1004, "RECIPE_1004", false);
+		pUnit->addRecipe(1005, "RECIPE_1005", false);
+		pUnit->addRecipe(1006, "RECIPE_1006", true);
+	}
+}
+
+void CBEQDemoDlg::OnBnClickedButtonServoTest1()
+{
+	BEQ::IServo* pServo = nullptr;
+	BEQ_CreateServo(pServo, "BLServo");
+	ASSERT(pServo);
+
+	BEQ::IRemoteEquipment* pRemoteEquipment = nullptr;
+	pServo->createRemoteEquipment(pRemoteEquipment, "127.0.0.1", 8192);
+	ASSERT(pRemoteEquipment);
+
+	if (pRemoteEquipment != nullptr) {
+		BEQ::IUnit* pUnitA = pRemoteEquipment->addUnit("UNITA", 5);
+		BEQ::IUnit* pUnitB = pRemoteEquipment->addUnit("UNITB", 5);
+	}
+
+	char szAddr[64];
+	pRemoteEquipment->getAddr(szAddr, 64);
+	CString s; s.Format("%s:%d", szAddr, pRemoteEquipment->getPort());
+	AfxMessageBox(s);
+
+	BEQ::ServoListener listener;
+	listener.onRemoteEqConnecting = [&](void* pServo, void* pRemoteEiuipment) -> void {
+		TRACE("<ServoListener>onRemoteEqConnecting...\n");
+	};
+	listener.onRemoteEqConnected = [&](void* pServo, void* pRemoteEiuipment) -> void {
+		TRACE("<ServoListener>onRemoteEqConnected...\n");
+	};
+	listener.onRemoteEqConnectFailed = [&](void* pServo, void* pRemoteEiuipment, int errorCode) -> void {
+		TRACE("<ServoListener>onRemoteEqConnectFailed...\n");
+	};
+	listener.onRemoteEqDisconnecting = [&](void* pServo, void* pRemoteEiuipment) -> void {
+		TRACE("<ServoListener>onRemoteEqDisconnecting...\n");
+	};
+	listener.onRemoteEqDisconnected = [&](void* pServo, void* pRemoteEiuipment) -> void {
+		TRACE("<ServoListener>onRemoteEqDisconnected...\n");
+	};
+	listener.onRemoteEqReadRawdata = [&](void* pServo, void* pRemoteEiuipment, const char* pszData, int len) -> void {
+		TRACE("<ServoListener>onRemoteEqReadRawdata...\n");
+	};
+	listener.onRemoteEqEventUpdate = [&](void* pServo, void* pRemoteEiuipment, void* pUnit, BEQ::REMOTE_EQ_EVENT eventCode) -> void {
+		TRACE("<ServoListener>onRemoteEqEventUpdate...\n");
+		HandleRemoteEqEventUpdate(eventCode, pUnit);
+	};
+	pServo->setListener(listener);
+	pServo->connectRemoteEquipment(pRemoteEquipment);
+}
+
+void CBEQDemoDlg::OnBnClickedButtonServoTest2()
+{
+	BEQ::IServo* pServo = nullptr;
+	BEQ_GetServo(pServo, "BLServo");
+	ASSERT(pServo);
+
+	char szName[256];
+	pServo->getName(szName, 256);
+	AfxMessageBox(szName);
+}
+
+void CBEQDemoDlg::OnBnClickedButtonServoTest3()
+{
+	// TODO: 在此添加控件通知处理程序代码
+}
+
+void CBEQDemoDlg::AppendTextToLog(const CString& text)
+{
+	// 追加文本之前检查行数
+	CString existingText;
+	m_editLog.GetWindowText(existingText);
+
+	// 计算当前行数
+	int lineCount = 0;
+	for (int i = 0; i < existingText.GetLength(); i++)
+	{
+		if (existingText[i] == '\n')
+			lineCount++;
+	}
+
+	// 如果行数超过 100,清空控件
+	if (lineCount >= 100)
+	{
+		m_editLog.SetWindowText(_T("")); // 清空控件
+	}
+
+	// 追加新文本
+	m_editLog.SetSel(m_editLog.GetWindowTextLength(), m_editLog.GetWindowTextLength()); // 设置光标到文本末尾
+	m_editLog.ReplaceSel(text + _T("\r\n")); // 追加文本并换行
+}
+
+const char* CBEQDemoDlg::ConverUint64ToTimeString(uint64_t time)
+{
+	static char buffer[32];
+	auto timePoint = std::chrono::time_point<std::chrono::system_clock>(std::chrono::milliseconds(time));
+	std::time_t t = std::chrono::system_clock::to_time_t(timePoint);
+	std::tm tmPtr;
+	if (localtime_s(&tmPtr, &t) == 0) {
+		strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tmPtr);
+	}
+	else {
+		snprintf(buffer, sizeof(buffer), "Invalid Time");
+	}
+
+	return buffer;
+}
+
+void CBEQDemoDlg::UpdateDoorStatus(CColorStatic& doorControl, bool isOpen)
+{
+	if (isOpen) {
+		doorControl.SetWindowText(_T("open"));
+		doorControl.SetBkColor(RGB(255, 0, 0)); // 红色表示打开
+	}
+	else {
+		doorControl.SetWindowText(_T("close"));
+		doorControl.SetBkColor(RGB(0, 255, 0)); // 绿色表示关闭
+	}
+	doorControl.Invalidate();
+}
+
+void CBEQDemoDlg::HandleRemoteEqEventUpdate(BEQ::REMOTE_EQ_EVENT eventCode, void* pUnit)
+{
+	BEQ::IUnit* pUnitEx = (BEQ::IUnit*)pUnit;
+	char chUnitName[128] = {0};
+	pUnitEx->getName(chUnitName, sizeof(chUnitName));
+
+	switch (eventCode) {
+	case BEQ::REMOTE_EQ_EVENT::DEVICE_STATUS_CHANGED: {
+		// 处理设备状态
+		CString strStatus;
+		static char* eqState[] = { "IDLE", "RUN", "DOWN", "MAINTENANCE", "MCHG", "E_TIME" };
+		strStatus.Format("DEVICE_STATUS_CHANGED@%s: %s", chUnitName, eqState[(int)pUnitEx->getState()]);
+		AppendTextToLog(strStatus);
+		break;
+	}
+	case BEQ::REMOTE_EQ_EVENT::DOOR_STATUS_CHANGED: {
+		// 处理门状态
+		UpdateDoorStatus(m_staticDoor1, (pUnitEx->getDoorState() >> 0) & 1);
+		UpdateDoorStatus(m_staticDoor2, (pUnitEx->getDoorState() >> 1) & 1);
+		UpdateDoorStatus(m_staticDoor3, (pUnitEx->getDoorState() >> 2) & 1);
+		UpdateDoorStatus(m_staticDoor4, (pUnitEx->getDoorState() >> 3) & 1);
+		UpdateDoorStatus(m_staticDoor5, (pUnitEx->getDoorState() >> 4) & 1);
+
+		CString strDoorStatus;
+		strDoorStatus.Format("DOOR_STATUS_CHANGED@%s: %d", chUnitName, pUnitEx->getDoorState());
+		AppendTextToLog(strDoorStatus);
+		break;
+	}
+	case BEQ::REMOTE_EQ_EVENT::ALARM_INFO_CHANGED: {
+		// 处理报警信息
+		CString strAlarmInfo;
+		strAlarmInfo.Format("ALARM_INFO_CHANGED@%s: %d %d", chUnitName, pUnitEx->getAlarmCode(), pUnitEx->getAlarmLevel());
+		AppendTextToLog(strAlarmInfo);
+		break;
+	}
+	case BEQ::REMOTE_EQ_EVENT::REMOVE_ALARM_INFO: {
+		// 处理解除告警
+		CString strRemoveAlarmInfo;
+		strRemoveAlarmInfo.Format("REMOVE_ALARM_INFO@%s: %d %d", chUnitName, pUnitEx->getAlarmCode(), pUnitEx->getAlarmLevel());
+		AppendTextToLog(strRemoveAlarmInfo);
+		break;
+	}
+	case BEQ::REMOTE_EQ_EVENT::PRODUCTION_PROCESS_CHANGED: {
+		// 处理制作过程状态
+		static char* stepState[] = { "IDLE", "MATERIAL_RECEIVED", "MATERIAL_REMOVED", "PROCESSING_STARTED", "PROCESSING", "PROCESSING_COMPLETED" };
+		CString strProduction;
+		strProduction.Format("PRODUCTION_PROCESS_CHANGED@%s: %s", chUnitName, stepState[(int)pUnitEx->getStepState()]);
+		AppendTextToLog(strProduction);
+		break;
+	}
+	case BEQ::REMOTE_EQ_EVENT::SERSOR_DATA_CHANGED: {
+		// 处理最新数据,传感器(温度、压力等)
+		CString strSersorData;
+		strSersorData.Format("SERSOR_DATA_CHANGED@%s: %s", chUnitName, ConverUint64ToTimeString(pUnitEx->getDataTime()));
+		AppendTextToLog(strSersorData);
+		break;
+	}
+	case::BEQ::REMOTE_EQ_EVENT::RECIPE_LIST_CHANGED: {
+		// 处理配方列表
+		CString strRecipeList;
+		strRecipeList.Format("RECIPE_LIST_CHANGED@%s: ", chUnitName);
+		std::map<int, std::string> mapRec;// = pUnit->getRecipes();
+		for (auto it = mapRec.begin(); it != mapRec.end(); it++)
+		{
+			TRACE("RecipeList[%d]: %s\n", it->first, it->second.c_str());
+		}
+		AppendTextToLog(strRecipeList);
+		break;
+	}
+	case BEQ::REMOTE_EQ_EVENT::LOAD_EVENT_CHANGED: {
+		// 处理上报事件
+		break;
+	}
+	default:
+		// 处理其他状态...
+		TRACE("<ServoListener>Unknown status...\n");
+		break;
+	}
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQDemo/BEQDemoDlg.h b/SourceCode/Bond/BEQDemo/BEQDemoDlg.h
new file mode 100644
index 0000000..d284a26
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/BEQDemoDlg.h
@@ -0,0 +1,56 @@
+
+// BEQDemoDlg.h : 头文件
+//
+
+#pragma once
+
+#include "ColorStatic.h"
+
+// CBEQDemoDlg 对话框
+class CBEQDemoDlg : public CDialogEx
+{
+// 构造
+public:
+	CBEQDemoDlg(CWnd* pParent = NULL);	// 标准构造函数
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_BEQDEMO_DIALOG };
+#endif
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
+
+
+// 实现
+protected:
+	HICON m_hIcon;
+	CEdit m_editLog;
+	CColorStatic m_staticDoor1;
+	CColorStatic m_staticDoor2;
+	CColorStatic m_staticDoor3;
+	CColorStatic m_staticDoor4;
+	CColorStatic m_staticDoor5;
+
+private:
+	void AppendTextToLog(const CString& text);
+	const char* ConverUint64ToTimeString(uint64_t time);
+	void UpdateDoorStatus(CColorStatic& doorControl, bool isOpen);
+	void HandleRemoteEqEventUpdate(BEQ::REMOTE_EQ_EVENT eventCode, void* pUnit);
+
+	// 生成的消息映射函数
+	virtual BOOL OnInitDialog();
+	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+	afx_msg void OnPaint();
+	afx_msg HCURSOR OnQueryDragIcon();
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnBnClickedButtonTest1();
+	afx_msg void OnBnClickedButtonTest2();
+	afx_msg void OnBnClickedButtonTest3();
+	afx_msg void OnBnClickedButtonSetState();
+	afx_msg void OnBnClickedButtonSetState2();
+	afx_msg void OnBnClickedButtonServoTest1();
+	afx_msg void OnBnClickedButtonServoTest2();
+	afx_msg void OnBnClickedButtonServoTest3();
+};
diff --git a/SourceCode/Bond/BEQDemo/ColorStatic.cpp b/SourceCode/Bond/BEQDemo/ColorStatic.cpp
new file mode 100644
index 0000000..1c00eb6
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/ColorStatic.cpp
@@ -0,0 +1,22 @@
+#include "stdafx.h"
+#include "ColorStatic.h"
+
+BEGIN_MESSAGE_MAP(CColorStatic, CStatic)
+    ON_WM_PAINT()
+END_MESSAGE_MAP()
+
+void CColorStatic::OnPaint()
+{
+    CPaintDC dc(this); // 创建绘图上下文
+
+    // 填充背景颜色
+    CRect rect;
+    GetClientRect(&rect);
+    dc.FillSolidRect(rect, m_bkColor);
+
+    // 绘制文本
+    CString text;
+    GetWindowText(text);
+    dc.SetTextColor(RGB(0, 0, 0)); // 设置文本颜色为黑色
+    dc.DrawText(text, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); // 绘制文本
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQDemo/ColorStatic.h b/SourceCode/Bond/BEQDemo/ColorStatic.h
new file mode 100644
index 0000000..ce6ef3b
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/ColorStatic.h
@@ -0,0 +1,15 @@
+#pragma once
+#include <afxwin.h>
+
+class CColorStatic : public CStatic
+{
+public:
+    void SetBkColor(COLORREF color) { m_bkColor = color; }
+
+protected:
+    afx_msg void OnPaint();
+    DECLARE_MESSAGE_MAP()
+
+private:
+    COLORREF m_bkColor = RGB(255, 255, 255); // 默认背景颜色为白色
+};
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQDemo/ReadMe.txt b/SourceCode/Bond/BEQDemo/ReadMe.txt
new file mode 100644
index 0000000..2c07c19
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/ReadMe.txt
@@ -0,0 +1,67 @@
+锘�================================================================================
+    MICROSOFT 鍩虹绫诲簱 : BEQDemo 椤圭洰姒傝堪
+===============================================================================
+
+搴旂敤绋嬪簭鍚戝宸蹭负鎮ㄥ垱寤轰簡姝� BEQDemo 搴旂敤绋嬪簭銆傛搴旂敤绋嬪簭涓嶄粎婕旂ず Microsoft 鍩虹绫荤殑鍩烘湰浣跨敤鏂规硶锛岃繕鍙綔涓烘偍缂栧啓搴旂敤绋嬪簭鐨勮捣鐐广��
+
+鏈枃浠舵瑕佷粙缁嶇粍鎴� BEQDemo 搴旂敤绋嬪簭鐨勬瘡涓枃浠剁殑鍐呭銆�
+
+BEQDemo.vcxproj
+    杩欐槸浣跨敤搴旂敤绋嬪簭鍚戝鐢熸垚鐨� VC++ 椤圭洰鐨勪富椤圭洰鏂囦欢锛屽叾涓寘鍚敓鎴愯鏂囦欢鐨� Visual C++ 鐨勭増鏈俊鎭紝浠ュ強鏈夊叧浣跨敤搴旂敤绋嬪簭鍚戝閫夋嫨鐨勫钩鍙般�侀厤缃拰椤圭洰鍔熻兘鐨勪俊鎭��
+
+BEQDemo.vcxproj.filters
+    杩欐槸浣跨敤鈥滃簲鐢ㄧ▼搴忓悜瀵尖�濈敓鎴愮殑 VC++ 椤圭洰绛涢�夊櫒鏂囦欢銆傚畠鍖呭惈鏈夊叧椤圭洰鏂囦欢涓庣瓫閫夊櫒涔嬮棿鐨勫叧鑱斾俊鎭�傚湪 IDE 涓紝閫氳繃杩欑鍏宠仈锛屽湪鐗瑰畾鑺傜偣涓嬩互鍒嗙粍褰㈠紡鏄剧ず鍏锋湁鐩镐技鎵╁睍鍚嶇殑鏂囦欢銆備緥濡傦紝鈥�.cpp鈥濇枃浠朵笌鈥滄簮鏂囦欢鈥濈瓫閫夊櫒鍏宠仈銆�
+
+BEQDemo.h
+    杩欐槸搴旂敤绋嬪簭鐨勪富澶存枃浠躲��
+    鍏朵腑鍖呮嫭鍏朵粬椤圭洰鐗瑰畾鐨勬爣澶达紙鍖呮嫭 Resource.h锛夛紝骞跺0鏄� CBEQDemoApp 搴旂敤绋嬪簭绫汇��
+
+BEQDemo.cpp
+    杩欐槸鍖呭惈搴旂敤绋嬪簭绫� CBEQDemoApp 鐨勪富搴旂敤绋嬪簭婧愭枃浠躲��
+
+BEQDemo.rc
+    杩欐槸绋嬪簭浣跨敤鐨勬墍鏈� Microsoft Windows 璧勬簮鐨勫垪琛ㄣ�傚畠鍖呮嫭 RES 瀛愮洰褰曚腑瀛樺偍鐨勫浘鏍囥�佷綅鍥惧拰鍏夋爣銆傛鏂囦欢鍙互鐩存帴鍦� Microsoft Visual C++ 涓繘琛岀紪杈戙�傞」鐩祫婧愬寘鍚湪 2052 涓��
+
+res\BEQDemo.ico
+    杩欐槸鐢ㄤ綔搴旂敤绋嬪簭鍥炬爣鐨勫浘鏍囨枃浠躲�傛鍥炬爣鍖呮嫭鍦ㄤ富璧勬簮鏂囦欢 BEQDemo.rc 涓��
+
+res\BEQDemo.rc2
+    姝ゆ枃浠跺寘鍚笉鍦� Microsoft Visual C++ 涓繘琛岀紪杈戠殑璧勬簮銆傛偍搴旇灏嗕笉鍙敱璧勬簮缂栬緫鍣ㄧ紪杈戠殑鎵�鏈夎祫婧愭斁鍦ㄦ鏂囦欢涓��
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+搴旂敤绋嬪簭鍚戝鍒涘缓涓�涓璇濇绫伙細
+
+BEQDemoDlg.h銆丅EQDemoDlg.cpp - 瀵硅瘽妗�
+    杩欎簺鏂囦欢鍖呭惈 CBEQDemoDlg 绫汇�傛绫诲畾涔夊簲鐢ㄧ▼搴忕殑涓诲璇濇鐨勮涓恒�傚璇濇妯℃澘鍖呭惈鍦� BEQDemo.rc 涓紝璇ユ枃浠跺彲浠ュ湪 Microsoft Visual C++ 涓紪杈戙��
+
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬鍔熻兘锛�
+
+ActiveX 鎺т欢
+    璇ュ簲鐢ㄧ▼搴忓寘鍚浣跨敤 ActiveX 鎺т欢鐨勬敮鎸併��
+
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬鏍囧噯鏂囦欢:
+
+StdAfx.h, StdAfx.cpp
+    杩欎簺鏂囦欢鐢ㄤ簬鐢熸垚鍚嶄负 BEQDemo.pch 鐨勯缂栬瘧澶� (PCH) 鏂囦欢鍜屽悕涓� StdAfx.obj 鐨勯缂栬瘧绫诲瀷鏂囦欢銆�
+
+Resource.h
+    杩欐槸鏍囧噯澶存枃浠讹紝鍙敤浜庡畾涔夋柊鐨勮祫婧� ID銆侻icrosoft Visual C++ 灏嗚鍙栧苟鏇存柊姝ゆ枃浠躲��
+
+BEQDemo.manifest
+	Windows XP 浣跨敤搴旂敤绋嬪簭娓呭崟鏂囦欢鏉ユ弿杩扮壒瀹氱増鏈殑骞惰绋嬪簭闆嗙殑搴旂敤绋嬪簭渚濊禆椤广�傚姞杞界▼搴忎娇鐢ㄨ繖浜涗俊鎭潵浠庣▼搴忛泦缂撳瓨涓姞杞界浉搴旂殑绋嬪簭闆嗭紝骞朵繚鎶ゅ叾涓嶈搴旂敤绋嬪簭璁块棶銆傚簲鐢ㄧ▼搴忔竻鍗曞彲鑳戒細鍖呭惈鍦ㄥ唴锛屼互浣滀负涓庡簲鐢ㄧ▼搴忓彲鎵ц鏂囦欢瀹夎鍦ㄥ悓涓�鏂囦欢澶逛腑鐨勫閮� .manifest 鏂囦欢杩涜閲嶆柊鍒嗗彂锛屽畠杩樺彲鑳戒互璧勬簮鐨勫舰寮忓寘鍚湪鍙墽琛屾枃浠朵腑銆�
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬娉ㄩ噴:
+
+搴旂敤绋嬪簭鍚戝浣跨敤鈥淭ODO:鈥濇潵鎸囩ず搴旀坊鍔犳垨鑷畾涔夌殑婧愪唬鐮侀儴鍒嗐��
+
+濡傛灉搴旂敤绋嬪簭浣跨敤鍏变韩 DLL 涓殑 MFC锛屾偍灏嗛渶瑕侀噸鏂板垎鍙� MFC DLL銆傚鏋滃簲鐢ㄧ▼搴忔墍浣跨敤鐨勮瑷�涓庢搷浣滅郴缁熺殑鍖哄煙璁剧疆涓嶅悓锛屽垯杩橀渶瑕侀噸鏂板垎鍙戠浉搴旂殑鏈湴鍖栬祫婧� mfc110XXX.DLL銆�
+鏈夊叧涓婅堪璇濋鐨勬洿澶氫俊鎭紝璇峰弬瑙� MSDN 鏂囨。涓湁鍏抽噸鏂板垎鍙� Visual C++ 搴旂敤绋嬪簭鐨勯儴鍒嗐��
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/SourceCode/Bond/BEQDemo/res/BEQDemo.ico b/SourceCode/Bond/BEQDemo/res/BEQDemo.ico
new file mode 100644
index 0000000..d56fbcd
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/res/BEQDemo.ico
Binary files differ
diff --git a/SourceCode/Bond/BEQDemo/res/BEQDemo.rc2 b/SourceCode/Bond/BEQDemo/res/BEQDemo.rc2
new file mode 100644
index 0000000..b250ac9
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/res/BEQDemo.rc2
Binary files differ
diff --git a/SourceCode/Bond/BEQDemo/res/application.exe.manifest b/SourceCode/Bond/BEQDemo/res/application.exe.manifest
new file mode 100644
index 0000000..b96c40d
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/res/application.exe.manifest
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+    <assemblyIdentity
+         name="XP style manifest"
+         processorArchitecture="amd64"
+         version="1.0.0.0"
+         type="win32"/>
+    <dependency>
+        <dependentAssembly>
+            <assemblyIdentity
+                type="win32"
+                name="Microsoft.Windows.Common-Controls"
+                version="6.0.0.0"
+                processorArchitecture="amd64"
+                publicKeyToken="6595b64144ccf1df"
+                language="*"
+            />
+        </dependentAssembly>
+    </dependency>
+</assembly>
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQDemo/resource.h b/SourceCode/Bond/BEQDemo/resource.h
new file mode 100644
index 0000000..6afabc2
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/resource.h
Binary files differ
diff --git a/SourceCode/Bond/BEQDemo/stdafx.cpp b/SourceCode/Bond/BEQDemo/stdafx.cpp
new file mode 100644
index 0000000..2501997
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/stdafx.cpp
@@ -0,0 +1,8 @@
+
+// stdafx.cpp : 只包括标准包含文件的源文件
+// BEQDemo.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+
diff --git a/SourceCode/Bond/BEQDemo/stdafx.h b/SourceCode/Bond/BEQDemo/stdafx.h
new file mode 100644
index 0000000..bb6502b
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/stdafx.h
@@ -0,0 +1,54 @@
+
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+
+#pragma once
+
+#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 扩展
+
+
+#include <afxdisp.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 支持
+
+
+
+
+
+#include "..\BEQLibrarySDK\include\BEQLib.h"
+
+
+
+#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
+
+
diff --git a/SourceCode/Bond/BEQDemo/targetver.h b/SourceCode/Bond/BEQDemo/targetver.h
new file mode 100644
index 0000000..416cebf
--- /dev/null
+++ b/SourceCode/Bond/BEQDemo/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
+
+// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
+// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
+
+#include <SDKDDKVer.h>
diff --git a/SourceCode/Bond/BEQLibrary/AcceptClient.cpp b/SourceCode/Bond/BEQLibrary/AcceptClient.cpp
new file mode 100644
index 0000000..c23b505
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/AcceptClient.cpp
@@ -0,0 +1,58 @@
+#include "stdafx.h"
+#include "AcceptClient.h"
+
+
+namespace BEQ {
+	CAcceptClient::CAcceptClient()
+	{
+		m_listener.onRead = nullptr;
+		m_listener.onClose = nullptr;
+		m_pContext1 = nullptr;
+		m_pContext2 = nullptr;
+		m_pContext3 = nullptr;
+		m_pContext4 = nullptr;
+	}
+
+	CAcceptClient::~CAcceptClient()
+	{
+
+	}
+
+	void CAcceptClient::setListener(AcceptClientListener listener)
+	{
+		m_listener.onRead = listener.onRead;
+		m_listener.onClose = listener.onClose;
+	}
+
+	void CAcceptClient::OnClose(int nErrorCode)
+	{
+		if (m_listener.onClose != nullptr) {
+			m_listener.onClose(this);
+		}
+
+		__super::OnClose(nErrorCode);
+	}
+
+
+	void CAcceptClient::OnReceive(int nErrorCode)
+	{
+		char szBuffer[4096];
+		int nRead = Receive(szBuffer, 4096);
+		switch (nRead) {
+		case 0:
+			Close();
+			break;
+		case SOCKET_ERROR:
+			if (GetLastError() != WSAEWOULDBLOCK) {
+				Close();
+			}
+			break;
+		default:
+			if (m_listener.onRead != nullptr) {
+				m_listener.onRead(this, szBuffer, nRead);
+			}
+		}
+
+		__super::OnReceive(nErrorCode);
+	}
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQLibrary/AcceptClient.h b/SourceCode/Bond/BEQLibrary/AcceptClient.h
new file mode 100644
index 0000000..ce0f062
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/AcceptClient.h
@@ -0,0 +1,37 @@
+#pragma once
+#include <afxSock.h>
+#include <functional>
+
+namespace BEQ {
+	typedef std::function<int(void* pClient, const char* pData, int nLen)> ONREAD;
+	typedef std::function<int(void* pClient)> ONCLOSE;
+
+	typedef struct _AcceptClientListener
+	{
+		ONREAD			onRead;
+		ONCLOSE			onClose;
+	} AcceptClientListener;
+
+	class CAcceptClient :
+		public CAsyncSocket
+	{
+	public:
+		CAcceptClient();
+		~CAcceptClient();
+
+	public:
+		void setListener(AcceptClientListener listener);
+		virtual void OnClose(int nErrorCode);
+		virtual void OnReceive(int nErrorCode);
+
+	private:
+		AcceptClientListener m_listener;
+
+	public:
+		void* m_pContext1;
+		void* m_pContext2;
+		void* m_pContext3;
+		void* m_pContext4;
+	};
+}
+
diff --git a/SourceCode/Bond/BEQLibrary/Action.cpp b/SourceCode/Bond/BEQLibrary/Action.cpp
new file mode 100644
index 0000000..a62a675
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/Action.cpp
@@ -0,0 +1,66 @@
+#include "stdafx.h"
+#include "Action.h"
+
+
+namespace BEQ {
+	static int g_nActionId = 0;
+	CAction::CAction()
+	{
+		m_id = ++g_nActionId;
+		m_nType = 0;
+		m_nTime = 0;
+		m_nValidLen = 0;
+		m_nReplyCode = REPLY_NOERROR;
+	}
+
+	CAction::CAction(int type)
+	{
+		m_id = ++g_nActionId;
+		m_nType = type;
+		m_nTime = 0;
+		m_nValidLen = 0;
+		m_nReplyCode = REPLY_NOERROR;
+	}
+
+	CAction::~CAction()
+	{
+	}
+
+	int CAction::getId()
+	{
+		return m_id;
+	}
+
+	int CAction::getType()
+	{
+		return m_nType;
+	}
+
+	int CAction::timeIncrease(int ms)
+	{
+		m_nTime += ms;
+		return m_nTime;
+	}
+
+	void CAction::getRawData(char*& pRawData, int& size, int& validLen)
+	{
+		pRawData = m_szRawData;
+		size = 1024;
+		validLen = m_nValidLen;
+	}
+
+	int CAction::setRawString(const char* pszTxt)
+	{
+		int len = min(1023, strlen(pszTxt));
+		memcpy(m_szRawData, pszTxt, len);
+		m_szRawData[len] = '\0';
+		m_nValidLen = len;
+
+		return len;
+	}
+
+	void CAction::setReplyCode(int code)
+	{
+		m_nReplyCode = code;
+	}
+}
diff --git a/SourceCode/Bond/BEQLibrary/Action.h b/SourceCode/Bond/BEQLibrary/Action.h
new file mode 100644
index 0000000..2e4123f
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/Action.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#define REPLY_PACKET_NOT_END	1
+#define REPLY_NOERROR			0
+#define REPLY_MEMROY_ERROR		-1
+#define REPLY_PACKET_ERROR		-2
+
+namespace BEQ {
+	class CAction
+	{
+	public:
+		CAction();
+		CAction(int type);
+		~CAction();
+
+	public:
+		int getId();
+		int getType();
+		int timeIncrease(int ms);
+		int setRawString(const char* pszTxt);
+		void getRawData(char*& pRawData, int& size, int& validLen);
+		void setReplyCode(int code);
+
+	private:
+		int m_id;
+		int m_nType;
+		int m_nTime;
+		char m_szRawData[1024];
+		int m_nValidLen;
+		int m_nReplyCode;
+	};
+}
+
diff --git a/SourceCode/Bond/BEQLibrary/BEQCommon.h b/SourceCode/Bond/BEQLibrary/BEQCommon.h
new file mode 100644
index 0000000..0adb8fa
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/BEQCommon.h
@@ -0,0 +1,84 @@
+#pragma once
+
+
+#define LERROR		4
+#define LWARN		3
+#define LINFO		2
+#define LDEBUG		1
+
+/* ERROR CODE*/
+#define ERR_NOERR					0		/* 没有错误 */
+#define ERR_MISMATCH				-1		/* 机器名不匹配 */
+#define ERR_UNKNOWN_CMD				-2		/* 未识别的指令 */
+#define ERR_UNIT_ALREADY_EXIST		-3		/* 单元已存在 */
+#define ERR_NO_UNIT					-4		/* 单元不存在 */
+#define ERR_PARAM_ERROE				-5		/* 参数不正确 */
+
+/* Command Request */
+#define CMD_GET_EQID_REQ		_T("GET_EQID_REQ")
+#define CMD_GET_VERSION_REQ		_T("GET_VERSION_REQ")
+#define CMD_GET_STATE_REQ		_T("GET_STATE_REQ")
+#define CMD_GET_DOOR_REQ		_T("GET_DOOR_REQ")
+#define CMD_GET_ERROR_REQ		_T("GET_ERROR_REQ")
+#define CMD_GET_STEP_REQ		_T("GET_STEP_REQ")
+#define CMD_GET_DATA_REQ		_T("GET_DATA_REQ")
+#define CMD_GET_RECIPE_LIST_REQ	_T("GET_RECIPE_LIST_REQ")
+#define CMD_RUN_RECIPE_REQ		_T("RUN_RECIPE_REQ")
+#define CMD_LOAD_READY_REQ		_T("LOAD_READY_REQ")
+#define CMD_LOAD_COMPLETE_REQ	_T("LOAD_COMPLETE_REQ")
+#define CMD_UNLOAD_COMPLETE_REQ	_T("UNLOAD_COMPLETE_REQ")
+
+
+/* Command Reply*/
+#define CMD_GET_EQID_REP		_T("GET_EQID_REP")
+#define CMD_GET_VERSION_REP		_T("GET_VERSION_REP")
+#define CMD_GET_STATE_REP		_T("GET_STATE_REP")
+#define CMD_GET_DOOR_REP		_T("GET_DOOR_REP")
+#define CMD_GET_ERROR_REP		_T("GET_ERROR_REP")
+#define CMD_GET_STEP_REP		_T("GET_STEP_REP")
+#define CMD_GET_DATA_REP		_T("GET_DATA_REP")
+#define CMD_GET_RECIPE_LIST_REP	_T("GET_RECIPE_LIST_REP")
+#define CMD_RUN_RECIPE_REP		_T("RUN_RECIPE_REP")
+#define CMD_LOAD_READY_REP		_T("LOAD_READY_REP")
+#define CMD_LOAD_COMPLETE_REP	_T("LOAD_COMPLETE_REP")
+#define CMD_UNLOAD_COMPLETE_REP	_T("UNLOAD_COMPLETE_REP")
+
+
+/* Auto send */
+#define AS_MC_STATE_REP			_T("MC_STATE_REP")
+#define AS_GET_DOOR_REP			_T("GET_DOOR_REP")
+#define AS_SEND_ERROR_REP		_T("SEND_ERROR_REP")
+#define AS_REMOVE_ERROR_REP		_T("REMOVE_ERROR_REP")
+#define AS_MC_INFO_REP			_T("MC_INFO_REP")
+#define AS_SEND_STEP_REP		_T("SEND_STEP_REP")
+#define AS_SEND_EVENT_REP		_T("SEND_EVENT_REP")
+
+
+
+/* Param */
+#define PARAM_EQID				_T("EQID")
+#define PARAM_VERSION			_T("VERSION")
+#define PARAM_UNIT				_T("UNIT")
+#define PARAM_STATE				_T("STATE")
+#define PARAM_DOOR				_T("DOOR")
+#define PARAM_CODE				_T("CODE")
+#define PARAM_STEP				_T("STEP")
+#define PARAM_PVTIME			_T("PVTIME")
+#define PARAM_SVTIME			_T("SVTIME")
+#define PARAM_MATERIAL_ID		_T("MATERIAL_ID")
+#define PARAM_MATERIEL_ID		_T("MATERIEL_ID")
+#define PARAM_RESULT			_T("RESULT")
+#define PARAM_TEX				_T("TEX")
+#define PARAM_TIME				_T("TIME")
+#define PARAM_AIR				_T("AIR")
+#define PARAM_PRE				_T("PRE")
+#define PARAM_TMP				_T("TMP")
+#define PARAM_RECIPE_LIST		_T("RECIPE_LIST")
+#define PARAM_RECIPEID			_T("RECIPEID")
+#define PARAM_RECIPENAME		_T("RECIPENAME")
+#define PARAM_EVENT				_T("EVENT")
+
+
+/* EVENT */
+#define EVENT_LOAD				_T("LOAD")
+#define EVENT_UNLOAD			_T("UNLOAD")
diff --git a/SourceCode/Bond/BEQLibrary/BEQLib.h b/SourceCode/Bond/BEQLibrary/BEQLib.h
new file mode 100644
index 0000000..dd26bfd
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/BEQLib.h
@@ -0,0 +1,74 @@
+#pragma once
+#include <vector>
+#include "IServo.h"
+#include "IUnit.h"
+#include "IEquipment.h"
+#include "IRemoteEquipment.h"
+
+#ifdef _COMPILE_AS_LIB
+	#warning "compiling as lib!"
+#else
+	#ifdef _DEBUG
+		#ifndef _WIN64
+			#pragma comment(lib, "../BEQibrarySDK/lib/Win32/Debug/BEQ.lib")
+		#else 
+			#pragma comment(lib, "../BEQLibrarySDK/lib/x64/Debug/BEQ.lib")
+		#endif
+	#else 
+		#ifndef _WIN64
+			#pragma comment(lib, "../BEQLibrarySDK/lib/Win32/Release/BEQ.lib")
+		#else 
+			#pragma comment(lib, "../BEQLibrarySDK/lib/x64/Release/BEQ.lib")
+		#endif
+	#endif
+#endif // !BUILD_AS_LIB
+
+///////////////////////////////////////////////////////////////////////////////////
+//// Define C linkage if using a C++ compiler
+///////////////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+	///////////////////////////////////////////////////////////////////////////////////
+	//// Determine callling convention baesd on compiler
+	///////////////////////////////////////////////////////////////////////////////////
+#ifdef __BORLANDC__
+
+#ifdef __WIN32__
+#define EXPORTED __declspec(dllexport) __stdcall
+#else
+#define EXPORTED FAR PASCAL __export
+#endif // WIN32
+
+#else // __BORLANDC__
+
+
+#ifdef WIN32
+#define EXPORTED __declspec(dllexport)
+#else
+#define EXPORTED FAR PASCAL __export
+#endif // WIN32
+
+#endif //__BORLANDC__
+
+
+
+	/////////////////////////////////////////////////////////////////////////////////////
+	//// 导出函数
+	////////////////////////////////////////////////////////////////////////////////////
+	int			EXPORTED	BEQ_Initialize();
+	int			EXPORTED	BEQ_Term();
+	int			EXPORTED	BEQ_CreateServo(BEQ::IServo*& pServo, const char* pszName);
+	int			EXPORTED	BEQ_GetServo(BEQ::IServo*& pServo, const char* pszName);
+	int			EXPORTED	BEQ_DestroyServo(BEQ::IServo* pServo);
+	int			EXPORTED	BEQ_CreateEquipment(BEQ::IEquipment*& pEquipment, const char* pszName);
+	int			EXPORTED	BEQ_GetEquipment(BEQ::IEquipment*& pEquipment, const char* pszName);
+	int			EXPORTED	BEQ_DestroyEquipment(BEQ::IEquipment*& pEquipment);
+
+#ifdef __cplusplus
+};
+
+#endif //__cplusplus
+
+
diff --git a/SourceCode/Bond/BEQLibrary/BEQLibrary.cpp b/SourceCode/Bond/BEQLibrary/BEQLibrary.cpp
new file mode 100644
index 0000000..3f1abad
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/BEQLibrary.cpp
@@ -0,0 +1,63 @@
+// BEQLibrary.cpp : 定义 DLL 的初始化例程。
+//
+
+#include "stdafx.h"
+#include "BEQLibrary.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+//
+//TODO:  如果此 DLL 相对于 MFC DLL 是动态链接的,
+//		则从此 DLL 导出的任何调入
+//		MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
+//		该函数的最前面。
+//
+//		例如: 
+//
+//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
+//		{
+//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
+//			// 此处为普通函数体
+//		}
+//
+//		此宏先于任何 MFC 调用
+//		出现在每个函数中十分重要。  这意味着
+//		它必须作为函数中的第一个语句
+//		出现,甚至先于所有对象变量声明,
+//		这是因为它们的构造函数可能生成 MFC
+//		DLL 调用。
+//
+//		有关其他详细信息,
+//		请参阅 MFC 技术说明 33 和 58。
+//
+
+// CBEQLibraryApp
+
+BEGIN_MESSAGE_MAP(CBEQLibraryApp, CWinApp)
+END_MESSAGE_MAP()
+
+
+// CBEQLibraryApp 构造
+
+CBEQLibraryApp::CBEQLibraryApp()
+{
+	// TODO:  在此处添加构造代码,
+	// 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的一个 CBEQLibraryApp 对象
+
+CBEQLibraryApp theApp;
+
+
+// CBEQLibraryApp 初始化
+
+BOOL CBEQLibraryApp::InitInstance()
+{
+	CWinApp::InitInstance();
+
+	return TRUE;
+}
diff --git a/SourceCode/Bond/BEQLibrary/BEQLibrary.def b/SourceCode/Bond/BEQLibrary/BEQLibrary.def
new file mode 100644
index 0000000..14ff794
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/BEQLibrary.def
@@ -0,0 +1,6 @@
+; BEQLibrary.def : 声明 DLL 的模块参数。
+
+LIBRARY
+
+EXPORTS
+    ; 此处可以是显式导出
diff --git a/SourceCode/Bond/BEQLibrary/BEQLibrary.h b/SourceCode/Bond/BEQLibrary/BEQLibrary.h
new file mode 100644
index 0000000..aa4f1b6
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/BEQLibrary.h
@@ -0,0 +1,27 @@
+// BEQLibrary.h : BEQLibrary DLL 的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
+#endif
+
+#include "resource.h"		// 主符号
+
+
+// CBEQLibraryApp
+// 有关此类实现的信息,请参阅 BEQLibrary.cpp
+//
+
+class CBEQLibraryApp : public CWinApp
+{
+public:
+	CBEQLibraryApp();
+
+// 重写
+public:
+	virtual BOOL InitInstance();
+
+	DECLARE_MESSAGE_MAP()
+};
diff --git a/SourceCode/Bond/BEQLibrary/BEQLibrary.rc b/SourceCode/Bond/BEQLibrary/BEQLibrary.rc
new file mode 100644
index 0000000..dadfa17
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/BEQLibrary.rc
Binary files differ
diff --git a/SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj b/SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj
new file mode 100644
index 0000000..8aadde3
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj
@@ -0,0 +1,265 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{8421CE64-06F9-48F4-A3F3-ACFB683C94D4}</ProjectGuid>
+    <RootNamespace>BEQLibrary</RootNamespace>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+    <Keyword>MFCDLLProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <TargetName>BEQ</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <TargetName>BEQ</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ModuleDefinitionFile>.\BEQLibrary.def</ModuleDefinitionFile>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ModuleDefinitionFile>.\BEQLibrary.def</ModuleDefinitionFile>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <PostBuildEvent>
+      <Command>copy "$(SolutionDir)$(ProjectName)\IEquipment.h" "$(SolutionDir)BEQLibrarySDK\Include\IEquipment.h"
+copy "$(SolutionDir)$(ProjectName)\IRemoteEquipment.h" "$(SolutionDir)BEQLibrarySDK\Include\IRemoteEquipment.h"
+copy "$(SolutionDir)$(ProjectName)\IUnit.h" "$(SolutionDir)BEQLibrarySDK\Include\IUnit.h"
+copy "$(SolutionDir)$(ProjectName)\IServo.h" "$(SolutionDir)BEQLibrarySDK\Include\IServo.h"
+copy "$(SolutionDir)$(ProjectName)\BEQLib.h" "$(SolutionDir)BEQLibrarySDK\Include\BEQLib.h"
+copy "$(SolutionDir)$(Platform)\$(Configuration)\BEQ.dll" "$(SolutionDir)BEQLibrarySDK\lib\$(Platform)\$(Configuration)\BEQ.dll"
+copy "$(SolutionDir)$(Platform)\$(Configuration)\BEQ.lib" "$(SolutionDir)BEQLibrarySDK\lib\$(Platform)\$(Configuration)\BEQ.lib"
+copy "$(SolutionDir)$(Platform)\$(Configuration)\BEQ.pdb" "$(SolutionDir)BEQLibrarySDK\lib\$(Platform)\$(Configuration)\BEQ.pdb_"
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <ModuleDefinitionFile>.\BEQLibrary.def</ModuleDefinitionFile>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <ModuleDefinitionFile>.\BEQLibrary.def</ModuleDefinitionFile>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+    <PostBuildEvent>
+      <Command>copy "$(SolutionDir)$(ProjectName)\IEquipment.h" "$(SolutionDir)BEQLibrarySDK\Include\IEquipment.h"
+copy "$(SolutionDir)$(ProjectName)\IRemoteEquipment.h" "$(SolutionDir)BEQLibrarySDK\Include\IRemoteEquipment.h"
+copy "$(SolutionDir)$(ProjectName)\IUnit.h" "$(SolutionDir)BEQLibrarySDK\Include\IUnit.h"
+copy "$(SolutionDir)$(ProjectName)\IServo.h" "$(SolutionDir)BEQLibrarySDK\Include\IServo.h"
+copy "$(SolutionDir)$(ProjectName)\BEQLib.h" "$(SolutionDir)BEQLibrarySDK\Include\BEQLib.h"
+copy "$(SolutionDir)$(Platform)\$(Configuration)\BEQ.dll" "$(SolutionDir)BEQLibrarySDK\lib\$(Platform)\$(Configuration)\BEQ.dll"
+copy "$(SolutionDir)$(Platform)\$(Configuration)\BEQ.lib" "$(SolutionDir)BEQLibrarySDK\lib\$(Platform)\$(Configuration)\BEQ.lib"
+copy "$(SolutionDir)$(Platform)\$(Configuration)\BEQ.pdb" "$(SolutionDir)BEQLibrarySDK\lib\$(Platform)\$(Configuration)\BEQ.pdb_"
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="AcceptClient.cpp" />
+    <ClCompile Include="Action.cpp" />
+    <ClCompile Include="BEQLibrary.cpp" />
+    <ClCompile Include="BEQMain.cpp" />
+    <ClCompile Include="Data.cpp" />
+    <ClCompile Include="Equipment.cpp" />
+    <ClCompile Include="RemoteEquipment.cpp" />
+    <ClCompile Include="Servo.cpp" />
+    <ClCompile Include="SocketClient.cpp" />
+    <ClCompile Include="SocketServer.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="Unit.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="AcceptClient.h" />
+    <ClInclude Include="Action.h" />
+    <ClInclude Include="BEQCommon.h" />
+    <ClInclude Include="BEQLib.h" />
+    <ClInclude Include="BEQLibrary.h" />
+    <ClInclude Include="Data.h" />
+    <ClInclude Include="Equipment.h" />
+    <ClInclude Include="IEquipment.h" />
+    <ClInclude Include="IRemoteEquipment.h" />
+    <ClInclude Include="IServo.h" />
+    <ClInclude Include="IUnit.h" />
+    <ClInclude Include="RemoteEquipment.h" />
+    <ClInclude Include="Resource.h" />
+    <ClInclude Include="Servo.h" />
+    <ClInclude Include="SocketClient.h" />
+    <ClInclude Include="SocketServer.h" />
+    <ClInclude Include="stdafx.h" />
+    <ClInclude Include="targetver.h" />
+    <ClInclude Include="Unit.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="BEQLibrary.def" />
+    <None Include="res\BEQLibrary.rc2" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="BEQLibrary.rc" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj.filters b/SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj.filters
new file mode 100644
index 0000000..8d7790e
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj.filters
@@ -0,0 +1,130 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="婧愭枃浠�">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="澶存枃浠�">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="璧勬簮鏂囦欢">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="BEQLibrary.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="BEQMain.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="Servo.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="SocketClient.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="SocketServer.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="AcceptClient.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="Equipment.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="Data.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="Unit.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="RemoteEquipment.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="Action.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="stdafx.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Resource.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="IServo.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Servo.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="SocketClient.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="SocketServer.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="AcceptClient.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Equipment.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="IEquipment.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Data.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Unit.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="IUnit.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="BEQLibrary.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="BEQLib.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="BEQCommon.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="RemoteEquipment.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="IRemoteEquipment.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Action.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="BEQLibrary.def">
+      <Filter>婧愭枃浠�</Filter>
+    </None>
+    <None Include="res\BEQLibrary.rc2">
+      <Filter>璧勬簮鏂囦欢</Filter>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="BEQLibrary.rc">
+      <Filter>璧勬簮鏂囦欢</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj.user b/SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj.user
new file mode 100644
index 0000000..abe8dd8
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/BEQLibrary.vcxproj.user
@@ -0,0 +1,4 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQLibrary/BEQMain.cpp b/SourceCode/Bond/BEQLibrary/BEQMain.cpp
new file mode 100644
index 0000000..f440be7
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/BEQMain.cpp
@@ -0,0 +1,216 @@
+// BEQMain.cpp : 定义 DLL 的初始化例程。
+//
+
+
+#include "stdafx.h"
+#include "BEQCommon.h"
+#include "Servo.h"
+#include "Equipment.h"
+#include <map>
+#include <string>
+
+
+CString			g_strLogDir;				// 日志目录
+CStdioFile		g_logFile;					// 日志文件
+int				g_nActionTimeout = 5000;	// 超时时间		
+
+std::map<std::string, BEQ::CServo*>		g_mapServos;		// Servo映身表
+std::map<std::string, BEQ::CEquipment*>	g_mapEquipments;	// Equipment映身表
+
+CString& GetCurTime(CString& strTime)
+{
+	_SYSTEMTIME sysTime;
+	GetLocalTime(&sysTime);
+	strTime.Format(_T("%d/%02d/%02d %02d:%02d:%02d.%03d"), sysTime.wYear, sysTime.wMonth, sysTime.wDay,
+		sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds);
+	return strTime;
+}
+
+void log(int level, const char* pszMessage)
+{
+	if (g_logFile.m_hFile != CFile::hFileNull) {
+		CTime time = CTime::GetCurrentTime();
+		CString strTime, strText;
+		strText.Format(_T("%s > %s\n"), GetCurTime(strTime), pszMessage);
+		g_logFile.WriteString(strText);
+
+		// 文件超过50M,重新创建
+		if (g_logFile.GetLength() > 50 * 1024 * 1024) {
+			g_logFile.Close();
+
+			CString strFilepath;
+			strFilepath.Format(_T("%s\\%d_%02d_%02d_%02d_%02d_%02d.log"), g_strLogDir,
+				time.GetYear(), time.GetMonth(), time.GetDay(), time.GetHour(), time.GetMinute(), time.GetSecond());
+			if (g_logFile.Open(strFilepath, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite | CFile::shareDenyWrite)) {
+				g_logFile.SeekToEnd();
+			}
+		}
+	}
+}
+
+//
+// 初始化网络
+//
+extern "C" __declspec(dllexport) 
+int BEQ_Initialize()
+{
+	// 初始化网络
+	WSADATA wsaData;
+	WORD version = MAKEWORD(2, 2);
+	int ret = WSAStartup(version, &wsaData);
+	if (ret != 0) {
+		log(LERROR, "初始化网络失败。");
+		return -1;
+	}
+	log(LDEBUG, "初始化网络成功 。");
+
+
+	// 本程序文件目录
+	TCHAR sDrive[_MAX_DRIVE];
+	TCHAR sDir[_MAX_DIR];
+	TCHAR sFilename[_MAX_FNAME], sAppFilename[_MAX_FNAME];
+	TCHAR sExt[_MAX_EXT];
+	GetModuleFileName((HMODULE)&__ImageBase, sAppFilename, _MAX_FNAME);
+	_tsplitpath_s(sAppFilename, sDrive, sDir, sFilename, sExt);
+	g_strLogDir = CString(sDrive) + CString(sDir) + CString("\\BEQLog");
+	::CreateDirectory(g_strLogDir, NULL);
+
+	CTime time = CTime::GetCurrentTime();
+	CString strFilepath;
+	strFilepath.Format(_T("%s\\%d_%02d_%02d_%02d_%02d_%02d.log"), g_strLogDir,
+		time.GetYear(), time.GetMonth(), time.GetDay(), time.GetHour(), time.GetMinute(), time.GetSecond());
+	if (!g_logFile.Open(strFilepath, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite | CFile::shareDenyWrite)) {
+		return -2;
+	}
+	g_logFile.SeekToEnd();
+	log(0, "BEQ_Initialize 完成.");
+
+
+	return 0;
+}
+
+
+//
+// 终止并清理
+//
+extern "C" __declspec(dllexport) 
+int BEQ_Term()
+{
+	// 关闭和释放所有Servo, Equipment
+	for (auto itor : g_mapServos) {
+		BEQ::CServo *pServo = (BEQ::CServo *)itor.second;
+		pServo->close();
+		delete pServo;
+	}
+	g_mapServos.clear();
+
+	for (auto itor : g_mapEquipments) {
+		BEQ::CEquipment *pEquipment = (BEQ::CEquipment *)itor.second;
+		delete pEquipment;
+	}
+	g_mapEquipments.clear();
+
+	// 其它清理工作
+	WSACleanup();
+	log(LDEBUG, "BEQ_Initialize.");
+
+	if (g_logFile.m_hFile != CFile::hFileNull) {
+		g_logFile.Close();
+	}
+
+	return 0;
+}
+
+extern "C" __declspec(dllexport) 
+int BEQ_CreateServo(BEQ::IServo*& pServo, const char* pszName)
+{
+	// 检查是否已经存在
+	auto iter = g_mapServos.find(pszName);
+	if (iter != g_mapServos.end()) {
+		return -1;
+	}
+
+	// 不存在则创建新的
+	BEQ::CServo* pTemp = new BEQ::CServo(pszName);
+	pServo = pTemp;
+	g_mapServos[pszName] = pTemp;
+
+	return 0;
+}
+
+extern "C" __declspec(dllexport)
+int BEQ_GetServo(BEQ::IServo*& pServo, const char* pszName)
+{
+	// 检查是否已经存在
+	auto iter = g_mapServos.find(pszName);
+	if (iter == g_mapServos.end()) {
+		return -1;
+	}
+
+	pServo = (BEQ::IServo*)iter->second;
+	return 0;
+}
+
+extern "C" __declspec(dllexport)
+int BEQ_DestroyServo(BEQ::IServo* pServo)
+{
+	// 检查是否存在
+	BOOL bFound = FALSE;
+	for (auto iter = g_mapServos.begin(); iter != g_mapServos.end(); iter++) {
+		if (iter->second == pServo) {
+			delete iter->second;
+			g_mapServos.erase(iter);
+			bFound = TRUE;
+			break;
+		}
+	}
+
+	return bFound ? 0 : -1;
+}
+
+extern "C" __declspec(dllexport)
+int BEQ_CreateEquipment(BEQ::IEquipment*& pEquipment, const char* pszName)
+{
+	// 检查是否已经存在
+	auto iter = g_mapEquipments.find(pszName);
+	if (iter != g_mapEquipments.end()) {
+		return -1;
+	}
+
+	// 不存在则创建新的
+	BEQ::CEquipment* pTemp = new BEQ::CEquipment(pszName);
+	pEquipment = pTemp;
+	g_mapEquipments[pszName] = pTemp;
+
+	return 0;
+}
+
+extern "C" __declspec(dllexport)
+int BEQ_GetEquipment(BEQ::IEquipment*& pEquipment, const char* pszName)
+{
+	// 检查是否已经存在
+	auto iter = g_mapEquipments.find(pszName);
+	if (iter == g_mapEquipments.end()) {
+		return -1;
+	}
+
+	pEquipment = (BEQ::IEquipment*)iter->second;
+	return 0;
+}
+
+extern "C" __declspec(dllexport)
+int BEQ_DestroyEquipment(BEQ::IEquipment*& pEquipment)
+{
+	// 检查是否存在
+	BOOL bFound = FALSE;
+	for (auto iter = g_mapEquipments.begin(); iter != g_mapEquipments.end(); iter++) {
+		if (iter->second == pEquipment) {
+			delete iter->second;
+			g_mapEquipments.erase(iter);
+			bFound = TRUE;
+			break;
+		}
+	}
+
+	return bFound ? 0 : -1;
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQLibrary/Data.cpp b/SourceCode/Bond/BEQLibrary/Data.cpp
new file mode 100644
index 0000000..832c85a
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/Data.cpp
@@ -0,0 +1,49 @@
+#include "stdafx.h"
+#include "Data.h"
+
+
+namespace BEQ {
+	CData::CData()
+	{
+		m_pBuffer = nullptr;
+		m_nBufferSize = 0;
+		m_nDataLen = 0;
+	}
+
+	CData::CData(int nInitSize)
+	{
+		m_pBuffer = new char[nInitSize];
+		m_nBufferSize = nInitSize;
+		m_nDataLen = 0;
+	}
+
+	CData::~CData()
+	{
+		if (m_pBuffer != nullptr) {
+			delete[] m_pBuffer;
+		}
+	}
+
+	void CData::init(int nInitSize)
+	{
+		m_pBuffer = new char[nInitSize];
+		m_nBufferSize = nInitSize;
+		m_nDataLen = 0;
+	}
+
+	int CData::append(const char* pData, int len)
+	{
+		if (m_nDataLen + len > m_nBufferSize) {
+			return -1;
+		}
+
+		memcpy(&m_pBuffer[m_nDataLen], pData, len);
+		m_nDataLen += len;
+		return (int)m_nDataLen;
+	}
+
+	void CData::clear()
+	{
+		m_nDataLen = 0;
+	}
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQLibrary/Data.h b/SourceCode/Bond/BEQLibrary/Data.h
new file mode 100644
index 0000000..fb73031
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/Data.h
@@ -0,0 +1,22 @@
+#pragma once
+
+
+namespace BEQ {
+	class CData
+	{
+	public:
+		CData();
+		CData(int nInitSize);
+		~CData();
+
+	public:
+		void init(int nInitSize);
+		int append(const char* pData, int len);
+		void clear();
+
+	public:
+		char* m_pBuffer;
+		size_t m_nBufferSize;
+		size_t m_nDataLen;
+	};
+}
diff --git a/SourceCode/Bond/BEQLibrary/Equipment.cpp b/SourceCode/Bond/BEQLibrary/Equipment.cpp
new file mode 100644
index 0000000..144c390
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/Equipment.cpp
@@ -0,0 +1,935 @@
+#include "stdafx.h"
+#include "Equipment.h"
+#include "Data.h"
+#include "BEQCommon.h"
+
+
+#define DATA_INIT_LEN		1024 * 8
+
+
+namespace BEQ {
+	CEquipment::CEquipment()
+	{
+		m_pClientListener = nullptr;
+		m_strVersion = _T("1.0.1");
+		m_pActiveClient = nullptr;
+		m_listener.onConnected = nullptr;
+		m_listener.onDisconnected = nullptr;
+		m_listener.onRunRecipe = nullptr;
+		m_listener.onGetRecipeList = nullptr;
+		m_listener.onLoadReady = nullptr;
+		m_listener.onLoadComplete = nullptr;
+		m_listener.onUnloadComplete = nullptr;
+		m_pReqRecipeListClient = nullptr;
+		m_pReqRecipeListUnit = nullptr;
+	}
+
+	CEquipment::CEquipment(const char* pszName)
+	{
+		m_strName = pszName;
+		m_strVersion = _T("1.0.1");
+		m_pClientListener = nullptr;
+		m_pActiveClient = nullptr;
+		m_listener.onConnected = nullptr;
+		m_listener.onDisconnected = nullptr;
+		m_listener.onRunRecipe = nullptr;
+		m_listener.onGetRecipeList = nullptr;
+		m_listener.onLoadReady = nullptr;
+		m_listener.onLoadComplete = nullptr;
+		m_listener.onUnloadComplete = nullptr;
+		m_pReqRecipeListClient = nullptr;
+		m_pReqRecipeListUnit = nullptr;
+	}
+
+	CEquipment::~CEquipment()
+	{
+		for (auto iter = m_recycleClients.begin(); iter != m_recycleClients.end(); iter++) {
+			delete (CData*)((*iter)->m_pContext1);
+			delete *iter;
+		}
+		m_recycleClients.clear();
+
+		for (auto iter = m_clients.begin(); iter != m_clients.end(); iter++) {
+			delete (CData*)((*iter)->m_pContext1);
+			delete *iter;
+		}
+
+		for (auto iter = m_units.begin(); iter != m_units.end(); iter++) {
+			delete iter->second;
+		}
+		m_units.clear();
+
+		if (m_pClientListener != nullptr) {
+			delete m_pClientListener;
+			m_pClientListener = nullptr;
+		}
+
+		if (m_pServer != nullptr) {
+			m_pServer->Close();
+			delete m_pServer;
+			m_pServer = nullptr;
+		}
+	}
+
+	void CEquipment::setEquipmentListener(EquipmentListener listener)
+	{
+		m_listener.onConnected = listener.onConnected;
+		m_listener.onDisconnected = listener.onDisconnected;
+		m_listener.onRunRecipe = listener.onRunRecipe;
+		m_listener.onGetRecipeList = listener.onGetRecipeList;
+		m_listener.onLoadReady = listener.onLoadReady;	
+		m_listener.onLoadComplete = listener.onLoadComplete;
+		m_listener.onUnloadComplete = listener.onUnloadComplete;
+	}
+	
+	int CEquipment::getName(char* pszBuffer, int nMaxCount)
+	{
+		return strcpy_s(pszBuffer, nMaxCount, m_strName.c_str());
+	}
+
+	void CEquipment::setName(const char* pszName)
+	{
+		m_strName = pszName;
+	}
+
+	int CEquipment::getVersion(char* pszBuffer, int nMaxCount)
+	{
+		return strcpy_s(pszBuffer, nMaxCount, m_strName.c_str());
+	}
+
+	void CEquipment::setVersion(const char* pszVersion)
+	{
+		m_strVersion = pszVersion;
+	}
+
+	IUnit* CEquipment::addUnit(const char* pszName, int nDoorCount)
+	{
+		auto iter = m_units.find(pszName);
+		if (iter != m_units.end()) {
+			return (IUnit*)iter->second;
+		}
+
+		CUnit* pUnit = new CUnit(pszName);
+		m_units[pszName] = pUnit;
+		pUnit->setDoorCount(nDoorCount);
+
+		UnitListener listener;
+		listener.onStateChanged = [&](void* pUnit, EQ_STATE nStete) -> void {
+			if (m_pActiveClient != nullptr) {
+				repState(m_pActiveClient, (CUnit*)pUnit, AS_MC_STATE_REP);
+			}
+		};
+		listener.onDoorStateChanged = [&](void* pUnit, int stete) -> void {
+			if (m_pActiveClient != nullptr) {
+				repDoorState(m_pActiveClient, (CUnit*)pUnit, AS_GET_DOOR_REP);
+			}
+		};
+		listener.onAlarm = [&](void* pUnit, int code, int level, const char* pszText) -> void {
+			if (m_pActiveClient != nullptr) {
+				repAlarm(m_pActiveClient, (CUnit*)pUnit, AS_SEND_ERROR_REP);
+			}
+		};
+		listener.onRemoveAlarm = [&](void* pUnit, int code, int level, const char* pszText) -> void {
+			if (m_pActiveClient != nullptr) {
+				repAlarm(m_pActiveClient, (CUnit*)pUnit, AS_REMOVE_ERROR_REP);
+			}
+		};
+		listener.onStepChanged = [&](void* pUnit, STEP_STATE) -> void {
+			if (m_pActiveClient != nullptr) {
+				repStep(m_pActiveClient, (CUnit*)pUnit, AS_SEND_STEP_REP);
+			}
+		};
+		listener.onDataChanged = [&](void* pUnit, unsigned long long time) -> void {
+			if (m_pActiveClient != nullptr) {
+				repData(m_pActiveClient, (CUnit*)pUnit, AS_MC_INFO_REP);
+			}
+		};
+		listener.onReqLoad = [&](void* pUnit, int layer) -> void {
+			if (m_pActiveClient != nullptr) {
+				repLoad(m_pActiveClient, (CUnit*)pUnit, layer, AS_SEND_EVENT_REP);
+			}
+		};
+		listener.onReqUnload = [&](void* pUnit, int layer) -> void {
+			if (m_pActiveClient != nullptr) {
+				repUnload(m_pActiveClient, (CUnit*)pUnit, layer, AS_SEND_EVENT_REP);
+			}
+		};
+		pUnit->setListener(listener);
+
+		return (IUnit*)pUnit;
+	}
+
+	IUnit* CEquipment::getUnit(const char* pszName)
+	{
+		auto iter = m_units.find(pszName);
+		if (iter != m_units.end()) {
+			return (IUnit*)iter->second;
+		}
+
+
+		return nullptr;
+	}
+
+	int CEquipment::runOnClientMode(const char* pAddr, int port)
+	{
+		return 0;
+	}
+
+	int CEquipment::runOnServerMode(int port)
+	{
+		m_pClientListener = new AcceptClientListener;
+		m_pClientListener->onClose = [&](void* pClient) -> int {
+			if (m_listener.onDisconnected != nullptr) {
+				CAcceptClient* p = (CAcceptClient*)pClient;
+				CString strIp;
+				UINT port;
+				m_pActiveClient->GetPeerName(strIp, port);
+				m_listener.onDisconnected(this, (LPTSTR)(LPCTSTR)strIp, port);
+			}
+			removeClient((CAcceptClient*)pClient);
+			m_pActiveClient = nullptr;
+			return 0;
+		};
+		m_pClientListener->onRead = [&](void* pClient, const char* pData, int len) -> int {
+			return decode((CAcceptClient*)pClient, pData, len);
+		};
+
+		ServerListener listener;
+		listener.onAccept = [&](void* pServer, CAcceptClient* pClient) -> int {
+			addClient(pClient);
+			m_pActiveClient = pClient;
+			for (auto item : m_units) {
+				item.second->resetLoadState();
+			}
+			if (m_listener.onConnected != nullptr) {
+				CString strIp;
+				UINT port;
+				m_pActiveClient->GetPeerName(strIp, port);
+				m_listener.onConnected(this, (LPTSTR)(LPCTSTR)strIp, port);
+			}
+			return 0;
+		};
+		listener.onClose = [&](void* pServer) -> int {
+			return 0;
+		};
+
+		m_pServer = new CSocketServer(port, listener);
+		m_pServer->init();
+		return 0;
+	}
+
+	void CEquipment::addClient(CAcceptClient* pClient)
+	{
+		pClient->m_pContext1 = new CData(DATA_INIT_LEN);
+		m_clients.push_back(pClient);
+		pClient->setListener(*m_pClientListener);
+	}
+
+	void CEquipment::removeClient(CAcceptClient* pClient)
+	{
+		for (auto iter = m_clients.begin(); iter != m_clients.end(); iter++) {
+			if (*iter == pClient) {
+				m_recycleClients.push_back(*iter);
+				m_clients.erase(iter);
+				break;
+			}
+		}
+	}
+
+	int CEquipment::decode(CAcceptClient* pClient, const char* pData, int len)
+	{
+		// 增加数据到尾部
+		BEQ::CData* pClsData = (BEQ::CData*) (pClient->m_pContext1);
+		if (-1 == pClsData->append(pData, len)) {
+			return -1;
+		}
+
+
+		// 在未找到@符之前,所有的字母必须是 'A' ~ 'Z' 或 '_'
+		int nCmdEnd = -1;
+		BOOL bInvalid = false;
+		for (int i = 0; i < pClsData->m_nDataLen; i++) {
+			if ((char)'@' == pClsData->m_pBuffer[i]) {
+				nCmdEnd = i;
+				break;
+			}
+
+			if ( !(((char)'A' <= pClsData->m_pBuffer[i] && pClsData->m_pBuffer[i] <= (char)'Z')
+				|| (char)'_' == pClsData->m_pBuffer[i]) ) {
+				bInvalid = true;
+				break;
+			}
+		}
+
+		if (bInvalid) {
+			pClsData->clear();
+			return -1;
+		}
+
+		if (nCmdEnd <= 0) {
+			return -2;
+		}
+
+
+		// 查找终止符
+		int nPacketEnd = -1;
+		bInvalid = false;
+		for (int i = nCmdEnd; i < pClsData->m_nDataLen; i++) {
+			if ((char)'#' == pClsData->m_pBuffer[i]) {
+				nPacketEnd = i;
+				break;
+			}
+
+			if ( !((char)32 <= pClsData->m_pBuffer[i] && pClsData->m_pBuffer[i] <= (char)127) ) {
+				bInvalid = true;
+				break;
+			}
+		}
+
+		if (bInvalid) {
+			pClsData->clear();
+			return -3;
+		}
+
+		if (nPacketEnd <= nCmdEnd) {
+			return -4;
+		}
+
+
+		// 得到命令,消息体
+		// 消息体分解为参数列表
+		CString strCmd = CString(pClsData->m_pBuffer, nCmdEnd);
+		CString strBody = CString(&pClsData->m_pBuffer[nCmdEnd+1], nPacketEnd - nCmdEnd - 1);
+
+		int iParam = 0;
+		CString strParam;
+		std::map<std::string, std::string> params;
+		do {
+			if (!AfxExtractSubString(strParam, (LPCTSTR)strBody, iParam, '/')) break;
+			int n = strParam.Find("=");
+			if (n > 0) {
+				std::string strName = (LPTSTR)(LPCTSTR)strParam.Left(n);
+				std::string strValue = (LPTSTR)(LPCTSTR)strParam.Right(strParam.GetLength() - n - 1);
+				params[strName] = strValue;
+			}
+			iParam++;
+		} while (true);
+
+
+
+		// 处理消息后复位
+		int nRet = executeCommand(pClient, strCmd, params);
+		pClsData->clear();
+
+
+		return nRet;
+	}
+
+	int CEquipment::executeCommand(CAcceptClient* pClient, CString& strCmd, std::map<std::string, std::string>& params)
+	{
+		// 获取机器名
+		CString strResponse;
+		if (strCmd.Compare(CMD_GET_EQID_REQ) == 0) {
+			makeResponse(CMD_GET_EQID_REP, PARAM_EQID, m_strName.c_str(), strResponse);
+			pClient->Send((LPTSTR)(LPCTSTR)strResponse, strResponse.GetLength());
+			return ERR_NOERR;
+		}
+
+
+		// 以下命令需要验证机器ID,不一致不回复
+		auto iter = params.find(PARAM_EQID);
+		if (iter == params.end()) return -101;
+		if (iter->second.compare(m_strName) != 0) {
+			return ERR_MISMATCH;
+		}
+
+
+		// 获取程序版本
+		if (strCmd.Compare(CMD_GET_VERSION_REQ) == 0) {
+			makeResponseEx(CMD_GET_VERSION_REP, PARAM_VERSION, m_strVersion.c_str(), strResponse);
+			pClient->Send((LPTSTR)(LPCTSTR)strResponse, strResponse.GetLength());
+			return ERR_NOERR;
+		}
+		
+
+		// 取出参数中的单元,默认为0
+		CUnit* pUnit = nullptr;
+		std::string strUnit = "1";
+		auto iterUnit = params.find("UNIT");
+		if (iterUnit != params.end()) {
+			strUnit = iterUnit->second;
+		}
+		
+
+		// 获取机器状态
+		if (strCmd.Compare(CMD_GET_STATE_REQ) == 0) {
+			pUnit = checkUnitAndReply(strUnit, pClient, CMD_GET_STATE_REP);
+			if (pUnit == nullptr) {
+				return ERR_NO_UNIT;
+			}
+
+			repState(m_pActiveClient, (CUnit*)pUnit, CMD_GET_STATE_REP);
+			return ERR_NOERR;
+		}
+
+		// 获取安全门状态
+		if (strCmd.Compare(CMD_GET_DOOR_REQ) == 0) {
+			pUnit = checkUnitAndReply(strUnit, pClient, CMD_GET_DOOR_REP);
+			if (pUnit == nullptr) {
+				return ERR_NO_UNIT;
+			}
+
+			repDoorState(pClient, pUnit, CMD_GET_DOOR_REP);
+			return ERR_NOERR;
+		}
+		
+
+		// 获取当前告警信息
+		if (strCmd.Compare(CMD_GET_ERROR_REQ) == 0) {
+			pUnit = checkUnitAndReply(strUnit, pClient, CMD_GET_ERROR_REP);
+			if (pUnit == nullptr) {
+				return ERR_NO_UNIT;
+			}
+
+			repAlarm(pClient, pUnit, CMD_GET_ERROR_REP);
+			return ERR_NOERR;
+		}
+
+
+		// 获取当前制程
+		if (strCmd.Compare(CMD_GET_STEP_REQ) == 0) {
+			pUnit = checkUnitAndReply(strUnit, pClient, CMD_GET_STEP_REP);
+			if (pUnit == nullptr) {
+				return ERR_NO_UNIT;
+			}
+
+			repStep(pClient, pUnit, CMD_GET_STEP_REP);
+			return ERR_NOERR;
+		}
+		
+
+		// 获取数据
+		if (strCmd.Compare(CMD_GET_DATA_REQ) == 0) {
+			pUnit = checkUnitAndReply(strUnit, pClient, CMD_GET_DATA_REP);
+			if (pUnit == nullptr) {
+				return ERR_NO_UNIT;
+			}
+
+			repData(pClient, pUnit, CMD_GET_DATA_REP);
+			return ERR_NOERR;
+		}
+
+
+		// 获取配方列表
+		if (strCmd.Compare(CMD_GET_RECIPE_LIST_REQ) == 0) {
+			pUnit = checkUnitAndReply(strUnit, pClient, CMD_GET_RECIPE_LIST_REP);
+			if (pUnit == nullptr) {
+				return ERR_NO_UNIT;
+			}
+
+			repRecipeList(pClient, pUnit, CMD_GET_RECIPE_LIST_REP);
+			return ERR_NOERR;
+		}
+
+
+		// 执行配方
+		if (strCmd.Compare(CMD_RUN_RECIPE_REQ) == 0) {
+			pUnit = checkUnitAndReply(strUnit, pClient, CMD_RUN_RECIPE_REP);
+			if (pUnit == nullptr) {
+				return ERR_NO_UNIT;
+			}
+
+			auto iterId = params.find(PARAM_RECIPEID);
+			auto iterName = params.find(PARAM_RECIPENAME);
+			if (iterId == params.end() || iterName == params.end()) {
+				makeFailResponse(CMD_RUN_RECIPE_REP, strUnit.c_str(),
+					"缺少参数", strResponse);
+				pClient->Send((LPTSTR)(LPCTSTR)strResponse, strResponse.GetLength());
+				return ERR_PARAM_ERROE;
+			}
+
+			repRunRecipe(pClient, pUnit, atoi(iterId->second.c_str()), 
+				iterName->second.c_str(), CMD_RUN_RECIPE_REP);
+			return ERR_NOERR;
+		}
+
+
+		// 上料就绪
+		if (strCmd.Compare(CMD_LOAD_READY_REQ) == 0) {
+			int layer = 1;
+			pUnit = checkUnitAndReplyEx(strUnit, layer, pClient, CMD_LOAD_READY_REP);
+			if (pUnit == nullptr) {
+				return ERR_NO_UNIT;
+			}
+
+			auto iterMeterialId = params.find(PARAM_MATERIAL_ID);
+			if (iterMeterialId == params.end()) {
+				iterMeterialId = params.find(PARAM_MATERIEL_ID);
+			}
+
+			if (iterMeterialId == params.end()) {
+				makeFailResponse(CMD_LOAD_READY_REP, strUnit.c_str(),
+					"缺少参数\"MATERIAL_ID\"", strResponse);
+				pClient->Send((LPTSTR)(LPCTSTR)strResponse, strResponse.GetLength());
+				return ERR_PARAM_ERROE;
+			}
+
+			auto iterRecipeId = params.find(PARAM_RECIPEID);
+			if (iterRecipeId == params.end()) {
+				makeFailResponse(CMD_LOAD_READY_REP, strUnit.c_str(),
+					"缺少参数\"RECIPEID\"", strResponse);
+				pClient->Send((LPTSTR)(LPCTSTR)strResponse, strResponse.GetLength());
+				return ERR_PARAM_ERROE;
+			}
+
+			repLoadReady(pClient, pUnit, strUnit.c_str(), iterMeterialId->second.c_str(),
+				iterRecipeId->second.c_str(), CMD_LOAD_READY_REP);
+			return ERR_NOERR;
+		}
+
+
+		// 上料完成
+		if (strCmd.Compare(CMD_LOAD_COMPLETE_REQ) == 0) {
+			int layer = 1;
+			pUnit = checkUnitAndReplyEx(strUnit, layer, pClient, CMD_LOAD_COMPLETE_REP);
+			if (pUnit == nullptr) {
+				return ERR_NO_UNIT;
+			}
+
+			repLoadComplete(pClient, pUnit, strUnit.c_str(), layer, CMD_LOAD_COMPLETE_REP);
+			return ERR_NOERR;
+		}
+
+
+		// 下料完成
+		if (strCmd.Compare(CMD_UNLOAD_COMPLETE_REQ) == 0) {
+			int layer = 1;
+			pUnit = checkUnitAndReplyEx(strUnit, layer, pClient, CMD_UNLOAD_COMPLETE_REP);
+			if (pUnit == nullptr) {
+				return ERR_NO_UNIT;
+			}
+
+			repUnloadComplete(pClient, pUnit, strUnit.c_str(), layer, CMD_UNLOAD_COMPLETE_REP);
+			return ERR_NOERR;
+		}
+
+
+		return ERR_UNKNOWN_CMD;
+	}
+
+	const char* CEquipment::getReply(const char* pszReply)
+	{
+		if (strcmp(pszReply, CMD_GET_EQID_REQ) == 0) {
+			return CMD_GET_EQID_REP;
+		}
+
+		if (strcmp(pszReply, CMD_GET_VERSION_REQ) == 0) {
+			return CMD_GET_VERSION_REP;
+		}
+
+		if (strcmp(pszReply, CMD_GET_STATE_REQ) == 0) {
+			return CMD_GET_STATE_REP;
+		}
+
+		return "";
+	}
+
+	CUnit* CEquipment::checkUnitAndReply(std::string& strUnit, CAcceptClient* pClient, const char* pszReply)
+	{
+		auto iter = m_units.find(strUnit);
+		if (iter != m_units.end()) return iter->second;
+
+		CString strResponse;
+		makeFailResponse(pszReply, strUnit.c_str(),
+			"单元不存在", strResponse);
+		pClient->Send((LPTSTR)(LPCTSTR)strResponse, strResponse.GetLength());
+		return nullptr;
+	}
+
+	CUnit* CEquipment::checkUnitAndReplyEx(std::string& strUnit, int& layer, CAcceptClient* pClient, const char* pszReply)
+	{
+		// 查找到数字,取出层
+		std::string strUnit2, strLayer;
+		BOOL bLeft = TRUE;
+		for (int i = 0; i < strUnit.length(); i++) {
+			char c = strUnit.at(i);
+			if (0x30 <= c && c <= 0x39) {
+				bLeft = FALSE;
+			}
+			if (bLeft) strUnit2.push_back(c);
+			else strLayer.push_back(c);
+		}
+		
+
+		layer = strLayer.empty() ? 1 : atoi(strLayer.c_str());
+		auto iter = m_units.find(strUnit2);
+		if (iter != m_units.end()) return iter->second;
+
+		CString strResponse;
+		makeFailResponse(pszReply, strUnit.c_str(),
+			"单元不存在", strResponse);
+		pClient->Send((LPTSTR)(LPCTSTR)strResponse, strResponse.GetLength());
+		return nullptr;
+	}
+
+	void CEquipment::makeResponse(const char* pszReply, const char* pszParam, const char* pValue, CString& strResponse)
+	{
+		strResponse.Format(_T("%s@%s=%s#"), pszReply, pszParam, pValue);
+	}
+
+	void CEquipment::makeResponseEx(const char* pszReply, const char* pszParam, const char* pValue, CString& strResponse)
+	{
+		strResponse.Format(_T("%s@%s=%s/%s=%s#"), pszReply, PARAM_EQID, m_strName.c_str(), pszParam, pValue);
+	}
+
+	void CEquipment::makeResponseEx(const char* pszReply, const char* pszUnit, const char* pszParam, const char* pValue, CString& strResponse)
+	{
+		strResponse.Format(_T("%s@%s=%s/%s=%s/%s=%s#"), pszReply, PARAM_EQID, m_strName.c_str(),
+			PARAM_UNIT, pszUnit, pszParam, pValue);
+	}
+
+	void CEquipment::makeFailResponse(const char* pszReply, const char* pszUnit, const char* pszText, CString& strResponse)
+	{
+		strResponse.Format(_T("%s@%s=%s/%s=%s/RESULT=FAIL/TEXT=%s#"), pszReply, PARAM_EQID, m_strName.c_str(),
+			PARAM_UNIT, pszUnit, pszText);
+	}
+
+	void CEquipment::repState(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		CString strReply;
+		strReply.Format(_T("%s@%s=%s/%s=%s/%s=%s#"), pszReply, PARAM_EQID, m_strName.c_str(),
+			PARAM_UNIT, pUnit->getName().c_str(),
+			PARAM_STATE, pUnit->getStateText());
+		pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+	}
+
+	void CEquipment::repDoorState(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		std::string strDoorState;
+		CString strReply;
+		strReply.Format(_T("%s@%s=%s/%s=%s/%s=%s#"), pszReply, PARAM_EQID, m_strName.c_str(),
+			PARAM_UNIT, pUnit->getName().c_str(),
+			PARAM_DOOR, pUnit->getDoorState(strDoorState).c_str());
+		pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+	}
+
+	void CEquipment::repAlarm(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		CString strReply;
+		int code = pUnit->getAlarmCode();
+		if (code == 0) {
+			strReply.Format(_T("%s@%s=%s/%s=%s/%s=%d#"), pszReply, PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str(),
+				PARAM_CODE, pUnit->getAlarmCode());
+		}
+		else {
+			strReply.Format(_T("%s@%s=%s/%s=%s/%s=%d,%d,%s#"), pszReply, PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str(),
+				PARAM_CODE, pUnit->getAlarmCode(), pUnit->getAlarmLevel(), pUnit->getAlarmText().c_str());
+		}
+
+		pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+	}
+
+	void CEquipment::repStep(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		CString strReply;
+		STEP_STATE stepState = pUnit->getStepState();
+		if (stepState == STEP_STATE::IDLE) {
+			// idle只有状态
+			strReply.Format(_T("%s@%s=%s/%s=%s/%s=%s#"), pszReply, 
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str(),
+				PARAM_STEP, pUnit->getStepStateText());
+		}
+		else if (stepState == STEP_STATE::PROCESSING) {
+			// step, id, svtime, pvtime
+			strReply.Format(_T("%s@%s=%s/%s=%s/%s=%s/%s=%s/SVTIME=%d/PVTIME=%d#"), pszReply,
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str(),
+				PARAM_STEP, pUnit->getStepStateText(),
+				PARAM_MATERIAL_ID, pUnit->getStepMaterialId().c_str(),
+				pUnit->getStepSvTime(), pUnit->getSetpPvTime());
+		}
+		else {
+			// step, id
+			strReply.Format(_T("%s@%s=%s/%s=%s/%s=%s/%s=%s#"), pszReply,
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str(),
+				PARAM_STEP, pUnit->getStepStateText(), 
+				PARAM_MATERIAL_ID, pUnit->getStepMaterialId().c_str());
+		}
+
+		pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+	}
+
+	void CEquipment::repData(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		CString strReply;
+		unsigned long long time = pUnit->getDataTime();
+		if (time == 0) {
+			// 没有数据
+			strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=FAIL/TEX=NO DATA#"), pszReply,
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str());
+		}
+		else {
+			strReply.Format(_T("%s@%s=%s/%s=%s/%s=%s"), pszReply,
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str(),
+				PARAM_TIME, timeToString(pUnit->getDataTime()).c_str());
+			std::map<std::string, std::string>& datas = pUnit->getDatas();
+			for (auto& item : datas) {
+				strReply.AppendFormat("/%s=%s", item.first.c_str(),
+					item.second.c_str());
+			}
+			strReply.Append("#");
+		}
+
+		pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+	}
+
+	void CEquipment::repRecipeList(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		CString strReply;
+		if (m_listener.onGetRecipeList != nullptr) {
+			int nRet = m_listener.onGetRecipeList(this, pUnit);
+			if (nRet == 1) {
+				// 保存数据,等待上层完成
+				m_pReqRecipeListClient = pClient;
+				m_pReqRecipeListUnit = pUnit;
+				m_strReqRecipeListReply = pszReply;
+			}
+			else {
+				std::map<int, std::string>& recipes = pUnit->getRecipes();
+				if (recipes.empty()) {
+					// 没有配方
+					strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=FAIL/TEX=NO RECIPE#"), pszReply,
+						PARAM_EQID, m_strName.c_str(),
+						PARAM_UNIT, pUnit->getName().c_str());
+
+				}
+				else {
+					strReply.Format(_T("%s@%s=%s/%s=%s/RECIPE_LIST="), pszReply,
+						PARAM_EQID, m_strName.c_str(),
+						PARAM_UNIT, pUnit->getName().c_str());
+					for (auto& item : recipes) {
+						strReply.AppendFormat("%d,%s,", item.first, item.second.c_str());
+					}
+					strReply.SetAt(strReply.GetLength() - 1, '#');
+				}
+
+				pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+			}
+		}
+	}
+
+	int CEquipment::repRecipeListComplete()
+	{
+		if (m_pReqRecipeListClient == nullptr) return -1;
+		if (m_pReqRecipeListUnit == nullptr) return -1;
+
+		CString strReply;
+		std::map<int, std::string>& recipes = m_pReqRecipeListUnit->getRecipes();
+		if (recipes.empty()) {
+			// 没有配方
+			strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=FAIL/TEX=NO RECIPE#"), m_strReqRecipeListReply.c_str(),
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, m_pReqRecipeListUnit->getName().c_str());
+
+		}
+		else {
+			strReply.Format(_T("%s@%s=%s/%s=%s/RECIPE_LIST="), m_strReqRecipeListReply.c_str(),
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, m_pReqRecipeListUnit->getName().c_str());
+			for (auto& item : recipes) {
+				strReply.AppendFormat("%d,%s,", item.first, item.second.c_str());
+			}
+			strReply.SetAt(strReply.GetLength() - 1, '#');
+		}
+
+		m_pReqRecipeListClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+		return 0;
+	}
+
+	void CEquipment::repRunRecipe(CAcceptClient* pClient, CUnit* pUnit, int id, const char* pszName, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		CString strReply;
+		if (!pUnit->checkRecipe(id, pszName)) {
+			// 没有配方
+			strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=FAIL/TEX=RECIPE'S ID AND NAME DO NOT MATCH#"), pszReply,
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str());
+		}
+		else {
+			// 模拟切换配方
+			if (m_listener.onRunRecipe != nullptr) {
+				int ret = m_listener.onRunRecipe(this, pUnit, id);
+				if (ret >= 0) {
+					strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=PASS#"), pszReply,
+						PARAM_EQID, m_strName.c_str(),
+						PARAM_UNIT, pUnit->getName().c_str());
+				}
+				else {
+					strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=FAIL/TEX=ERROR%d#"), pszReply,
+						PARAM_EQID, m_strName.c_str(),
+						PARAM_UNIT, pUnit->getName().c_str(), ret);
+				}
+			}
+		}
+
+		pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+	}
+
+	void CEquipment::repLoadReady(CAcceptClient* pClient, CUnit* pUnit, const char* pszUnitName, const char* pszMaterielId, const char* pszRecipeId, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		CString strReply;
+		if (m_listener.onRunRecipe != nullptr) {
+			int ret = m_listener.onLoadReady(this, pUnit, pszMaterielId, pszRecipeId);
+			if (ret == 1) {
+				// 保存数据,等待上层完成
+				m_pRunRecipeClient = pClient;
+				m_pRunRecipeUnit = pUnit;
+				m_strRunRecipeReply = pszReply;
+			}
+			else if (ret >= 0) {
+				strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=PASS#"), pszReply,
+					PARAM_EQID, m_strName.c_str(),
+					PARAM_UNIT, pszUnitName);
+			}
+			else {
+				strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=FAIL/TEX=ERROR%d#"), pszReply,
+					PARAM_EQID, m_strName.c_str(),
+					PARAM_UNIT, pszUnitName, ret);
+			}
+		}
+
+		pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+	}
+
+	int CEquipment::repLoadReadyComplete(int errorCode)
+	{
+		if (m_pRunRecipeClient == nullptr) return -1;
+		if (m_pRunRecipeUnit == nullptr) return -1;
+
+		CString strReply;
+		if (errorCode == 0) {
+			strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=PASS#"), m_strRunRecipeReply.c_str(),
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, m_pRunRecipeUnit->getName().c_str());
+		}
+		else {
+			strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=FAIL/TEX=ERROR%d#"), m_strRunRecipeReply.c_str(),
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, m_pRunRecipeUnit->getName().c_str(), errorCode);
+		}
+
+		m_pRunRecipeClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+		return 0;
+	}
+
+	void CEquipment::repLoad(CAcceptClient* pClient, CUnit* pUnit, int layer, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		CString strReply;
+		if (pUnit->getLayerCount() == 1) {
+			strReply.Format(_T("%s@%s=%s/%s=%s/%s=%s#"), pszReply,
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str(),
+				PARAM_EVENT, EVENT_LOAD);
+		}
+		else {
+			strReply.Format(_T("%s@%s=%s/%s=%s%d/%s=%s#"), pszReply,
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str(), layer, 
+				PARAM_EVENT, EVENT_LOAD);
+		}
+
+
+		pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+	}
+
+	void CEquipment::repUnload(CAcceptClient* pClient, CUnit* pUnit, int layer, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		CString strReply;
+		if (pUnit->getLayerCount() == 1) {
+			strReply.Format(_T("%s@%s=%s/%s=%s/%s=%s#"), pszReply,
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str(),
+				PARAM_EVENT, EVENT_UNLOAD);
+		}
+		else {
+			strReply.Format(_T("%s@%s=%s/%s=%s%d/%s=%s#"), pszReply,
+				PARAM_EQID, m_strName.c_str(),
+				PARAM_UNIT, pUnit->getName().c_str(), layer,
+				PARAM_EVENT, EVENT_UNLOAD);
+		}
+
+
+		pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+	}
+
+	void CEquipment::repLoadComplete(CAcceptClient* pClient, CUnit* pUnit, const char* pszUnitName, int layer, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		CString strReply;
+		if (m_listener.onLoadComplete != nullptr) {
+			int ret = m_listener.onLoadComplete(this, pUnit, layer);
+			if (ret >= 0) {
+				strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=PASS#"), pszReply,
+					PARAM_EQID, m_strName.c_str(),
+					PARAM_UNIT, pszUnitName);
+			}
+			else {
+				strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=FAIL/TEX=ERROR%d#"), pszReply,
+					PARAM_EQID, m_strName.c_str(),
+					PARAM_UNIT, pszUnitName, ret);
+			}
+		}
+
+		pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+	}
+
+	void CEquipment::repUnloadComplete(CAcceptClient* pClient, CUnit* pUnit, const char* pszUnitName, int layer, const char* pszReply)
+	{
+		ASSERT(pClient != nullptr);
+		CString strReply;
+		if (m_listener.onUnloadComplete != nullptr) {
+			int ret = m_listener.onUnloadComplete(this, pUnit, layer);
+			if (ret >= 0) {
+				strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=PASS#"), pszReply,
+					PARAM_EQID, m_strName.c_str(),
+					PARAM_UNIT, pszUnitName);
+			}
+			else {
+				strReply.Format(_T("%s@%s=%s/%s=%s/RESULT=FAIL/TEX=ERROR%d#"), pszReply,
+					PARAM_EQID, m_strName.c_str(),
+					PARAM_UNIT, pszUnitName, ret);
+			}
+		}
+
+		pClient->Send((LPTSTR)(LPCTSTR)strReply, strReply.GetLength());
+	}
+
+	std::string CEquipment::timeToString(ULONGLONG time)
+	{
+		ULONGLONG time1;
+		time1 = time / 1000;
+
+		char buffer[256];
+		struct tm timeinfo;
+		time_t t = time_t(time1);
+		localtime_s(&timeinfo, &t);
+		strftime(buffer, 128, "%Y-%m-%d %H:%M:%S", &timeinfo);
+		return std::string(buffer);
+	}
+}
diff --git a/SourceCode/Bond/BEQLibrary/Equipment.h b/SourceCode/Bond/BEQLibrary/Equipment.h
new file mode 100644
index 0000000..09e9c95
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/Equipment.h
@@ -0,0 +1,82 @@
+#pragma once
+#include "IEquipment.h"
+#include <string>
+#include "SocketServer.h"
+#include <list>
+#include <map>
+#include "Unit.h"
+
+
+namespace BEQ {
+	class CEquipment : 
+		public IEquipment
+	{
+	public:
+		CEquipment();
+		CEquipment::CEquipment(const char* pszName);
+		~CEquipment();
+
+	public:
+		virtual void setEquipmentListener(EquipmentListener listener);
+		virtual int getName(char* pszBuffer, int nMaxCount);
+		virtual void setName(const char* pszName);
+		virtual int getVersion(char* pszBuffer, int nMaxCount);
+		virtual void setVersion(const char* pszVersion);
+		virtual IUnit* addUnit(const char* pszName, int nDoorCount);
+		virtual IUnit* getUnit(const char* pszName);
+		virtual int runOnClientMode(const char* pAddr, int port);
+		virtual int runOnServerMode(int port);
+		virtual int repRecipeListComplete();
+		virtual int repLoadReadyComplete(int errorCode);
+
+	private:
+		void addClient(CAcceptClient* pClient);
+		void removeClient(CAcceptClient* pClient);
+		int decode(CAcceptClient* pClient, const char* pData, int len);
+		int executeCommand(CAcceptClient* pClient, CString& strCmd, std::map<std::string, std::string>& params);
+		const char* getReply(const char* pszReply);
+		CUnit* checkUnitAndReply(std::string& strUnit, CAcceptClient* pClient, const char* pszReply);
+		CUnit* checkUnitAndReplyEx(std::string& strUnit, int& layer, CAcceptClient* pClient, const char* pszReply);
+		void makeResponse(const char* pszReply, const char* pszParam, const char* pValue, CString& strResponse);
+		void makeResponseEx(const char* pszReply, const char* pszParam, const char* pValue, CString& strResponse);
+		void makeResponseEx(const char* pszReply, const char* pszUnit, const char* pszParam, const char* pValue, CString& strResponse);
+		void makeFailResponse(const char* pszReply, const char* pszUnit, const char* pszText, CString& strResponse);
+		void repState(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply);
+		void repDoorState(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply);
+		void repAlarm(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply);
+		void repStep(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply);
+		void repData(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply);
+		void repRecipeList(CAcceptClient* pClient, CUnit* pUnit, const char* pszReply);
+		void repRunRecipe(CAcceptClient* pClient, CUnit* pUnit, int id, const char* pszName, const char* pszReply);
+		void repLoadReady(CAcceptClient* pClient, CUnit* pUnit, const char* pszUnitName, const char* pszMaterielId, const char* pszRecipeId, const char* pszReply);
+		void repLoad(CAcceptClient* pClient, CUnit* pUnit, int layer, const char* pszReply);
+		void repUnload(CAcceptClient* pClient, CUnit* pUnit, int layer, const char* pszReply);
+		void repLoadComplete(CAcceptClient* pClient, CUnit* pUnit, const char* pszUnitName, int layer, const char* pszReply);
+		void repUnloadComplete(CAcceptClient* pClient, CUnit* pUnit, const char* pszUnitName, int layer, const char* pszReply);
+
+	private:
+		std::string timeToString(ULONGLONG time);
+
+	private:
+		std::string m_strName;
+		std::string m_strVersion;
+		CSocketServer* m_pServer;
+		AcceptClientListener* m_pClientListener;
+		std::list<CAcceptClient*> m_clients;
+		std::list<CAcceptClient*> m_recycleClients;
+		CAcceptClient* m_pActiveClient;
+
+	private:
+		std::map<std::string, BEQ::CUnit*> m_units;
+		EquipmentListener m_listener;
+
+	private:
+		CAcceptClient* m_pReqRecipeListClient;
+		CUnit* m_pReqRecipeListUnit;
+		std::string m_strReqRecipeListReply;
+		CAcceptClient* m_pRunRecipeClient;
+		CUnit* m_pRunRecipeUnit;
+		std::string m_strRunRecipeReply;
+	};
+}
+
diff --git a/SourceCode/Bond/BEQLibrary/IEquipment.h b/SourceCode/Bond/BEQLibrary/IEquipment.h
new file mode 100644
index 0000000..b8063f0
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/IEquipment.h
@@ -0,0 +1,41 @@
+#pragma once
+#include "IUnit.h"
+#include <functional>
+
+
+namespace BEQ {
+	typedef std::function<void(void* pEiuipment, const char* pszAddr, int port)> ONCONNECTED;
+	typedef std::function<void(void* pEiuipment, const char* pszAddr, int port)> ONDISCONNECTED;
+	typedef std::function<int(void* pEiuipment, void* pUnit, int id)> ONRUNRECIPE;
+	typedef std::function<int(void* pEiuipment, void* pUnit)> ONGETRECIPELIST;
+	typedef std::function<int(void* pEiuipment, void* pUnit, const char* pszMaterielId, const char* pszRecipeId)> ONLOADREADY;
+	typedef std::function<int(void* pEiuipment, void* pUnit, int layer)> ONLOADCOMPLETE;
+
+	typedef struct _EquipmentListener
+	{
+		ONCONNECTED			onConnected;
+		ONDISCONNECTED		onDisconnected;
+		ONRUNRECIPE			onRunRecipe;
+		ONGETRECIPELIST		onGetRecipeList;
+		ONLOADREADY			onLoadReady;
+		ONLOADCOMPLETE		onLoadComplete;
+		ONLOADCOMPLETE		onUnloadComplete;
+	} EquipmentListener;
+
+	class IEquipment
+	{
+	public:
+		virtual void setEquipmentListener(EquipmentListener listener) = 0;
+		virtual int getName(char* pszBuffer, int nMaxCount) = 0;
+		virtual void setName(const char* pszName) = 0;
+		virtual int getVersion(char* pszBuffer, int nMaxCount) = 0;
+		virtual void setVersion(const char* pszVersion) = 0;
+		virtual IUnit* addUnit(const char* pszName, int nDoorCount) = 0;
+		virtual IUnit* getUnit(const char* pszName) = 0;
+		virtual int runOnClientMode(const char* pAddr, int port) = 0;
+		virtual int runOnServerMode(int port) = 0;
+		virtual int repRecipeListComplete() = 0;
+		virtual int repLoadReadyComplete(int errorCode) = 0;
+	};
+}
+
diff --git a/SourceCode/Bond/BEQLibrary/IRemoteEquipment.h b/SourceCode/Bond/BEQLibrary/IRemoteEquipment.h
new file mode 100644
index 0000000..6292bed
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/IRemoteEquipment.h
@@ -0,0 +1,35 @@
+#pragma once
+#include "IUnit.h"
+#include <functional>
+
+
+namespace BEQ {
+	enum class REMOTE_EQ_EVENT
+	{
+		UNKNOWN = 0,
+		DEVICE_STATUS_CHANGED,
+		DOOR_STATUS_CHANGED,
+		ALARM_INFO_CHANGED,
+		REMOVE_ALARM_INFO,
+		PRODUCTION_PROCESS_CHANGED,
+		SERSOR_DATA_CHANGED,
+		RECIPE_LIST_CHANGED,
+		LOAD_EVENT_CHANGED
+	};
+
+	class IRemoteEquipment
+	{
+	public:
+		virtual int getAddr(char* pszBuffer, int nMaxCount) = 0;
+		virtual int getPort() = 0;
+		virtual int getName(char* pszBuffer, int nMaxCount) = 0;
+		virtual int getVersion(char* pszBuffer, int nMaxCount) = 0;
+		virtual bool isConnected() = 0;
+		virtual int connect() = 0;
+		virtual IUnit* addUnit(const char* pszName, int nDoorCount) = 0;
+		virtual IUnit* getUnit(const char* pszName) = 0;
+		virtual const char** getAllUnitNames() = 0;
+		virtual int getUnitCount() const = 0;
+		virtual ULONGLONG getConnectTick() = 0;
+	};
+}
diff --git a/SourceCode/Bond/BEQLibrary/IServo.h b/SourceCode/Bond/BEQLibrary/IServo.h
new file mode 100644
index 0000000..1c3e07c
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/IServo.h
@@ -0,0 +1,30 @@
+#pragma once
+#include "IRemoteEquipment.h"
+
+
+namespace BEQ {
+	typedef std::function<void(void* pServo, void* pRemoteEiuipment)> ONREQCONNECTED;
+	typedef std::function<void(void* pServo, void* pRemoteEiuipment, int errorCode)> ONREQCONNECTFAILED;
+	typedef std::function<void(void* pServo, void* pRemoteEiuipment, const char* pszData, int len)> ONREQREAD;
+	typedef std::function<void(void* pServo, void* pRemoteEquipment, void* pUnit, REMOTE_EQ_EVENT eventCode)> ONREQEVENTUPDATE;
+
+	typedef struct _ServoListener
+	{
+		ONREQCONNECTED		onRemoteEqConnecting;
+		ONREQCONNECTED		onRemoteEqConnected;
+		ONREQCONNECTFAILED	onRemoteEqConnectFailed;
+		ONREQCONNECTED		onRemoteEqDisconnecting;
+		ONREQCONNECTED		onRemoteEqDisconnected;
+		ONREQREAD			onRemoteEqReadRawdata;
+		ONREQEVENTUPDATE	onRemoteEqEventUpdate;
+	} ServoListener;
+
+	class IServo
+	{
+	public:
+		virtual void setListener(BEQ::ServoListener listener) = 0;
+		virtual int getName(char* pszBuffer, int nMaxCount) = 0;
+		virtual int createRemoteEquipment(IRemoteEquipment*& pRemoteEquipment, const char* pszAddr, int port) = 0;
+		virtual int connectRemoteEquipment(IRemoteEquipment* pRemoteEquipment) = 0;
+	};
+}
diff --git a/SourceCode/Bond/BEQLibrary/IUnit.h b/SourceCode/Bond/BEQLibrary/IUnit.h
new file mode 100644
index 0000000..2a49a4e
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/IUnit.h
@@ -0,0 +1,56 @@
+#pragma once
+
+namespace BEQ {
+	enum class EQ_STATE
+	{
+		IDLE = 0,
+		RUN,
+		DOWN,
+		MAINTENANCE,
+		MCHG,
+		E_TIME
+	};
+
+	enum class STEP_STATE
+	{
+		IDLE = 0,
+		MATERIAL_RECEIVED,
+		MATERIAL_REMOVEED,
+		PROCESSING_STARTED,
+		PROCESSING,
+		PROCESSING_COMPLETED
+	};
+
+	class IUnit
+	{
+	public:
+		virtual int getName(char* pszBuffer, int nMaxCount) = 0;
+		virtual void setState(EQ_STATE state) = 0;
+		virtual EQ_STATE getState() = 0;
+		virtual void setDoorCount(int count) = 0;
+		virtual void setDoorState(int state) = 0;
+		virtual int  getDoorState() = 0;
+		virtual void setLayerCount(int count) = 0;
+		virtual int getLayerCount() = 0;
+		virtual void setIndex(int index) = 0;
+		virtual int getIndex() = 0;
+		virtual void setAlarm(int code, int level, const char* pszText) = 0;
+		virtual int getAlarmCode() = 0;
+		virtual int getAlarmLevel() = 0;
+		virtual void stepIdle() = 0;
+		virtual void stepMaterialReceived(const char* pszID) = 0;
+		virtual void stepMaterialRemoved(const char* pszID) = 0;
+		virtual void stepProcessingStarted(const char* pszID) = 0;
+		virtual void stepProcessing(const char* pszID, int nSvTime, int nTvTime) = 0;
+		virtual void stepProcessingCompleted(const char* pszID) = 0;
+		virtual STEP_STATE getStepState() = 0;
+		virtual void setDataTime(unsigned long long time) = 0;
+		virtual void setDataTimeAndResetData(unsigned long long time) = 0;
+		virtual unsigned long long getDataTime() = 0;
+		virtual void addData(const char* pszName, const char* pszDataText, bool bComplete) = 0;
+		virtual void addRecipe(int id, const char* pszName, bool bComplete) = 0;
+		virtual int reqLoad(int layer) = 0;
+		virtual int reqUnload(int layer) = 0;
+	};
+}
+
diff --git a/SourceCode/Bond/BEQLibrary/ReadMe.txt b/SourceCode/Bond/BEQLibrary/ReadMe.txt
new file mode 100644
index 0000000..5fd3690
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/ReadMe.txt
@@ -0,0 +1,45 @@
+锘�========================================================================
+    MICROSOFT 鍩虹绫诲簱 : BEQLibrary 椤圭洰姒傝堪
+========================================================================
+
+
+搴旂敤绋嬪簭鍚戝宸蹭负鎮ㄥ垱寤轰簡姝� BEQLibrary DLL銆傛 DLL 涓嶄粎婕旂ず Microsoft 鍩虹绫荤殑鍩烘湰浣跨敤鏂规硶锛岃繕鍙綔涓烘偍缂栧啓 DLL 鐨勮捣鐐广��
+
+鏈枃浠舵瑕佷粙缁嶇粍鎴� BEQLibrary DLL 鐨勬瘡涓枃浠剁殑鍐呭銆�
+
+BEQLibrary.vcxproj
+    杩欐槸浣跨敤搴旂敤绋嬪簭鍚戝鐢熸垚鐨� VC++ 椤圭洰鐨勪富椤圭洰鏂囦欢锛屽叾涓寘鍚敓鎴愯鏂囦欢鐨� Visual C++ 鐨勭増鏈俊鎭紝浠ュ強鏈夊叧浣跨敤搴旂敤绋嬪簭鍚戝閫夋嫨鐨勫钩鍙般�侀厤缃拰椤圭洰鍔熻兘鐨勪俊鎭��
+
+BEQLibrary.vcxproj.filters
+    杩欐槸浣跨敤鈥滃簲鐢ㄧ▼搴忓悜瀵尖�濈敓鎴愮殑 VC++ 椤圭洰绛涢�夊櫒鏂囦欢銆傚畠鍖呭惈鏈夊叧椤圭洰鏂囦欢涓庣瓫閫夊櫒涔嬮棿鐨勫叧鑱斾俊鎭�傚湪 IDE 涓紝閫氳繃杩欑鍏宠仈锛屽湪鐗瑰畾鑺傜偣涓嬩互鍒嗙粍褰㈠紡鏄剧ず鍏锋湁鐩镐技鎵╁睍鍚嶇殑鏂囦欢銆備緥濡傦紝鈥�.cpp鈥濇枃浠朵笌鈥滄簮鏂囦欢鈥濈瓫閫夊櫒鍏宠仈銆�
+
+BEQLibrary.h
+    杩欐槸 DLL 鐨勪富澶存枃浠躲�傚畠澹版槑浜� CBEQLibraryApp 绫汇��
+
+BEQLibrary.cpp
+    杩欐槸涓� DLL 婧愭枃浠躲�傚畠鍖呭惈 CBEQLibraryApp 绫汇��
+
+BEQLibrary.rc
+    杩欐槸绋嬪簭浣跨敤鐨勬墍鏈� Microsoft Windows 璧勬簮鐨勫垪琛ㄣ�傚畠鍖呮嫭 RES 瀛愮洰褰曚腑瀛樺偍鐨勫浘鏍囥�佷綅鍥惧拰鍏夋爣銆傛鏂囦欢鍙互鐩存帴鍦� Microsoft Visual C++ 涓繘琛岀紪杈戙��
+
+res\BEQLibrary.rc2
+    姝ゆ枃浠跺寘鍚笉鍦� Microsoft Visual C++ 涓繘琛岀紪杈戠殑璧勬簮銆傛偍搴旇灏嗕笉鍙敱璧勬簮缂栬緫鍣ㄧ紪杈戠殑鎵�鏈夎祫婧愭斁鍦ㄦ鏂囦欢涓��
+
+BEQLibrary.def
+    姝ゆ枃浠跺寘鍚湪 Microsoft Windows 涓繍琛屾墍蹇呴渶鐨� DLL 鐨勬湁鍏充俊鎭�傚畠瀹氫箟浜� DLL 鐨勫悕绉板拰璇存槑绛夊弬鏁帮紝鑰屼笖杩樹粠 DLL 瀵煎嚭鍑芥暟銆�
+
+/////////////////////////////////////////////////////////////////////////////
+鍏朵粬鏍囧噯鏂囦欢:
+
+StdAfx.h, StdAfx.cpp
+    杩欎簺鏂囦欢鐢ㄤ簬鐢熸垚鍚嶄负 BEQLibrary.pch 鐨勯缂栬瘧澶� (PCH) 鏂囦欢鍜屽悕涓� StdAfx.obj 鐨勯缂栬瘧绫诲瀷鏂囦欢銆�
+
+Resource.h
+    杩欐槸鏍囧噯澶存枃浠讹紝鍙敤浜庡畾涔夋柊鐨勮祫婧� ID銆侻icrosoft Visual C++ 灏嗚鍙栧苟鏇存柊姝ゆ枃浠躲��
+
+/////////////////////////////////////////////////////////////////////////////
+鍏朵粬娉ㄩ噴:
+
+搴旂敤绋嬪簭鍚戝浣跨敤鈥淭ODO:鈥濇潵鎸囩ず搴旀坊鍔犳垨鑷畾涔夌殑婧愪唬鐮侀儴鍒嗐��
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/SourceCode/Bond/BEQLibrary/RemoteEquipment.cpp b/SourceCode/Bond/BEQLibrary/RemoteEquipment.cpp
new file mode 100644
index 0000000..eba207d
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/RemoteEquipment.cpp
@@ -0,0 +1,1061 @@
+#include "stdafx.h"
+#include "RemoteEquipment.h"
+#include <Ws2tcpip.h>
+#include <map>
+#include <vector>
+#include <string>
+#include <unordered_map>
+#include "BEQCommon.h"
+
+
+/* 超时时间 */
+extern int g_nActionTimeout;
+
+namespace BEQ {
+
+/* socket 缓冲区大小 */
+#define BUFFER_SIZE			1024
+
+
+	CRemoteEquipment::CRemoteEquipment()
+	{
+		m_nPort = 0;
+		m_nLocalPort = 0;
+		m_listener.onConnected = nullptr;
+		m_listener.onConnectFailed = nullptr;
+		m_listener.onDisconnecting = nullptr;
+		m_listener.onDisconnected = nullptr;
+		m_listener.onRead = nullptr;
+		m_listener.onEventUpdate = nullptr;
+		m_hSocket = NULL;
+		m_remoteEqNetState = REMOTE_EQ_NET_STATE::DISCONNECTED;
+		m_bWorking = FALSE;
+		m_hWSAEvent = nullptr;
+		m_hEventClose = nullptr;
+		m_hEventWrite = nullptr;
+		m_hEventActions = nullptr;
+		m_hEventActionsThreadExit = nullptr;
+		m_hEventTimeoutCheckThreadExit = nullptr;
+		m_pCurrentAction = nullptr;
+		m_data.init(1024);
+		::InitializeCriticalSection(&m_cs);
+	}
+
+	CRemoteEquipment::CRemoteEquipment(const char* pszAddr, int port)
+	{
+		m_nPort = 0;
+		m_nLocalPort = 0;
+		m_listener.onConnecting = nullptr;
+		m_listener.onConnected = nullptr;
+		m_listener.onConnectFailed = nullptr;
+		m_listener.onDisconnecting = nullptr;
+		m_listener.onDisconnected = nullptr;
+		m_listener.onRead = nullptr;
+		m_listener.onEventUpdate = nullptr;
+		m_strAddr = pszAddr;
+		m_nPort = port;
+		m_hSocket = NULL;
+		m_remoteEqNetState = REMOTE_EQ_NET_STATE::DISCONNECTED;
+		m_bWorking = FALSE;
+		m_hWSAEvent = nullptr;
+		m_hEventClose = nullptr;
+		m_hEventWrite = nullptr;
+		m_hEventActions = nullptr;
+		m_hEventActionsThreadExit = nullptr;
+		m_hEventTimeoutCheckThreadExit = nullptr;
+		m_pCurrentAction = nullptr;
+		m_data.init(1024);
+		::InitializeCriticalSection(&m_cs);
+		m_ullConnectTick = 0;
+	}
+
+	CRemoteEquipment::~CRemoteEquipment()
+	{
+		close();
+
+		for (auto iter = m_units.begin(); iter != m_units.end(); iter++) {
+			delete iter->second;
+		}
+		m_units.clear();
+
+		::DeleteCriticalSection(&m_cs);
+	}
+
+	void CRemoteEquipment::setRemoteEquipmentListener(RemoteEquipmentListener listener)
+	{
+		m_listener.onConnecting = listener.onConnecting;
+		m_listener.onConnected = listener.onConnected;
+		m_listener.onConnectFailed = listener.onConnectFailed;
+		m_listener.onDisconnecting = listener.onDisconnecting;
+		m_listener.onDisconnected = listener.onDisconnected;
+		m_listener.onRead = listener.onRead;
+		m_listener.onEventUpdate = listener.onEventUpdate;
+	}
+
+	int CRemoteEquipment::getAddr(char* pszBuffer, int nMaxCount)
+	{
+		return strcpy_s(pszBuffer, nMaxCount, m_strAddr.c_str());
+	}
+
+	int CRemoteEquipment::getPort()
+	{
+		return m_nPort;
+	}
+
+	int CRemoteEquipment::getName(char* pszBuffer, int nMaxCount)
+	{
+		if (!m_strName.empty()) {
+			return strcpy_s(pszBuffer, nMaxCount, m_strName.c_str());
+		}
+		else {
+			return sprintf_s(pszBuffer, nMaxCount, "%s:%d", m_strAddr.c_str(), m_nPort);
+		}
+
+	}
+
+	int CRemoteEquipment::getVersion(char* pszBuffer, int nMaxCount)
+	{
+		return strcpy_s(pszBuffer, nMaxCount, m_strVersion.c_str());
+	}
+
+	bool CRemoteEquipment::isConnected()
+	{
+		return m_hSocket != NULL && m_remoteEqNetState == REMOTE_EQ_NET_STATE::CONNECTED;
+	}
+
+	int CRemoteEquipment::connect()
+	{
+		TRACE("%p, m_remoteEqNetState:%d\n", this, m_remoteEqNetState);
+		if (m_remoteEqNetState == REMOTE_EQ_NET_STATE::CONNECTING
+			|| m_remoteEqNetState == REMOTE_EQ_NET_STATE::CONNECTED
+			|| m_remoteEqNetState == REMOTE_EQ_NET_STATE::DISCONNECTING) {
+			return -1;
+		}
+		m_remoteEqNetState = REMOTE_EQ_NET_STATE::CONNECTING;
+		if (m_listener.onConnecting != nullptr) {
+			m_listener.onConnecting(this);
+		}
+
+
+		// 待原线程退了先
+		m_bWorking = FALSE;
+		WSASetEvent(m_hWSAEvent);
+		if (m_hEventActions != NULL) {
+			SetEvent(m_hEventActions);
+		}
+		if (m_hEventActionsThreadExit != NULL) {
+			::WaitForSingleObject(m_hEventActionsThreadExit, INFINITE);
+		}
+
+		if (m_hEventTimeoutCheckThreadExit != NULL) {
+			::WaitForSingleObject(m_hEventTimeoutCheckThreadExit, INFINITE);
+		}
+
+
+		//准备服务器的信息,这里需要指定服务器的地址
+		sockaddr_in addr;
+		struct in_addr dst;
+		if (InetPton(AF_INET, m_strAddr.c_str(), &dst) != 1) {
+			return -1;
+		}
+
+		addr.sin_family = AF_INET;
+		addr.sin_addr = dst;
+		addr.sin_port = htons(m_nPort);   //改变端口号的数据格式
+
+
+		// 如果原来打开这套接字先关闭
+		if (m_hSocket != NULL) {
+			closesocket(m_hSocket);
+			m_hSocket = NULL;
+		}
+
+
+		// 创建新的套接字
+		if (m_hSocket == NULL) {
+			m_hSocket = socket(AF_INET, SOCK_STREAM, 0);
+			ASSERT(m_hSocket != NULL);
+			initClient();
+		}
+
+		if (m_hEventClose == NULL) {
+			m_hEventClose = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+		}
+		ResetEvent(m_hEventClose);
+
+		if (m_hEventActions == NULL) {
+			m_hEventActions = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+		}
+		ResetEvent(m_hEventActions);
+
+		if (m_hEventActionsThreadExit == NULL) {
+			m_hEventActionsThreadExit = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+		}
+		ResetEvent(m_hEventActionsThreadExit);
+
+		if (m_hEventTimeoutCheckThreadExit == NULL) {
+			m_hEventTimeoutCheckThreadExit = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+		}
+		ResetEvent(m_hEventTimeoutCheckThreadExit);
+
+
+		// 主动连接服务器,该过程将等待一定时间
+		if (SOCKET_ERROR == ::connect(m_hSocket, (LPSOCKADDR)&addr, sizeof(addr))) {
+			if (WSAGetLastError() != WSAEWOULDBLOCK)
+				return -2;
+		}
+
+
+		return 0;
+	}
+
+	int CRemoteEquipment::close()
+	{
+		m_bWorking = FALSE;
+		WSASetEvent(m_hWSAEvent);
+		if (m_hEventActions != NULL) {
+			SetEvent(m_hEventActions);
+		}
+
+		lock();
+		if (m_hSocket != NULL) {
+			m_remoteEqNetState = REMOTE_EQ_NET_STATE::DISCONNECTING;
+			if (m_listener.onDisconnecting != nullptr) {
+				m_listener.onDisconnecting(this);
+			}
+
+			shutdown(m_hSocket, SD_BOTH);
+			closesocket(m_hSocket);
+			m_hSocket = NULL;
+			unlock();
+
+			if (m_hEventClose != NULL) {
+				::WaitForSingleObject(m_hEventClose, INFINITE);
+			}
+
+			if (m_hEventActionsThreadExit != NULL) {
+				::WaitForSingleObject(m_hEventActionsThreadExit, INFINITE);
+			}
+
+			if (m_hEventTimeoutCheckThreadExit != NULL) {
+				::WaitForSingleObject(m_hEventTimeoutCheckThreadExit, INFINITE);
+			}
+
+			m_remoteEqNetState = REMOTE_EQ_NET_STATE::DISCONNECTED;
+			if (m_listener.onDisconnected != nullptr) {
+				m_listener.onDisconnected(this);
+			}
+		}
+		else {
+			unlock();
+		}
+
+
+		return 0;
+	}
+
+	int CRemoteEquipment::reqGetAction(int type, const char* pszCommand, const char* pszUnitName, const char* pszParams)
+	{
+		std::string strRawText = std::string(pszCommand) + "@EQID=" + m_strName;
+
+		if (pszUnitName) {
+			strRawText += ("/UNIT=" + std::string(pszUnitName));
+		}
+		if (pszParams) {
+			strRawText += pszParams;
+		}
+		strRawText += "#";
+
+		CAction* pAction = new CAction(type);
+		ASSERT(pAction);
+		pAction->setRawString(strRawText.c_str());
+
+		lock();
+		m_actions.push_back(pAction);
+		unlock();
+
+		SetEvent(m_hEventActions);
+
+		return pAction->getId();
+	}
+
+	int CRemoteEquipment::reqGetName()
+	{
+		return reqGetAction(ACTION_GETNAME, CMD_GET_EQID_REQ);
+	}
+
+	int CRemoteEquipment::reqGetVersion()
+	{
+		return reqGetAction(ACTION_GETVERSION, CMD_GET_VERSION_REQ);
+	}
+
+	int CRemoteEquipment::reqGetState(const char* pszUnitName)
+	{
+		return reqGetAction(ACTION_GETDEVICESTATE, CMD_GET_STATE_REQ, pszUnitName);
+	}
+
+	int CRemoteEquipment::reqGetDoorState(const char* pszUnitName)
+	{
+		return reqGetAction(ACTION_GETDOORSTATE, CMD_GET_DOOR_REQ, pszUnitName);
+	}
+
+	int CRemoteEquipment::reqGetAlarmInfo(const char* pszUnitName)
+	{
+		return reqGetAction(ACTION_GETALARMINFO, CMD_GET_ERROR_REQ, pszUnitName);
+	}
+
+	int CRemoteEquipment::reqGetStep(const char* pszUnitName)
+	{
+		return reqGetAction(ACTION_GETSTEP, CMD_GET_STEP_REQ, pszUnitName);
+	}
+
+	int CRemoteEquipment::reqGetData(const char* pszUnitName)
+	{
+		return reqGetAction(ACTION_GETDATA, CMD_GET_DATA_REQ, pszUnitName);
+	}
+
+	int CRemoteEquipment::reqRecipeList(const char* pszUnitName)
+	{
+		return reqGetAction(ACTION_GETRECIPELIST, CMD_GET_RECIPE_LIST_REQ, pszUnitName);
+	}
+
+	int CRemoteEquipment::reqRunRecipe(const char* pszUnitName, int nRecipeId, const char* pszRecipeName)
+	{
+		std::string strParams = "/RECIPEID=" + std::to_string(nRecipeId) + "/RECIPENAME=" + pszRecipeName;
+		return reqGetAction(ACTION_RUNRECIPE, CMD_RUN_RECIPE_REQ, pszUnitName, strParams.c_str());
+	}
+
+	IUnit* CRemoteEquipment::addUnit(const char* pszName, int nDoorCount)
+	{
+		auto iter = m_units.find(pszName);
+		if (iter != m_units.end()) {
+			return (IUnit*)iter->second;
+		}
+
+		CUnit* pUnit = new CUnit(pszName);
+		m_units[pszName] = pUnit;
+		pUnit->setDoorCount(nDoorCount);
+
+		UnitListener listener;
+		listener.onStateChanged = [&](void* pUnit, EQ_STATE nStete) -> void {
+			TRACE("<UnitListener>onStateChanged...\n");
+		};
+		listener.onDoorStateChanged = [&](void* pUnit, int stete) -> void {
+			TRACE("<UnitListener>onDoorStateChanged...\n");
+		};
+		listener.onAlarm = [&](void* pUnit, int code, int level, const char* pszText) -> void {
+			TRACE("<UnitListener>onAlarm...\n");
+		};
+		listener.onRemoveAlarm = [&](void* pUnit, int code, int level, const char* pszText) -> void {
+			TRACE("<UnitListener>onRemoveAlarm...\n");
+		};
+		listener.onStepChanged = [&](void* pUnit, STEP_STATE) -> void {
+			TRACE("<UnitListener>onStepChanged...\n");
+		};
+		listener.onDataChanged = [&](void* pUnit, unsigned long long time) -> void {
+			TRACE("<UnitListener>onDataChanged...\n");
+		};
+		listener.onReqLoad = [&](void* pUnit, int layer) -> void {
+			TRACE("<UnitListener>onReqLoad...\n");
+		};
+		listener.onReqUnload = [&](void* pUnit, int layer) -> void {
+			TRACE("<UnitListener>onReqUnload...\n");
+		};
+		pUnit->setListener(listener);
+
+		return (IUnit*)pUnit;
+	}
+
+	IUnit* CRemoteEquipment::getUnit(const char* pszName)
+	{
+		auto iter = m_units.find(pszName);
+		if (iter != m_units.end()) {
+			return (IUnit*)iter->second;
+		}
+
+		return nullptr;
+	}
+
+	const char** CRemoteEquipment::getAllUnitNames()
+	{
+		const int maxUnits = 128;
+		static const char* unitNames[maxUnits];
+		int index = 0;
+
+		for (const auto& pair : m_units) {
+			if (index >= maxUnits) break;
+			unitNames[index++] = pair.first.c_str();
+		}
+
+		return unitNames;
+	}
+
+	int CRemoteEquipment::getUnitCount() const
+	{
+		return m_units.size();
+	}
+
+	ULONGLONG CRemoteEquipment::getConnectTick()
+	{
+		return m_ullConnectTick;
+	}
+
+	BOOL CRemoteEquipment::initClient()
+	{
+		// 如果指定了本地端口(port != 0), 则要绑定指定端口
+		// 绑定一个套接字到本机的地址
+		ASSERT(m_hSocket);
+
+		// ref https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
+		int reuse = 1;
+		setsockopt(m_hSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse));
+
+		if (m_nLocalPort != 0) {
+			sockaddr_in addr;
+			addr.sin_family = AF_INET;
+			addr.sin_addr.S_un.S_addr = INADDR_ANY;
+			addr.sin_port = htons(m_nLocalPort);
+			bind(m_hSocket, (LPSOCKADDR)&addr, sizeof(addr));
+		}
+
+
+		// 采用事件选择模型WSAEventSelect
+		m_hWSAEvent = WSACreateEvent();
+		WSAEventSelect(m_hSocket, m_hWSAEvent, FD_CONNECT | FD_READ | FD_CLOSE | FD_WRITE);
+		m_bWorking = TRUE;
+		CWinThread* pThread = AfxBeginThread(&CRemoteEquipment::WorkerThreadFunction, (LPVOID)this,
+			THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
+		if (pThread) {
+			pThread->ResumeThread();
+		}
+
+		pThread = AfxBeginThread(&CRemoteEquipment::TimeoutCheckThreadFunction, (LPVOID)this,
+			THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
+		if (pThread) {
+			pThread->ResumeThread();
+		}
+
+		pThread = AfxBeginThread(&CRemoteEquipment::ActionsThreadFunction, (LPVOID)this,
+			THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
+		if (pThread) {
+			pThread->ResumeThread();
+		}
+
+		return TRUE;
+	}
+
+	UINT CRemoteEquipment::WorkerThreadFunction(LPVOID lpvData)
+	{
+		CRemoteEquipment *pRemoteEquipment = (CRemoteEquipment *)lpvData;
+		return pRemoteEquipment->WorkerThreadFunctionInner();
+	}
+
+	UINT CRemoteEquipment::WorkerThreadFunctionInner()
+	{
+		int					nThreadID, ret, index;
+		WSANETWORKEVENTS	networkEvents;
+
+
+		Sleep(100);		// 必须等待,使CreateChann...返回
+		nThreadID = 0;
+		char szRecvBuffer[BUFFER_SIZE];
+
+
+		while (m_bWorking) {
+			// 检测socket是否有效
+			lock();
+			if (m_hSocket == NULL) {
+				unlock();
+				break;
+			}
+			unlock();
+
+
+			// 等待网络事件
+			ret = WSAWaitForMultipleEvents(1, &m_hWSAEvent, FALSE, 1000, FALSE);
+			if (ret == WSA_WAIT_FAILED || ret == WSA_WAIT_TIMEOUT) {
+				continue;
+			}
+
+			index = ret - WSA_WAIT_EVENT_0;
+			WSAEnumNetworkEvents(m_hSocket, m_hWSAEvent, &networkEvents);
+
+
+			// 有数据到达
+			if (networkEvents.lNetworkEvents & FD_READ) {
+				int nRet = recv(m_hSocket, (char*)&szRecvBuffer, BUFFER_SIZE, 0);
+				if (nRet != SOCKET_ERROR) {
+					// 解释数据
+					int nDecodeRet = decode((char*)&szRecvBuffer, nRet);
+					if (m_listener.onRead != nullptr) {
+						m_listener.onRead(this, szRecvBuffer, nRet);
+					}
+				}
+			}
+
+
+			// 链接关闭
+			if (networkEvents.lNetworkEvents & FD_CLOSE) {
+				TRACE("链接关闭<FD_CLOSE>\n");
+				m_remoteEqNetState = REMOTE_EQ_NET_STATE::DISCONNECTED;
+				if (m_listener.onDisconnected != nullptr) {
+					m_listener.onDisconnected(this);
+				}
+				break;
+			}
+
+
+			// 链接结果
+			if (networkEvents.lNetworkEvents & FD_CONNECT) {
+				TRACE("链接结果<FD_CONNECT>\n");
+				m_ullConnectTick = GetTickCount64();
+				ResetEvent(m_hEventClose);
+
+				if (networkEvents.iErrorCode[FD_CONNECT_BIT] == 0) {
+					reqGetName();
+				}
+				else {
+					m_remoteEqNetState = REMOTE_EQ_NET_STATE::DISCONNECTED;
+					if (m_listener.onConnectFailed != nullptr) {
+						m_listener.onConnectFailed(this, networkEvents.iErrorCode[FD_CONNECT_BIT]);
+					}
+					m_bWorking = false;
+					break;
+				}
+			}
+
+			if (networkEvents.lNetworkEvents & FD_WRITE) {
+				if (m_hEventWrite != NULL) {
+					SetEvent(m_hEventWrite);
+				}
+			}
+		}
+
+
+		// 使m_hEventClose 受信, Close函数返回
+		if (m_hEventClose != NULL) {
+			TRACE("m_hEventClose 受信\n");
+			::SetEvent(m_hEventClose);
+		}
+
+
+		return 0;
+	}
+
+	UINT CRemoteEquipment::ActionsThreadFunction(LPVOID lpvData)
+	{
+		CRemoteEquipment *pRemoteEquipment = (CRemoteEquipment *)lpvData;
+		return pRemoteEquipment->ActionsThreadFunctionInner();
+	}
+
+	UINT CRemoteEquipment::ActionsThreadFunctionInner()
+	{
+		ULONGLONG lastTick = 0;
+		DWORD dwWait = INFINITE;
+		while (m_bWorking) {
+
+			DWORD dwRet = WaitForSingleObject(m_hEventActions, dwWait);
+			ResetEvent(m_hEventActions);
+			if (!m_bWorking) {
+				break;
+			}
+
+			lock();
+			if (m_pCurrentAction == NULL && m_actions.size() > 0) {
+				CAction* pAction = m_actions.front();
+
+				m_pCurrentAction = pAction;
+				m_actions.pop_front();
+
+				// 发送数据
+				char* pRawData = NULL;
+				int size, validLen;
+				m_pCurrentAction->getRawData(pRawData, size, validLen);
+				send(m_hSocket, pRawData, validLen, 0);
+			}
+			unlock();
+		}
+
+
+		TRACE("ActionsThreadFunctionInner exit\n");
+		SetEvent(m_hEventActionsThreadExit);
+
+		return 0;
+	}
+
+	UINT CRemoteEquipment::TimeoutCheckThreadFunction(LPVOID lpvData)
+	{
+		CRemoteEquipment *pRemoteEquipment = (CRemoteEquipment *)lpvData;
+		return pRemoteEquipment->TimeoutCheckThreadFunctionInner();
+	}
+
+	UINT CRemoteEquipment::TimeoutCheckThreadFunctionInner()
+	{
+		BOOL bMatchRemoteEq = TRUE;
+		while (m_bWorking) {
+			Sleep(1000);
+			if (!m_bWorking) {
+				break;
+			}
+
+			lock();
+			if (m_pCurrentAction != NULL) {
+				int nTime = m_pCurrentAction->timeIncrease(1000);
+				if (nTime > g_nActionTimeout) {
+					CurrentActionTimeout();
+					if (m_pCurrentAction->getType() == ACTION_GETNAME) {
+						bMatchRemoteEq = FALSE;
+					}
+
+					delete m_pCurrentAction;
+					m_pCurrentAction = NULL;
+					SetEvent(m_hEventActions);
+
+					if (!bMatchRemoteEq) {
+						unlock();
+						break;
+					}
+				}
+			}
+			unlock();
+		}
+
+
+		SetEvent(m_hEventTimeoutCheckThreadExit);
+		if (!bMatchRemoteEq) {
+			this->close();
+			if (m_listener.onConnectFailed != nullptr) {
+				m_listener.onConnectFailed(this, -1);
+			}
+		}
+		TRACE("TimeoutCheckThreadFunctionInner exit\n");
+		return 0;
+	}
+
+	void CRemoteEquipment::CurrentActionTimeout()
+	{
+		TRACE("Packer CurrentActionTimeout %d", g_nActionTimeout);
+	}
+
+	void CRemoteEquipment::splitCString(const CString& strText, TCHAR delimiter, std::function<void(const CString&, int)> callback)
+	{
+		// 通用字符串切割函数,支持回调函数处理每次解析后的结果
+		CString strGet;
+		int index = 0;
+
+		while (AfxExtractSubString(strGet, strText.GetString(), index, delimiter)) {
+			// 如果提供了回调函数,则执行回调,传递当前的字符串和索引
+			if (callback) {
+				callback(strGet, index);
+			}
+			++index;
+		}
+	}
+
+	void CRemoteEquipment::notifyEventUpdate(REMOTE_EQ_EVENT eventCode, CUnit* pUnit)
+	{
+		if (m_listener.onEventUpdate != nullptr) {
+			m_listener.onEventUpdate(this, pUnit, eventCode);
+		}
+	}
+
+	void CRemoteEquipment::processDoorState(const CString& strPart, int index, int& doorState)
+	{
+		if (strPart.CompareNoCase(_T("OPEN")) == 0) {
+			doorState |= (0x01 << index);
+		}
+	}
+
+	void CRemoteEquipment::updateDoorState(const CString& strText, int& doorState, CUnit* pUnit)
+	{
+		// 捕获this指针,使得Lambda可以访问类的成员函数或变量
+		splitCString(strText, ',', [this, &doorState](const CString& part, int index) {
+			processDoorState(part, index, doorState);
+		});
+
+		pUnit->setDoorState(doorState);
+	}
+
+	void CRemoteEquipment::parseAlarm(const CString& strText, CUnit* pUnit)
+	{
+		int alarmCode = -1;
+		int alarmLevel = -1;
+		CString alarmMessage;
+
+		if (0 == _ttoi(strText))
+		{
+			pUnit->setAlarm(0, 0, "");
+			return;
+		}
+
+		splitCString(strText, ',', [&alarmCode, &alarmLevel, &alarmMessage](const CString& part, int index) {
+			// 根据当前索引处理不同的报警信息
+			switch (index) {
+			case 0: // 报警代码
+				alarmCode = _ttoi(part);
+				break;
+			case 1: // 报警级别
+				alarmLevel = _ttoi(part);
+				break;
+			case 2: // 报警消息
+				alarmMessage = part;
+				break;
+			default:
+				break;
+			}
+		});
+
+		// 确保解析到3个子字符串,并设置报警信息
+		if (alarmCode != -1 && alarmLevel != -1 && !alarmMessage.IsEmpty()) {
+			pUnit->setAlarm(alarmCode, alarmLevel, alarmMessage.GetString());
+		}
+	}
+
+	void CRemoteEquipment::handleState(const std::map<std::string, std::string>& params, CUnit* pUnit)
+	{
+		auto iter = params.find(PARAM_STATE);
+		if (iter != params.end()) {
+			std::string strState(iter->second);
+			pUnit->setStateFromString(strState);
+			notifyEventUpdate(REMOTE_EQ_EVENT::DEVICE_STATUS_CHANGED, pUnit);
+		}
+	}
+
+	void CRemoteEquipment::handleDoorState(const std::map<std::string, std::string>& params, CUnit* pUnit)
+	{
+		auto iter = params.find(PARAM_DOOR);
+		if (iter != params.end()) {
+			CString strText = iter->second.c_str();
+			int doorState = 0;
+			updateDoorState(strText, doorState, pUnit);
+			notifyEventUpdate(REMOTE_EQ_EVENT::DOOR_STATUS_CHANGED, pUnit);
+		}
+	}
+
+	void CRemoteEquipment::handleAlarmInfo(const std::map<std::string, std::string>& params, CUnit* pUnit)
+	{
+		auto iter = params.find(PARAM_CODE);
+		if (iter != params.end()) {
+			CString strText = iter->second.c_str();
+			parseAlarm(strText, pUnit);
+			notifyEventUpdate(REMOTE_EQ_EVENT::ALARM_INFO_CHANGED, pUnit);
+		}
+	}
+
+	void CRemoteEquipment::handleStep(const std::map<std::string, std::string>& params, CUnit* pUnit)
+	{
+		auto materialIter = params.find(PARAM_MATERIAL_ID);
+		auto stepIter = params.find(PARAM_STEP);
+		if (stepIter != params.end()) {
+			auto pvIter = params.find(PARAM_PVTIME);
+			auto svIter = params.find(PARAM_SVTIME);
+			const std::string& strStep = stepIter->second;
+			const std::string& strMaterialId = materialIter != params.end() ? materialIter->second : "";
+			int iSVTime = svIter != params.end() ? _ttoi(svIter->second.c_str()) : 0;
+			int iPVTime = pvIter != params.end() ? _ttoi(pvIter->second.c_str()) : 0;
+
+			handleMachineProcess(strMaterialId, strStep, pUnit, iSVTime, iPVTime);
+			notifyEventUpdate(REMOTE_EQ_EVENT::PRODUCTION_PROCESS_CHANGED, pUnit);
+		}
+	}
+
+	void CRemoteEquipment::handleData(const std::map<std::string, std::string>& params, CUnit* pUnit)
+	{
+		auto retIter = params.find(PARAM_RESULT);
+		auto texIter = params.find(PARAM_TEX);
+		if ((retIter != params.end() && retIter->second.compare("FAIL")) || (texIter != params.end() && texIter->second.compare("NO DATA")))
+		{
+			// 获取数据失败或没有数据,不做处理
+		}
+		else {
+			auto preIter = params.find(PARAM_PRE);
+			auto airIter = params.find(PARAM_AIR);
+			auto tmpIter = params.find(PARAM_TMP);
+			auto timeIter = params.find(PARAM_TIME);
+			if (timeIter != params.end() && preIter != params.end() && airIter != params.end() && tmpIter != params.end()) {
+				uint64_t timestamp = pUnit->stringToTimeStamp(timeIter->second);
+				pUnit->setDataTimeAndResetData(timestamp);
+				pUnit->addData("PRE", preIter->second.c_str(), true);
+				pUnit->addData("AIR", airIter->second.c_str(), true);
+				pUnit->addData("TMP", tmpIter->second.c_str(), true);
+
+				notifyEventUpdate(REMOTE_EQ_EVENT::SERSOR_DATA_CHANGED, pUnit);
+			}
+		}
+	}
+
+	void CRemoteEquipment::handleRecipeList(const std::map<std::string, std::string>& params, CUnit* pUnit)
+	{
+		auto retIter = params.find(PARAM_RESULT);
+		auto texIter = params.find(PARAM_TEX);
+		if ((retIter != params.end() && retIter->second.compare("FAIL")) || (texIter != params.end() && texIter->second.compare("NO RECIPE"))) {
+			// 获取配方失败或没有配方,不做处理
+		}
+		else {
+			auto recipeIter = params.find(PARAM_RECIPE_LIST);
+			if (recipeIter != params.end()) {
+				// 解析配方列表
+				CString strRecipeList = recipeIter->second.c_str();
+				splitCString(strRecipeList, ',', [pUnit](const CString& part, int index) {
+					static int iRecipeid = -1;
+					if ((index + 1) % 2 == 0) {
+						pUnit->addRecipe(iRecipeid, part, true);
+					}
+					else {
+						iRecipeid = _ttoi(part);
+					}
+					});
+
+				notifyEventUpdate(REMOTE_EQ_EVENT::RECIPE_LIST_CHANGED, pUnit);
+			}
+		}
+	}
+
+	void CRemoteEquipment::handleIdle(CUnit* pUnit)
+	{
+		pUnit->stepIdle();
+	}
+
+	void CRemoteEquipment::handleMaterialReceived(const std::string& strMaterialId, CUnit* pUnit)
+	{
+		pUnit->stepMaterialReceived(strMaterialId.c_str());
+	}
+
+	void CRemoteEquipment::handleMaterialRemoved(const std::string& strMaterialId, CUnit* pUnit)
+	{
+		pUnit->stepMaterialRemoved(strMaterialId.c_str());
+	}
+
+	void CRemoteEquipment::handleProcessingStarted(const std::string& strMaterialId, CUnit* pUnit)
+	{
+		pUnit->stepProcessingStarted(strMaterialId.c_str());
+	}
+
+	void CRemoteEquipment::handleProcessing(const std::string& strMaterialId, CUnit* pUnit, int svTime, int pvTime)
+	{
+		pUnit->stepProcessing(strMaterialId.c_str(), svTime, pvTime);
+	}
+
+	void CRemoteEquipment::handleProcessingCompleted(const std::string& strMaterialId, CUnit* pUnit)
+	{
+		pUnit->stepProcessingCompleted(strMaterialId.c_str());
+	}
+
+	void CRemoteEquipment::handleMachineProcess(const std::string& strMaterialId, const std::string& strStep, CUnit* pUnit, int svTime, int pvTime)
+	{
+		// 映射步骤到处理函数
+		static const std::unordered_map<std::string, std::function<void(const std::string&, CUnit*, int, int)>> stepHandlers = {
+			{"IDLE", [this](const std::string&, CUnit* pUnit, int, int) { handleIdle(pUnit); }},
+			{"MATERIAL_RECEIVED", [this](const std::string& strMaterialId, CUnit* pUnit, int, int) { handleMaterialReceived(strMaterialId, pUnit); }},
+			{"MATERIAL_REMOVED", [this](const std::string& strMaterialId, CUnit* pUnit, int, int) { handleMaterialRemoved(strMaterialId, pUnit); }},
+			{"PROCESSING_STARTED", [this](const std::string& strMaterialId, CUnit* pUnit, int, int) { handleProcessingStarted(strMaterialId, pUnit); }},
+			{"PROCESSING_COMPLETED", [this](const std::string& strMaterialId, CUnit* pUnit, int, int) { handleProcessingCompleted(strMaterialId, pUnit); }},
+			{"PROCESSING", [this](const std::string& strMaterialId, CUnit* pUnit, int svTime, int pvTime) {
+				handleProcessing(strMaterialId, pUnit, svTime, pvTime);
+			}}
+		};
+
+		// 查找处理函数并执行
+		auto handler = stepHandlers.find(strStep);
+		if (handler != stepHandlers.end()) {
+			handler->second(strMaterialId, pUnit, svTime, pvTime); // 传递 svTime 和 pvTime
+		}
+	}
+
+	int CRemoteEquipment::decode(char* pszBuffer, int nBufferSize)
+	{
+		std::string txt = std::string(pszBuffer, nBufferSize);
+		TRACE("decode:%s\n", txt.c_str());
+		int nRet = REPLY_NOERROR;
+		int iParam = 0;
+		CString strParam, strCmd, strBody;
+		std::map<std::string, std::string> params;
+
+
+		lock();
+		if (-1 == m_data.append(pszBuffer, nBufferSize)) {
+			nRet = REPLY_MEMROY_ERROR;
+			goto CURACTION;
+		}
+
+		// 在未找到@符之前,所有的字母必须是 'A' ~ 'Z' 或 '_'
+		int nCmdEnd = -1;
+		BOOL bInvalid = false;
+		for (int i = 0; i < m_data.m_nDataLen; i++) {
+			if ((char)'@' == m_data.m_pBuffer[i]) {
+				nCmdEnd = i;
+				break;
+			}
+
+			if (!(((char)'A' <= m_data.m_pBuffer[i] && m_data.m_pBuffer[i] <= (char)'Z')
+				|| (char)'_' == m_data.m_pBuffer[i])) {
+				bInvalid = true;
+				break;
+			}
+		}
+
+		if (bInvalid) {
+			m_data.clear();
+			nRet = REPLY_PACKET_ERROR;
+			goto CURACTION;
+		}
+
+		if (nCmdEnd <= 0) {
+			nRet = REPLY_PACKET_ERROR;
+			goto CURACTION;
+		}
+
+
+		// 查找终止符
+		int nPacketEnd = -1;
+		bInvalid = false;
+		for (int i = nCmdEnd; i < m_data.m_nDataLen; i++) {
+			if ((char)'#' == m_data.m_pBuffer[i]) {
+				nPacketEnd = i;
+				break;
+			}
+
+			/*
+			if (!((char)32 <= m_data.m_pBuffer[i] && m_data.m_pBuffer[i] <= (char)127)) {
+				bInvalid = true;
+				break;
+			}
+			*/
+		}
+
+		if (bInvalid) {
+			m_data.clear();
+			nRet = REPLY_PACKET_ERROR;
+			goto CURACTION;
+		}
+
+		if (nPacketEnd <= nCmdEnd) {
+			nRet = REPLY_PACKET_NOT_END;
+			goto CURACTION;
+		}
+
+
+		// 得到命令,消息体
+		// 消息体分解为参数列表
+		strCmd = CString(m_data.m_pBuffer, nCmdEnd);
+		strBody = CString(&m_data.m_pBuffer[nCmdEnd + 1], nPacketEnd - nCmdEnd - 1);
+		do {
+			if (!AfxExtractSubString(strParam, (LPCTSTR)strBody, iParam, '/')) break;
+			int n = strParam.Find("=");
+			if (n > 0) {
+				std::string strName = (LPTSTR)(LPCTSTR)strParam.Left(n);
+				std::string strValue = (LPTSTR)(LPCTSTR)strParam.Right(strParam.GetLength() - n - 1);
+				params[strName] = strValue;
+			}
+			iParam++;
+		} while (true);
+
+
+	CURACTION:
+		m_data.clear();
+
+		// 获取设备单元指针
+		CUnit* pUnit = nullptr;
+		auto unitParamIter = params.find(PARAM_UNIT);
+		if (unitParamIter != params.end()) {
+			auto unitMapIter = m_units.find(unitParamIter->second);
+			if (unitMapIter != m_units.end() && unitMapIter->second != nullptr) {
+				pUnit = unitMapIter->second;
+			}
+		}
+
+		if (m_pCurrentAction != NULL) {
+			m_pCurrentAction->setReplyCode(nRet);
+			if (m_pCurrentAction->getType() == ACTION_GETNAME
+				&& strCmd.Compare(CMD_GET_EQID_REP) == 0) {
+				auto iter = params.find(PARAM_EQID);
+				if (iter != params.end()) {
+					m_strName = iter->second;
+					m_remoteEqNetState = REMOTE_EQ_NET_STATE::CONNECTED;
+					if (m_listener.onConnected != nullptr) {
+						m_listener.onConnected(this);
+					}
+
+					// test
+					reqGetVersion();
+					reqGetState("UNITA");
+					reqGetDoorState("UNITA");
+				}
+			}
+			else if (m_pCurrentAction->getType() == ACTION_GETVERSION && strCmd.Compare(CMD_GET_VERSION_REP) == 0) {
+				auto iter = params.find(PARAM_VERSION);
+				if (iter != params.end()) {
+					m_strVersion = iter->second;
+				}
+			}
+			else if (m_pCurrentAction->getType() == ACTION_GETDEVICESTATE && strCmd.Compare(CMD_GET_STATE_REP) == 0 && pUnit != nullptr) {
+				handleState(params, pUnit);
+			}
+			else if (m_pCurrentAction->getType() == ACTION_GETDOORSTATE && strCmd.Compare(CMD_GET_DOOR_REP) == 0 && pUnit != nullptr) {
+				handleDoorState(params, pUnit);
+			}
+			else if (m_pCurrentAction->getType() == ACTION_GETALARMINFO && strCmd.Compare(CMD_GET_ERROR_REP) == 0 && pUnit != nullptr) {
+				handleAlarmInfo(params, pUnit);
+			}
+			else if (m_pCurrentAction->getType() == ACTION_GETSTEP && strCmd.Compare(CMD_GET_STEP_REP) == 0 && pUnit != nullptr) {
+				handleStep(params, pUnit);
+			}
+			else if (m_pCurrentAction->getType() == ACTION_GETDATA && strCmd.Compare(CMD_GET_DATA_REP) == 0 && pUnit != nullptr) {
+				handleData(params, pUnit);
+			}
+			else if (m_pCurrentAction->getType() == ACTION_GETRECIPELIST && strCmd.Compare(CMD_GET_RECIPE_LIST_REP) == 0 && pUnit != nullptr) {
+				handleRecipeList(params, pUnit);
+			}
+			else if (m_pCurrentAction->getType() == ACTION_RUNRECIPE && strCmd.Compare(CMD_RUN_RECIPE_REP) == 0 && pUnit != nullptr) {
+				AfxMessageBox("配方执行中... ...");
+			}
+			else {
+				// 其他命令
+			}
+
+			// 包出错,且不需要拼下一包
+			if (nRet != REPLY_PACKET_NOT_END) {
+				delete m_pCurrentAction;
+				m_pCurrentAction = NULL;
+				SetEvent(m_hEventActions);
+			}
+		}
+		else {
+			if (pUnit != nullptr) {
+				if (strCmd.Compare(AS_MC_STATE_REP) == 0) {
+					// 获取机器状态
+					handleState(params, pUnit);
+				}
+				else if (strCmd.Compare(AS_GET_DOOR_REP) == 0) {
+					// 获取门状态
+					handleDoorState(params, pUnit);
+				}
+				else if (strCmd.Compare(AS_SEND_ERROR_REP) == 0) {
+					// 获取错误码
+					handleAlarmInfo(params, pUnit);
+				}
+				else if (strCmd.Compare(AS_REMOVE_ERROR_REP) == 0) {
+					// 解除告警
+					pUnit->setAlarm(0, 0, "");
+					notifyEventUpdate(REMOTE_EQ_EVENT::REMOVE_ALARM_INFO, pUnit);
+				}
+				else if (strCmd.Compare(AS_SEND_STEP_REP) == 0) {
+					// 处理机器制程
+					handleStep(params, pUnit);
+				}
+				else if (strCmd.Compare(AS_MC_INFO_REP) == 0) {
+					// 获取最新数据,传感器(温度、压力等)
+					handleData(params, pUnit);
+				}
+				else if (strCmd.Compare(AS_SEND_EVENT_REP) == 0) {
+					// 处理上报事件
+					notifyEventUpdate(REMOTE_EQ_EVENT::LOAD_EVENT_CHANGED, pUnit);
+				}
+			}
+		}
+		unlock();
+
+
+		return 0;
+	}
+}
diff --git a/SourceCode/Bond/BEQLibrary/RemoteEquipment.h b/SourceCode/Bond/BEQLibrary/RemoteEquipment.h
new file mode 100644
index 0000000..fb46381
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/RemoteEquipment.h
@@ -0,0 +1,147 @@
+#pragma once
+#include <string>
+#include <list>
+#include "IRemoteEquipment.h"
+#include "Action.h"
+#include "Data.h"
+#include "Unit.h"
+
+
+#define ACTION_GETNAME			    1
+#define ACTION_GETVERSION		    2
+#define ACTION_GETDEVICESTATE	    3
+#define ACTION_GETDOORSTATE		    4
+#define ACTION_GETALARMINFO		    5
+#define ACTION_GETSTEP				6
+#define ACTION_GETDATA				7
+#define ACTION_GETRECIPELIST		8
+#define ACTION_RUNRECIPE			9
+#define ACTION_LOADREADY			10
+#define ACTION_LOADCOMPLETE			11
+#define ACTION_UNLOADCOMPLETE		12
+
+
+namespace BEQ {
+	typedef std::function<void(void* pRemoteEiuipment)> ONREQCONNECTEDEX;
+	typedef std::function<void(void* pRemoteEiuipment, int errorCode)> ONREQCONNECTFAILEDEX;
+	typedef std::function<void(void* pRemoteEiuipment, const char* pszData, int len)> ONREQREADEX;
+	typedef std::function<void(void* pRemoteEquipment, void* pUnit, REMOTE_EQ_EVENT eventCode)> ONREQEVENTUPDATE_EX;
+
+	typedef struct _RemoteEquipmentListener
+	{
+		ONREQCONNECTEDEX		onConnecting;
+		ONREQCONNECTEDEX		onConnected;
+		ONREQCONNECTFAILEDEX	onConnectFailed;
+		ONREQCONNECTEDEX		onDisconnecting;
+		ONREQCONNECTEDEX		onDisconnected;
+		ONREQREADEX				onRead;
+		ONREQEVENTUPDATE_EX		onEventUpdate;
+	} RemoteEquipmentListener;
+
+	enum class REMOTE_EQ_NET_STATE
+	{
+		DISCONNECTED = 0,
+		CONNECTING,
+		CONNECTED,
+		DISCONNECTING
+	};
+
+	class CRemoteEquipment :
+		public IRemoteEquipment
+	{
+	public:
+		CRemoteEquipment();
+		CRemoteEquipment(const char* pszAddr, int port);
+		~CRemoteEquipment();
+
+	public:
+		virtual void setRemoteEquipmentListener(RemoteEquipmentListener listener);
+		virtual int getAddr(char* pszBuffer, int nMaxCount);
+		virtual int getPort();
+		virtual int getName(char* pszBuffer, int nMaxCount);
+		virtual int getVersion(char* pszBuffer, int nMaxCount);
+		virtual bool isConnected();
+		virtual int connect();
+		virtual int close();
+		virtual int reqGetAction(int type, const char* pszCommand, const char* pszUnitName = nullptr, const char* pszParams = nullptr);
+		virtual int reqGetName();
+		virtual int reqGetVersion();
+		virtual int reqGetState(const char* pszUnitName);
+		virtual int reqGetDoorState(const char* pszUnitName);
+		virtual int reqGetAlarmInfo(const char* pszUnitName);
+		virtual int reqGetStep(const char* pszUnitName);
+		virtual int reqGetData(const char* pszUnitName);
+		virtual int reqRecipeList(const char* pszUnitName);
+		virtual int reqRunRecipe(const char* pszUnitName, int nRecipeId, const char* pszRecipeName);
+		virtual IUnit* addUnit(const char* pszName, int nDoorCount);
+		virtual IUnit* getUnit(const char* pszName);
+		virtual const char** getAllUnitNames();
+		virtual int getUnitCount() const;
+		virtual ULONGLONG getConnectTick();
+
+	public:
+		inline void lock() { ::EnterCriticalSection(&m_cs); };
+		inline void unlock() { ::LeaveCriticalSection(&m_cs); };
+
+	private:
+		void splitCString(const CString& strText, TCHAR delimiter = ',', std::function<void(const CString&, int)> callback = nullptr);
+		void notifyEventUpdate(REMOTE_EQ_EVENT eventCode, CUnit* pUnit);
+		void processDoorState(const CString& strPart, int index, int& doorState);
+		void updateDoorState(const CString& strText, int& doorState, CUnit* pUnit);
+		void parseAlarm(const CString& strText, CUnit* pUnit);
+		void handleIdle(CUnit* pUnit);
+		void handleMaterialReceived(const std::string& strMaterialId, CUnit* pUnit);
+		void handleMaterialRemoved(const std::string& strMaterialId, CUnit* pUnit);
+		void handleProcessingStarted(const std::string& strMaterialId, CUnit* pUnit);
+		void handleProcessing(const std::string& strMaterialId, CUnit* pUnit, int svTime, int pvTime);
+		void handleProcessingCompleted(const std::string& strMaterialId, CUnit* pUnit);
+		void handleMachineProcess(const std::string& strMaterialId, const std::string& strStep, CUnit* pUnit, int svTime = 0, int pvTime = 0);
+
+	private:
+		void handleState(const std::map<std::string, std::string>& params, CUnit* pUnit);
+		void handleDoorState(const std::map<std::string, std::string>& params, CUnit* pUnit);
+		void handleAlarmInfo(const std::map<std::string, std::string>& params, CUnit* pUnit);
+		void handleStep(const std::map<std::string, std::string>& params, CUnit* pUnit);
+		void handleData(const std::map<std::string, std::string>& params, CUnit* pUnit);
+		void handleRecipeList(const std::map<std::string, std::string>& params, CUnit* pUnit);
+
+	private:
+		BOOL initClient();
+		static UINT WorkerThreadFunction(LPVOID lpvData);
+		static UINT ActionsThreadFunction(LPVOID lpvData);
+		static UINT TimeoutCheckThreadFunction(LPVOID lpvData);
+		UINT WorkerThreadFunctionInner();
+		UINT ActionsThreadFunctionInner();
+		UINT TimeoutCheckThreadFunctionInner();
+		void CurrentActionTimeout();
+		int decode(char* pszBuffer, int nBufferSize);
+
+	private:
+		CRITICAL_SECTION m_cs;		// 同步锁
+		RemoteEquipmentListener m_listener;
+		std::string m_strAddr;
+		int m_nPort;
+		int m_nLocalPort;
+		std::string m_strName;
+		std::string m_strVersion;
+
+	private:
+		SOCKET m_hSocket;
+		REMOTE_EQ_NET_STATE m_remoteEqNetState;
+		BOOL m_bWorking;
+		WSAEVENT m_hWSAEvent;
+		HANDLE m_hEventClose;		// 等待worker线程退出后, Close函数返回
+		HANDLE m_hEventWrite;
+		HANDLE m_hEventActions;
+		HANDLE m_hEventActionsThreadExit;
+		HANDLE m_hEventTimeoutCheckThreadExit;
+		CAction * m_pCurrentAction;
+		std::list<CAction*> m_actions;
+		BEQ::CData m_data;
+
+	private:
+		std::map<std::string, BEQ::CUnit*> m_units;
+		ULONGLONG m_ullConnectTick;
+	};
+}
+
diff --git a/SourceCode/Bond/BEQLibrary/Resource.h b/SourceCode/Bond/BEQLibrary/Resource.h
new file mode 100644
index 0000000..3a373d1
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/Resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by BEQLibrary.rc
+//
+
+// 新对象的下一组默认值
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NEXT_RESOURCE_VALUE	7000
+#define _APS_NEXT_CONTROL_VALUE		7000
+#define _APS_NEXT_SYMED_VALUE		7000
+#define _APS_NEXT_COMMAND_VALUE		32771
+#endif
+#endif
diff --git a/SourceCode/Bond/BEQLibrary/Servo.cpp b/SourceCode/Bond/BEQLibrary/Servo.cpp
new file mode 100644
index 0000000..32907ac
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/Servo.cpp
@@ -0,0 +1,177 @@
+#include "stdafx.h"
+#include "Servo.h"
+#include "RemoteEquipment.h"
+
+namespace BEQ {
+	CServo::CServo()
+	{
+		m_pClientListener = nullptr;
+		m_servoListener.onRemoteEqConnecting = nullptr;
+		m_servoListener.onRemoteEqConnected = nullptr;
+		m_servoListener.onRemoteEqConnectFailed = nullptr;
+		m_servoListener.onRemoteEqDisconnecting = nullptr;
+		m_servoListener.onRemoteEqDisconnected = nullptr;
+		m_servoListener.onRemoteEqReadRawdata = nullptr;
+		m_servoListener.onRemoteEqEventUpdate = nullptr;
+	}
+
+	CServo::CServo(const char* pszName)
+	{
+		m_strName = pszName;
+		m_pClientListener = nullptr;
+	}
+
+	CServo::~CServo()
+	{
+		for (auto iter = m_clients.begin(); iter != m_clients.end(); iter++) {
+			delete *iter;
+		}
+		m_clients.clear();
+
+		if (m_pClientListener != nullptr) {
+			delete m_pClientListener;
+			m_pClientListener = nullptr;
+		}
+
+		if (m_pServer != nullptr) {
+			m_pServer->Close();
+			delete m_pServer;
+			m_pServer = nullptr;
+		}
+
+		for (auto item : m_remoteEquipments) {
+			delete (CRemoteEquipment*)item;
+		}
+		m_remoteEquipments.clear();
+	}
+
+	void CServo::setListener(BEQ::ServoListener listener)
+	{
+		m_servoListener.onRemoteEqConnecting = listener.onRemoteEqConnecting;
+		m_servoListener.onRemoteEqConnected = listener.onRemoteEqConnected;
+		m_servoListener.onRemoteEqConnectFailed = listener.onRemoteEqConnectFailed;
+		m_servoListener.onRemoteEqDisconnecting = listener.onRemoteEqDisconnecting;
+		m_servoListener.onRemoteEqDisconnected = listener.onRemoteEqDisconnected;
+		m_servoListener.onRemoteEqReadRawdata = listener.onRemoteEqReadRawdata;
+		m_servoListener.onRemoteEqEventUpdate = listener.onRemoteEqEventUpdate;
+	}
+
+	int CServo::getName(char* pszBuffer, int nMaxCount)
+	{
+		return strcpy_s(pszBuffer, nMaxCount, m_strName.c_str());
+	}
+
+	int CServo::createRemoteEquipment(IRemoteEquipment*& pRemoteEquipment, const char* pszAddr, int port)
+	{
+		CRemoteEquipment* p = new CRemoteEquipment(pszAddr, port);
+		pRemoteEquipment = (IRemoteEquipment*)p;
+		m_remoteEquipments.push_back(pRemoteEquipment);
+
+		RemoteEquipmentListener listener;
+		listener.onConnecting = [&](void* pRemoteEiuipment) -> void {
+			if (m_servoListener.onRemoteEqConnecting != nullptr) {
+				m_servoListener.onRemoteEqConnecting(this, pRemoteEquipment);
+			}
+		};
+		listener.onConnected = [&](void* pRemoteEiuipment) -> void {
+			if (m_servoListener.onRemoteEqConnected != nullptr) {
+				m_servoListener.onRemoteEqConnected(this, pRemoteEquipment);
+			}
+		};
+		listener.onConnectFailed = [&](void* pRemoteEiuipment, int errorCode) -> void {
+			if (m_servoListener.onRemoteEqConnectFailed != nullptr) {
+				m_servoListener.onRemoteEqConnectFailed(this, pRemoteEquipment, errorCode);
+			}
+		};
+		listener.onDisconnecting = [&](void* pRemoteEiuipment) -> void {
+			if (m_servoListener.onRemoteEqDisconnecting != nullptr) {
+				m_servoListener.onRemoteEqDisconnecting(this, pRemoteEquipment);
+			}
+		};
+		listener.onDisconnected = [&](void* pRemoteEiuipment) -> void {
+			if (m_servoListener.onRemoteEqDisconnected != nullptr) {
+				m_servoListener.onRemoteEqDisconnected(this, pRemoteEquipment);
+			}
+		};
+		listener.onRead = [&](void* pRemoteEiuipment, const char* pszData, int len) -> void {
+			if (m_servoListener.onRemoteEqReadRawdata != nullptr) {
+				m_servoListener.onRemoteEqReadRawdata(this, pRemoteEquipment, pszData, len);
+			}
+		};
+		listener.onEventUpdate = [&](void* pRemoteEiuipment, void* pUnit, REMOTE_EQ_EVENT eventCode) -> void {
+			if (m_servoListener.onRemoteEqEventUpdate != nullptr) {
+				m_servoListener.onRemoteEqEventUpdate(this, pRemoteEquipment, pUnit, eventCode);
+			}
+		};
+		p->setRemoteEquipmentListener(listener);
+
+		return 0;
+	}
+
+	int CServo::connectRemoteEquipment(IRemoteEquipment* pRemoteEquipment)
+	{
+		if (!findRemoteEquipment(pRemoteEquipment)) return -1;
+		return pRemoteEquipment->connect();
+	}
+
+	bool CServo::findRemoteEquipment(IRemoteEquipment* pRemoteEquipment)
+	{
+		for (auto item : m_remoteEquipments) {
+			if (item == pRemoteEquipment) return true;
+		}
+
+		return false;
+	}
+
+	int CServo::runOnServerMode(int port)
+	{
+		return -1;
+
+		// 暂时不支持Server模式
+		m_pClientListener = new AcceptClientListener;
+		m_pClientListener->onClose = [&](void* pClient) -> int {
+			removeClient((CAcceptClient*)pClient);
+			return 0;
+		};
+		m_pClientListener->onRead = [&](void* pClient, const char* pData, int len) -> int {
+			AfxMessageBox(CString(pData, len));
+			return 0;
+		};
+
+		ServerListener listener;
+		listener.onAccept = [&](void* pServer, CAcceptClient* pClient) -> int {
+			addClient(pClient);
+			return 0;
+		};
+		listener.onClose = [&](void* pServer) -> int {
+			AfxMessageBox("onClose");
+			return 0;
+		};
+
+		m_pServer = new CSocketServer(port, listener);
+		m_pServer->init();
+		return 0;
+	}
+
+	int CServo::close()
+	{
+		return 0;
+	}
+
+	void CServo::addClient(CAcceptClient* pClient)
+	{
+		m_clients.push_back(pClient);
+		pClient->setListener(*m_pClientListener);
+	}
+
+	void CServo::removeClient(CAcceptClient* pClient)
+	{
+		for (auto iter = m_clients.begin(); iter != m_clients.end(); iter++) {
+			if (*iter == pClient) {
+				delete *iter;
+				m_clients.erase(iter);
+				break;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQLibrary/Servo.h b/SourceCode/Bond/BEQLibrary/Servo.h
new file mode 100644
index 0000000..c69ef29
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/Servo.h
@@ -0,0 +1,39 @@
+#pragma once
+#include "IServo.h"
+#include <string>
+#include "SocketServer.h"
+#include <list>
+
+namespace BEQ {
+	class CServo :
+		public IServo
+	{
+	public:
+		CServo();
+		CServo(const char* pszName);
+		~CServo();
+
+	public:
+		virtual void setListener(BEQ::ServoListener listener);
+		virtual int getName(char* pszBuffer, int nMaxCount);
+		virtual int createRemoteEquipment(IRemoteEquipment*& pRemoteEquipment, const char* pszAddr, int port);
+		virtual int connectRemoteEquipment(IRemoteEquipment* pRemoteEquipment);
+		virtual int runOnServerMode(int port);
+
+	public:
+		int close();
+
+	private:
+		bool findRemoteEquipment(IRemoteEquipment* pRemoteEquipment);
+		void addClient(CAcceptClient* pClient);
+		void removeClient(CAcceptClient* pClient);
+
+	private:
+		std::string m_strName;
+		CSocketServer* m_pServer;
+		ServoListener m_servoListener;
+		AcceptClientListener* m_pClientListener;
+		std::list<CAcceptClient*> m_clients;
+		std::list<IRemoteEquipment*> m_remoteEquipments;
+	};
+}
diff --git a/SourceCode/Bond/BEQLibrary/SocketClient.cpp b/SourceCode/Bond/BEQLibrary/SocketClient.cpp
new file mode 100644
index 0000000..f96ca96
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/SocketClient.cpp
@@ -0,0 +1,15 @@
+#include "stdafx.h"
+#include "SocketClient.h"
+
+
+namespace BEQ {
+	CSocketClient::CSocketClient()
+	{
+
+	}
+
+	CSocketClient::~CSocketClient()
+	{
+
+	}
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BEQLibrary/SocketClient.h b/SourceCode/Bond/BEQLibrary/SocketClient.h
new file mode 100644
index 0000000..bccb5c4
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/SocketClient.h
@@ -0,0 +1,20 @@
+#pragma once
+
+namespace BEQ {
+	enum class STATE
+	{
+		READY = 0,
+		CONNECTING,
+		CONNECTED,
+		CONNECTFAILED,
+		DISCONNECTED
+	};
+
+	class CSocketClient
+	{
+	public:
+		CSocketClient();
+		~CSocketClient();
+	};
+}
+
diff --git a/SourceCode/Bond/BEQLibrary/SocketServer.cpp b/SourceCode/Bond/BEQLibrary/SocketServer.cpp
new file mode 100644
index 0000000..d0815fd
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/SocketServer.cpp
@@ -0,0 +1,78 @@
+#include "stdafx.h"
+#include "SocketServer.h"
+
+
+namespace BEQ {
+	CSocketServer::CSocketServer()
+	{
+		m_port = 80;
+		m_listener.onAccept = nullptr;
+		m_listener.onClose = nullptr;
+	}
+
+	CSocketServer::CSocketServer(int port, BEQ::ServerListener listener)
+	{
+		m_port = port;
+		m_listener.onAccept = listener.onAccept;
+		m_listener.onClose = listener.onClose;
+	}
+
+	CSocketServer::~CSocketServer()
+	{
+
+	}
+
+	void CSocketServer::setPort(UINT port)
+	{
+		m_port = port;
+	}
+
+	void CSocketServer::setListenter(BEQ::ServerListener listener)
+	{
+		m_listener.onAccept = listener.onAccept;
+		m_listener.onClose = listener.onClose;
+	}
+
+	void CSocketServer::init()
+	{
+		AfxSocketInit();
+		Create(m_port, 1, FD_ACCEPT | FD_CLOSE);
+		Listen(5);
+	}
+
+	void CSocketServer::OnAccept(int nErrorCode)
+	{
+		sockaddr address;
+		int address_len = sizeof(address);
+		CAcceptClient* pClient = new CAcceptClient();
+		if (Accept(*pClient, &address, &address_len))
+		{
+			int t = 1;
+			pClient->SetSockOpt(TCP_NODELAY, &t, sizeof(int), IPPROTO_TCP);
+			pClient->AsyncSelect(FD_READ | FD_CLOSE);
+			if (m_listener.onAccept != nullptr) {
+				m_listener.onAccept(this, pClient);
+			}
+		}
+
+
+		__super::OnAccept(nErrorCode);
+	}
+
+	void CSocketServer::OnClose(int nErrorCode)
+	{
+		if (m_listener.onClose != nullptr) {
+			m_listener.onClose(this);
+		}
+
+		__super::OnClose(nErrorCode);
+	}
+
+
+	void CSocketServer::OnReceive(int nErrorCode)
+	{
+		TRACE("<CSocketServer>OnReceive此处不应该进入...");
+		__super::OnReceive(nErrorCode);
+	}
+}
+
diff --git a/SourceCode/Bond/BEQLibrary/SocketServer.h b/SourceCode/Bond/BEQLibrary/SocketServer.h
new file mode 100644
index 0000000..756768c
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/SocketServer.h
@@ -0,0 +1,39 @@
+#pragma once
+#include <afxSock.h>
+#include "AcceptClient.h"
+#include <functional>
+
+namespace BEQ {
+
+	typedef std::function<int(void* pServer, CAcceptClient* pClient)> ONACCEPT;
+	typedef std::function<int(void* pServer)> ONCLOSE;
+	
+	typedef struct _ServerListener
+	{
+		ONACCEPT		onAccept;
+		ONCLOSE			onClose;
+	} ServerListener;
+
+	class CSocketServer :
+		public CAsyncSocket
+	{
+	public:
+		CSocketServer();
+		CSocketServer::CSocketServer(int port, BEQ::ServerListener listener);
+		~CSocketServer();
+
+	public:
+		void setListenter(BEQ::ServerListener listener);
+		void setPort(UINT port);
+		void init();
+
+	public:
+		virtual void OnAccept(int nErrorCode);
+		virtual void OnClose(int nErrorCode);
+		virtual void OnReceive(int nErrorCode);
+
+	private:
+		UINT m_port;
+		ServerListener m_listener;
+	};
+}
diff --git a/SourceCode/Bond/BEQLibrary/Unit.cpp b/SourceCode/Bond/BEQLibrary/Unit.cpp
new file mode 100644
index 0000000..df10698
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/Unit.cpp
@@ -0,0 +1,425 @@
+#include "stdafx.h"
+#include "Unit.h"
+#include <chrono>
+#include <sstream>
+#include <iomanip>
+#include <unordered_map>
+
+
+namespace BEQ {
+	CUnit::CUnit()
+	{
+		m_eqState = EQ_STATE::IDLE;
+		m_nDoorCount = 1;
+		m_doorState = 0;
+		m_nAlarmCode = 0;
+		m_nAlarmLevel = 0;
+		m_stepState = STEP_STATE::IDLE;
+		m_stepSvTime = 0;
+		m_stepPvTime = 0;
+		m_dataTime = 0;
+		m_listener.onStateChanged = nullptr;
+		m_listener.onDoorStateChanged = nullptr;
+		m_listener.onAlarm = nullptr;
+		m_listener.onRemoveAlarm = nullptr;
+		m_listener.onStepChanged = nullptr;
+		m_listener.onDataChanged = nullptr;
+		m_nLayerCount = 1;
+		resetLoadState();
+	}
+
+	CUnit::CUnit(const char* pszName)
+	{
+		m_strName = pszName;
+		m_eqState = EQ_STATE::IDLE;
+		m_doorState = 0;
+		m_nAlarmCode = 0;
+		m_nAlarmLevel = 0;
+		m_stepState = STEP_STATE::IDLE;
+		m_stepSvTime = 0;
+		m_stepPvTime = 0;
+		m_dataTime = 0;
+		m_listener.onStateChanged = nullptr;
+		m_listener.onDoorStateChanged = nullptr;
+		m_listener.onAlarm = nullptr;
+		m_listener.onRemoveAlarm = nullptr;
+		m_listener.onStepChanged = nullptr;
+		m_listener.onDataChanged = nullptr;
+		m_listener.onReqLoad = nullptr;
+		m_listener.onReqUnload = nullptr;
+		m_nLayerCount = 1;
+	}
+
+	CUnit::~CUnit()
+	{
+	}
+
+	void CUnit::setListener(UnitListener listener)
+	{
+		m_listener.onStateChanged = listener.onStateChanged;
+		m_listener.onDoorStateChanged = listener.onDoorStateChanged;
+		m_listener.onAlarm = listener.onAlarm;
+		m_listener.onRemoveAlarm = listener.onRemoveAlarm;
+		m_listener.onStepChanged = listener.onStepChanged;
+		m_listener.onDataChanged = listener.onDataChanged;
+		m_listener.onReqLoad = listener.onReqLoad;
+		m_listener.onReqUnload = listener.onReqUnload;
+	}
+
+	int CUnit::getName(char* pszBuffer, int nMaxCount)
+	{
+		return strcpy_s(pszBuffer, nMaxCount, m_strName.c_str());
+	}
+
+	std::string& CUnit::getName()
+	{
+		return m_strName;
+	}
+
+	void CUnit::setState(EQ_STATE state)
+	{
+		m_eqState = state;
+		if (m_listener.onStateChanged != nullptr) {
+			m_listener.onStateChanged(this, m_eqState);
+		}
+	}
+
+	EQ_STATE CUnit::getState()
+	{
+		return m_eqState;
+	}
+
+	const char* CUnit::getStateText()
+	{
+		static char* eqState[] = { "IDLE", "RUN", "DOWN", "MAINTENANCE", "MCHG", "E_TIME" };
+		return eqState[(int)m_eqState];
+	}
+
+	void CUnit::setStateFromString(std::string& strState)
+	{
+		static const std::unordered_map<std::string, EQ_STATE> stateMap = {
+			{"IDLE", EQ_STATE::IDLE},
+			{"RUN", EQ_STATE::RUN},
+			{"DOWN", EQ_STATE::DOWN},
+			{"MAINTENANCE", EQ_STATE::MAINTENANCE},
+			{"MCHG", EQ_STATE::MCHG},
+			{"E_TIME", EQ_STATE::E_TIME}
+		};
+
+		auto it = stateMap.find(strState);
+		if (it != stateMap.end()) {
+			m_eqState = it->second;
+			if (m_listener.onStateChanged != nullptr) {
+				m_listener.onStateChanged(this, m_eqState);
+			}
+		}
+		else {
+			// 处理未找到的状态(根据需求决定是否抛出异常或设置默认值)
+			// m_eqState = EQ_STATE::UNKNOWN;
+		}
+	}
+
+	void CUnit::setDoorCount(int count)
+	{
+		m_nDoorCount = count;
+	}
+
+	void CUnit::setDoorState(int state)
+	{
+		m_doorState = state;
+		if (m_listener.onDoorStateChanged != nullptr) {
+			m_listener.onDoorStateChanged(this, state);
+		}
+	}
+
+	int  CUnit::getDoorState()
+	{
+		return m_doorState;
+	}
+
+	std::string& CUnit::getDoorState(std::string& strState)
+	{
+		static char* doorState[] = {"CLOSE", "OPEN"};
+
+		strState = "";
+		int temp = (int)m_doorState;
+		for (int i = 0; i < m_nDoorCount; i++) {
+			if (temp & 0x01) strState += "OPEN";
+			else strState += "CLOSE";
+			if (i != m_nDoorCount - 1) strState += ",";
+
+			temp = temp >> 1;
+		}
+
+		return strState;
+	}
+
+	void CUnit::setLayerCount(int count)
+	{
+		m_nLayerCount = min(8, count);
+	}
+
+	int CUnit::getLayerCount()
+	{
+		return m_nLayerCount;
+	}
+
+	void CUnit::setIndex(int index)
+	{
+		m_nIndex = index;
+	}
+
+	int CUnit::getIndex()
+	{
+		return m_nIndex;
+	}
+
+	void CUnit::setAlarm(int code, int level, const char* pszText)
+	{
+		if (code == 0) {
+			if (m_nAlarmCode != 0) {
+				m_listener.onRemoveAlarm(this, m_nAlarmCode, m_nAlarmLevel, m_strAlarmText.c_str());
+			}
+
+			m_nAlarmCode = code;
+			m_nAlarmLevel = level;
+			m_strAlarmText = pszText;
+		}
+		else {
+			m_nAlarmCode = code;
+			m_nAlarmLevel = level;
+			m_strAlarmText = pszText;
+
+			if (m_listener.onAlarm != nullptr) {
+				m_listener.onAlarm(this, code, level, pszText);
+			}
+		}
+
+	}
+
+	int CUnit::getAlarmCode()
+	{
+		return m_nAlarmCode;
+	}
+
+	int CUnit::getAlarmLevel()
+	{
+		return m_nAlarmLevel;
+	}
+
+	std::string& CUnit::getAlarmText()
+	{
+		return m_strAlarmText;
+	}
+
+	int CUnit::reqLoad(int layer)
+	{
+		ASSERT(m_listener.onReqLoad);
+		if (layer <= 0) return -1;
+		if (layer > m_nLayerCount) return -2;
+
+		// 状态改变才回调到上层
+		if (m_nLayerLoadState[layer - 1] != LAYER_LOAD_REQ) {
+			m_nLayerLoadState[layer - 1] = LAYER_LOAD_REQ;
+			m_listener.onReqLoad(this, layer);
+			return 0;
+		}
+
+		return -3;
+	}
+
+	int CUnit::reqUnload(int layer)
+	{
+		ASSERT(m_listener.onReqUnload);
+		if (layer <= 0) return -1;
+		if (layer > m_nLayerCount) return -2;
+
+		// 状态改变才回调到上层
+		if (m_nLayerLoadState[layer - 1] != LAYER_UNLOAD_REQ) {
+			m_nLayerLoadState[layer - 1] = LAYER_UNLOAD_REQ;
+			m_listener.onReqUnload(this, layer);
+			return 0;
+		}
+
+		return -3;
+	}
+
+	void CUnit::stepIdle()
+	{
+		m_stepState = STEP_STATE::IDLE;
+		if (m_listener.onStepChanged != nullptr) {
+			m_listener.onStepChanged(this, m_stepState);
+		}
+	}
+
+	void CUnit::stepMaterialReceived(const char* pszID)
+	{
+		m_stepState = STEP_STATE::MATERIAL_RECEIVED;
+		m_stepMaterialId = pszID;
+		if (m_listener.onStepChanged != nullptr) {
+			m_listener.onStepChanged(this, m_stepState);
+		}
+	}
+
+	void CUnit::stepMaterialRemoved(const char* pszID)
+	{
+		m_stepState = STEP_STATE::MATERIAL_REMOVEED;
+		m_stepMaterialId = pszID;
+		if (m_listener.onStepChanged != nullptr) {
+			m_listener.onStepChanged(this, m_stepState);
+		}
+	}
+
+	void CUnit::stepProcessingStarted(const char* pszID)
+	{
+		m_stepState = STEP_STATE::PROCESSING_STARTED;
+		m_stepMaterialId = pszID;
+		if (m_listener.onStepChanged != nullptr) {
+			m_listener.onStepChanged(this, m_stepState);
+		}
+	}
+
+	void CUnit::stepProcessing(const char* pszID, int nSvTime, int nTvTime)
+	{
+		m_stepState = STEP_STATE::PROCESSING;
+		m_stepMaterialId = pszID;
+		m_stepSvTime = nSvTime;
+		m_stepPvTime = nTvTime;
+		if (m_listener.onStepChanged != nullptr) {
+			m_listener.onStepChanged(this, m_stepState);
+		}
+	}
+
+	void CUnit::stepProcessingCompleted(const char* pszID)
+	{
+		m_stepState = STEP_STATE::PROCESSING_COMPLETED;
+		m_stepMaterialId = pszID;
+		if (m_listener.onStepChanged != nullptr) {
+			m_listener.onStepChanged(this, m_stepState);
+		}
+	}
+
+	STEP_STATE CUnit::getStepState()
+	{
+		return m_stepState;
+	}
+
+	const char* CUnit::getStepStateText()
+	{
+		static char* stepState[] = { "IDLE", "MATERIAL_RECEIVED", "MATERIAL_REMOVED",
+			"PROCESSING_STARTED", "PROCESSING", "PROCESSING_COMPLETED" };
+		return stepState[(int)m_stepState];
+	}
+
+	std::string& CUnit::getStepMaterialId()
+	{
+		return m_stepMaterialId;
+	}
+
+	int CUnit::getStepSvTime()
+	{
+		return m_stepSvTime;
+	}
+
+	int CUnit::getSetpPvTime()
+	{
+		return m_stepPvTime;
+	}
+
+	void CUnit::setDataTime(unsigned long long time)
+	{
+		m_dataTime = time;
+	}
+
+	void CUnit::setDataTimeAndResetData(unsigned long long time)
+	{
+		m_dataTime = time;
+		m_dataMap.clear();
+	}
+
+	void CUnit::addData(const char* pszName, const char* pszDataText, bool bComplete)
+	{
+		m_dataMap[pszName] = pszDataText;
+		if (bComplete) {
+			if (m_listener.onDataChanged != nullptr) {
+				m_listener.onDataChanged(this, m_dataTime);
+			}
+		}
+	}
+
+	unsigned long long CUnit::getDataTime()
+	{
+		return m_dataTime;
+	}
+
+	uint64_t CUnit::stringToTimeStamp(const std::string& strTime)
+	{
+		std::tm tm = {};
+		std::istringstream ss(strTime);
+
+		ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
+		if (ss.fail()) {
+			return 0;
+		}
+
+		std::time_t time = std::mktime(&tm);
+		if (time == -1) {
+			return 0;
+		}
+
+		return static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
+			std::chrono::system_clock::from_time_t(time).time_since_epoch()
+		).count());
+	}
+
+	const char* CUnit::getDataTimeText(uint64_t time)
+	{
+		static char buffer[32];
+		auto timePoint = std::chrono::time_point<std::chrono::system_clock>(std::chrono::milliseconds(time));
+		std::time_t t = std::chrono::system_clock::to_time_t(timePoint);
+		std::tm tmPtr;
+		if (localtime_s(&tmPtr, &t) == 0) {
+			strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tmPtr);
+		}
+		else {
+			snprintf(buffer, sizeof(buffer), "Invalid Time");
+		}
+
+		return buffer;
+	}
+
+	std::map<std::string, std::string>& CUnit::getDatas()
+	{
+		return m_dataMap;
+	}
+
+	std::map<int, std::string>& CUnit::getRecipes()
+	{
+		return m_mapRecipe;
+	}
+
+	void CUnit::addRecipe(int id, const char* pszName, bool bComplete)
+	{
+		m_mapRecipe[id] = pszName;
+	}
+
+	bool CUnit::checkRecipe(int id, const char* pszName)
+	{
+		bool bMatched = false;
+		for (auto item : m_mapRecipe) {
+			if (id == item.first && strcmp(pszName, item.second.c_str()) == 0) {
+				bMatched = true;
+				break;
+			}
+		}
+
+		return bMatched;
+	}
+
+	void CUnit::resetLoadState()
+	{
+		for (int i = 0; i < 8; i++) {
+			m_nLayerLoadState[i] = LAYER_LOAD_INIT;
+		}
+	}
+}
diff --git a/SourceCode/Bond/BEQLibrary/Unit.h b/SourceCode/Bond/BEQLibrary/Unit.h
new file mode 100644
index 0000000..9bc540d
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/Unit.h
@@ -0,0 +1,112 @@
+#pragma once
+#include <string>
+#include "IUnit.h"
+#include <functional>
+#include <map>
+
+
+#define LAYER_LOAD_INIT		0
+#define LAYER_LOAD_REQ		1
+#define LAYER_UNLOAD_REQ	2
+
+namespace BEQ {
+	typedef std::function<void(void* pUnit, EQ_STATE)> ONSTATECHANGED;
+	typedef std::function<void(void* pUnit, int stete)> ONDOORSTATECHANGED;
+	typedef std::function<void(void* pUnit, int code, int level, const char* pszText)> ONALARM;
+	typedef std::function<void(void* pUnit, STEP_STATE state)> ONSTEPCHANGED;
+	typedef std::function<void(void* pUnit, unsigned long long time)> ONDATACHANGED;
+	typedef std::function<void(void* pUnit, int layer)> ONREQLOAD;
+
+	typedef struct _UnitListener
+	{
+		ONSTATECHANGED		onStateChanged;
+		ONDOORSTATECHANGED	onDoorStateChanged;
+		ONALARM				onAlarm;
+		ONALARM				onRemoveAlarm;
+		ONSTEPCHANGED		onStepChanged;
+		ONDATACHANGED		onDataChanged;
+		ONREQLOAD			onReqLoad;
+		ONREQLOAD			onReqUnload;
+	} UnitListener;
+
+	class CUnit :
+		public IUnit
+	{
+	public:
+		CUnit();
+		CUnit(const char* pszName);
+		~CUnit();
+
+	public:
+		virtual int getName(char* pszBuffer, int nMaxCount);
+		virtual void setState(EQ_STATE state);
+		virtual EQ_STATE getState();
+		virtual void setDoorCount(int count);
+		virtual void setDoorState(int state);
+		virtual int getDoorState();
+		virtual void setLayerCount(int count);
+		virtual int getLayerCount();
+		virtual void setIndex(int index);
+		virtual int getIndex();
+		virtual void setAlarm(int code, int level, const char* pszText);
+		virtual int getAlarmCode();
+		virtual int getAlarmLevel();
+		virtual void stepIdle();
+		virtual void stepMaterialReceived(const char* pszID);
+		virtual void stepMaterialRemoved(const char* pszID);
+		virtual void stepProcessingStarted(const char* pszID);
+		virtual void stepProcessing(const char* pszID, int nSvTime, int nTvTime);
+		virtual void stepProcessingCompleted(const char* pszID);
+		virtual STEP_STATE getStepState();
+		virtual void setDataTime(unsigned long long time);
+		virtual void setDataTimeAndResetData(unsigned long long time);
+		virtual unsigned long long getDataTime();
+		virtual void addData(const char* pszName, const char* pszDataText, bool bComplete);
+		virtual void addRecipe(int id, const char* pszName, bool bComplete);
+		virtual int reqLoad(int layer);
+		virtual int reqUnload(int layer);
+		
+	public:
+		void setListener(UnitListener listener);
+		std::string& getName();
+		const char* getStateText();
+		void setStateFromString(std::string& strState);
+		std::string& getDoorState(std::string& strState);
+		std::string& getAlarmText();
+		const char* getStepStateText();
+		std::string& getStepMaterialId();
+		int getStepSvTime();
+		int getSetpPvTime();
+		uint64_t stringToTimeStamp(const std::string& strTime);
+		const char* getDataTimeText(uint64_t time);
+		std::map<std::string, std::string>& getDatas();
+		std::map<int, std::string>& getRecipes();
+		bool checkRecipe(int id, const char* pszName);
+		void resetLoadState();
+
+	private:
+		UnitListener m_listener;
+		std::string m_strName;
+		EQ_STATE m_eqState;
+		int m_nDoorCount;
+		int m_doorState;
+		int m_nAlarmCode;
+		int m_nAlarmLevel;
+		std::string m_strAlarmText;
+
+	private:
+		STEP_STATE m_stepState;
+		std::string m_stepMaterialId;
+		int m_stepSvTime;
+		int m_stepPvTime;
+		unsigned long long m_dataTime;
+		std::map<std::string, std::string> m_dataMap;
+		std::map<int, std::string> m_mapRecipe;
+
+	private:
+		int m_nLayerCount;
+		int m_nLayerLoadState[8];		// 各层上下料状态,0:未知;1:上料请求;2:下料请求
+		int m_nIndex;
+	};
+}
+
diff --git a/SourceCode/Bond/BEQLibrary/res/BEQLibrary.rc2 b/SourceCode/Bond/BEQLibrary/res/BEQLibrary.rc2
new file mode 100644
index 0000000..71596f9
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/res/BEQLibrary.rc2
Binary files differ
diff --git a/SourceCode/Bond/BEQLibrary/stdafx.cpp b/SourceCode/Bond/BEQLibrary/stdafx.cpp
new file mode 100644
index 0000000..1d6d963
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/stdafx.cpp
@@ -0,0 +1,7 @@
+// stdafx.cpp : 只包括标准包含文件的源文件
+// BEQLibrary.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+
diff --git a/SourceCode/Bond/BEQLibrary/stdafx.h b/SourceCode/Bond/BEQLibrary/stdafx.h
new file mode 100644
index 0000000..bde7e92
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/stdafx.h
@@ -0,0 +1,39 @@
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的
+
+#include <afxwin.h>         // MFC 核心组件和标准组件
+#include <afxext.h>         // MFC 扩展
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxole.h>         // MFC OLE 类
+#include <afxodlgs.h>       // MFC OLE 对话框类
+#include <afxdisp.h>        // MFC 自动化类
+#endif // _AFX_NO_OLE_SUPPORT
+
+#ifndef _AFX_NO_DB_SUPPORT
+#include <afxdb.h>                      // MFC ODBC 数据库类
+#endif // _AFX_NO_DB_SUPPORT
+
+#ifndef _AFX_NO_DAO_SUPPORT
+#include <afxdao.h>                     // MFC DAO 数据库类
+#endif // _AFX_NO_DAO_SUPPORT
+
+#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
+
+
diff --git a/SourceCode/Bond/BEQLibrary/targetver.h b/SourceCode/Bond/BEQLibrary/targetver.h
new file mode 100644
index 0000000..416cebf
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrary/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
+
+// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
+// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
+
+#include <SDKDDKVer.h>
diff --git a/SourceCode/Bond/BEQLibrarySDK/Include/BEQLib.h b/SourceCode/Bond/BEQLibrarySDK/Include/BEQLib.h
new file mode 100644
index 0000000..dd26bfd
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrarySDK/Include/BEQLib.h
@@ -0,0 +1,74 @@
+#pragma once
+#include <vector>
+#include "IServo.h"
+#include "IUnit.h"
+#include "IEquipment.h"
+#include "IRemoteEquipment.h"
+
+#ifdef _COMPILE_AS_LIB
+	#warning "compiling as lib!"
+#else
+	#ifdef _DEBUG
+		#ifndef _WIN64
+			#pragma comment(lib, "../BEQibrarySDK/lib/Win32/Debug/BEQ.lib")
+		#else 
+			#pragma comment(lib, "../BEQLibrarySDK/lib/x64/Debug/BEQ.lib")
+		#endif
+	#else 
+		#ifndef _WIN64
+			#pragma comment(lib, "../BEQLibrarySDK/lib/Win32/Release/BEQ.lib")
+		#else 
+			#pragma comment(lib, "../BEQLibrarySDK/lib/x64/Release/BEQ.lib")
+		#endif
+	#endif
+#endif // !BUILD_AS_LIB
+
+///////////////////////////////////////////////////////////////////////////////////
+//// Define C linkage if using a C++ compiler
+///////////////////////////////////////////////////////////////////////////////////
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+	///////////////////////////////////////////////////////////////////////////////////
+	//// Determine callling convention baesd on compiler
+	///////////////////////////////////////////////////////////////////////////////////
+#ifdef __BORLANDC__
+
+#ifdef __WIN32__
+#define EXPORTED __declspec(dllexport) __stdcall
+#else
+#define EXPORTED FAR PASCAL __export
+#endif // WIN32
+
+#else // __BORLANDC__
+
+
+#ifdef WIN32
+#define EXPORTED __declspec(dllexport)
+#else
+#define EXPORTED FAR PASCAL __export
+#endif // WIN32
+
+#endif //__BORLANDC__
+
+
+
+	/////////////////////////////////////////////////////////////////////////////////////
+	//// 导出函数
+	////////////////////////////////////////////////////////////////////////////////////
+	int			EXPORTED	BEQ_Initialize();
+	int			EXPORTED	BEQ_Term();
+	int			EXPORTED	BEQ_CreateServo(BEQ::IServo*& pServo, const char* pszName);
+	int			EXPORTED	BEQ_GetServo(BEQ::IServo*& pServo, const char* pszName);
+	int			EXPORTED	BEQ_DestroyServo(BEQ::IServo* pServo);
+	int			EXPORTED	BEQ_CreateEquipment(BEQ::IEquipment*& pEquipment, const char* pszName);
+	int			EXPORTED	BEQ_GetEquipment(BEQ::IEquipment*& pEquipment, const char* pszName);
+	int			EXPORTED	BEQ_DestroyEquipment(BEQ::IEquipment*& pEquipment);
+
+#ifdef __cplusplus
+};
+
+#endif //__cplusplus
+
+
diff --git a/SourceCode/Bond/BEQLibrarySDK/Include/IEquipment.h b/SourceCode/Bond/BEQLibrarySDK/Include/IEquipment.h
new file mode 100644
index 0000000..b8063f0
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrarySDK/Include/IEquipment.h
@@ -0,0 +1,41 @@
+#pragma once
+#include "IUnit.h"
+#include <functional>
+
+
+namespace BEQ {
+	typedef std::function<void(void* pEiuipment, const char* pszAddr, int port)> ONCONNECTED;
+	typedef std::function<void(void* pEiuipment, const char* pszAddr, int port)> ONDISCONNECTED;
+	typedef std::function<int(void* pEiuipment, void* pUnit, int id)> ONRUNRECIPE;
+	typedef std::function<int(void* pEiuipment, void* pUnit)> ONGETRECIPELIST;
+	typedef std::function<int(void* pEiuipment, void* pUnit, const char* pszMaterielId, const char* pszRecipeId)> ONLOADREADY;
+	typedef std::function<int(void* pEiuipment, void* pUnit, int layer)> ONLOADCOMPLETE;
+
+	typedef struct _EquipmentListener
+	{
+		ONCONNECTED			onConnected;
+		ONDISCONNECTED		onDisconnected;
+		ONRUNRECIPE			onRunRecipe;
+		ONGETRECIPELIST		onGetRecipeList;
+		ONLOADREADY			onLoadReady;
+		ONLOADCOMPLETE		onLoadComplete;
+		ONLOADCOMPLETE		onUnloadComplete;
+	} EquipmentListener;
+
+	class IEquipment
+	{
+	public:
+		virtual void setEquipmentListener(EquipmentListener listener) = 0;
+		virtual int getName(char* pszBuffer, int nMaxCount) = 0;
+		virtual void setName(const char* pszName) = 0;
+		virtual int getVersion(char* pszBuffer, int nMaxCount) = 0;
+		virtual void setVersion(const char* pszVersion) = 0;
+		virtual IUnit* addUnit(const char* pszName, int nDoorCount) = 0;
+		virtual IUnit* getUnit(const char* pszName) = 0;
+		virtual int runOnClientMode(const char* pAddr, int port) = 0;
+		virtual int runOnServerMode(int port) = 0;
+		virtual int repRecipeListComplete() = 0;
+		virtual int repLoadReadyComplete(int errorCode) = 0;
+	};
+}
+
diff --git a/SourceCode/Bond/BEQLibrarySDK/Include/IRemoteEquipment.h b/SourceCode/Bond/BEQLibrarySDK/Include/IRemoteEquipment.h
new file mode 100644
index 0000000..6292bed
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrarySDK/Include/IRemoteEquipment.h
@@ -0,0 +1,35 @@
+#pragma once
+#include "IUnit.h"
+#include <functional>
+
+
+namespace BEQ {
+	enum class REMOTE_EQ_EVENT
+	{
+		UNKNOWN = 0,
+		DEVICE_STATUS_CHANGED,
+		DOOR_STATUS_CHANGED,
+		ALARM_INFO_CHANGED,
+		REMOVE_ALARM_INFO,
+		PRODUCTION_PROCESS_CHANGED,
+		SERSOR_DATA_CHANGED,
+		RECIPE_LIST_CHANGED,
+		LOAD_EVENT_CHANGED
+	};
+
+	class IRemoteEquipment
+	{
+	public:
+		virtual int getAddr(char* pszBuffer, int nMaxCount) = 0;
+		virtual int getPort() = 0;
+		virtual int getName(char* pszBuffer, int nMaxCount) = 0;
+		virtual int getVersion(char* pszBuffer, int nMaxCount) = 0;
+		virtual bool isConnected() = 0;
+		virtual int connect() = 0;
+		virtual IUnit* addUnit(const char* pszName, int nDoorCount) = 0;
+		virtual IUnit* getUnit(const char* pszName) = 0;
+		virtual const char** getAllUnitNames() = 0;
+		virtual int getUnitCount() const = 0;
+		virtual ULONGLONG getConnectTick() = 0;
+	};
+}
diff --git a/SourceCode/Bond/BEQLibrarySDK/Include/IServo.h b/SourceCode/Bond/BEQLibrarySDK/Include/IServo.h
new file mode 100644
index 0000000..1c3e07c
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrarySDK/Include/IServo.h
@@ -0,0 +1,30 @@
+#pragma once
+#include "IRemoteEquipment.h"
+
+
+namespace BEQ {
+	typedef std::function<void(void* pServo, void* pRemoteEiuipment)> ONREQCONNECTED;
+	typedef std::function<void(void* pServo, void* pRemoteEiuipment, int errorCode)> ONREQCONNECTFAILED;
+	typedef std::function<void(void* pServo, void* pRemoteEiuipment, const char* pszData, int len)> ONREQREAD;
+	typedef std::function<void(void* pServo, void* pRemoteEquipment, void* pUnit, REMOTE_EQ_EVENT eventCode)> ONREQEVENTUPDATE;
+
+	typedef struct _ServoListener
+	{
+		ONREQCONNECTED		onRemoteEqConnecting;
+		ONREQCONNECTED		onRemoteEqConnected;
+		ONREQCONNECTFAILED	onRemoteEqConnectFailed;
+		ONREQCONNECTED		onRemoteEqDisconnecting;
+		ONREQCONNECTED		onRemoteEqDisconnected;
+		ONREQREAD			onRemoteEqReadRawdata;
+		ONREQEVENTUPDATE	onRemoteEqEventUpdate;
+	} ServoListener;
+
+	class IServo
+	{
+	public:
+		virtual void setListener(BEQ::ServoListener listener) = 0;
+		virtual int getName(char* pszBuffer, int nMaxCount) = 0;
+		virtual int createRemoteEquipment(IRemoteEquipment*& pRemoteEquipment, const char* pszAddr, int port) = 0;
+		virtual int connectRemoteEquipment(IRemoteEquipment* pRemoteEquipment) = 0;
+	};
+}
diff --git a/SourceCode/Bond/BEQLibrarySDK/Include/IUnit.h b/SourceCode/Bond/BEQLibrarySDK/Include/IUnit.h
new file mode 100644
index 0000000..2a49a4e
--- /dev/null
+++ b/SourceCode/Bond/BEQLibrarySDK/Include/IUnit.h
@@ -0,0 +1,56 @@
+#pragma once
+
+namespace BEQ {
+	enum class EQ_STATE
+	{
+		IDLE = 0,
+		RUN,
+		DOWN,
+		MAINTENANCE,
+		MCHG,
+		E_TIME
+	};
+
+	enum class STEP_STATE
+	{
+		IDLE = 0,
+		MATERIAL_RECEIVED,
+		MATERIAL_REMOVEED,
+		PROCESSING_STARTED,
+		PROCESSING,
+		PROCESSING_COMPLETED
+	};
+
+	class IUnit
+	{
+	public:
+		virtual int getName(char* pszBuffer, int nMaxCount) = 0;
+		virtual void setState(EQ_STATE state) = 0;
+		virtual EQ_STATE getState() = 0;
+		virtual void setDoorCount(int count) = 0;
+		virtual void setDoorState(int state) = 0;
+		virtual int  getDoorState() = 0;
+		virtual void setLayerCount(int count) = 0;
+		virtual int getLayerCount() = 0;
+		virtual void setIndex(int index) = 0;
+		virtual int getIndex() = 0;
+		virtual void setAlarm(int code, int level, const char* pszText) = 0;
+		virtual int getAlarmCode() = 0;
+		virtual int getAlarmLevel() = 0;
+		virtual void stepIdle() = 0;
+		virtual void stepMaterialReceived(const char* pszID) = 0;
+		virtual void stepMaterialRemoved(const char* pszID) = 0;
+		virtual void stepProcessingStarted(const char* pszID) = 0;
+		virtual void stepProcessing(const char* pszID, int nSvTime, int nTvTime) = 0;
+		virtual void stepProcessingCompleted(const char* pszID) = 0;
+		virtual STEP_STATE getStepState() = 0;
+		virtual void setDataTime(unsigned long long time) = 0;
+		virtual void setDataTimeAndResetData(unsigned long long time) = 0;
+		virtual unsigned long long getDataTime() = 0;
+		virtual void addData(const char* pszName, const char* pszDataText, bool bComplete) = 0;
+		virtual void addRecipe(int id, const char* pszName, bool bComplete) = 0;
+		virtual int reqLoad(int layer) = 0;
+		virtual int reqUnload(int layer) = 0;
+	};
+}
+
diff --git a/SourceCode/Bond/BLControlsSDK/include/BLButton.h b/SourceCode/Bond/BLControlsSDK/include/BLButton.h
new file mode 100644
index 0000000..063ae70
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/BLButton.h
@@ -0,0 +1,82 @@
+#if !defined(AFX_BLBUTTON_H__16C6D980_BD45_11D3_BDA3_00104B133581__INCLUDED_)
+#define AFX_BLBUTTON_H__16C6D980_BD45_11D3_BDA3_00104B133581__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// BLButton.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CBLButton by Niek Albers
+// Thanks to some people for the tooltip.
+// A cool CBitmapButton derived class with 3 states,
+// Up/Down/BL.
+class AFX_EXT_CLASS CBLButton : public CBitmapButton
+{
+	DECLARE_DYNAMIC(CBLButton);
+
+	// Construction
+public:
+	CBLButton();
+	void SetToolTipText(CString* spText, BOOL bActivate = TRUE);
+	void SetToolTipText(int nId, BOOL bActivate = TRUE);
+	void SetWindowText(CString strText);
+	void SetFontSize(int nSize);
+	void SetTextColor(COLORREF rgbNormal, COLORREF rgbDisable);
+	void SetBLButtonStyle(UINT uID, int nImgCount);
+	void SetBLButtonStyle(UINT uID, int nImgCount, CString spTipText);
+	void SetBLButtonStyle(UINT uID, int nImgCount, CString spTipText, CString spBtnText, int nFontSize);
+
+	CString m_strText;
+	CDC      m_gMemDC;
+
+// Attributes
+protected:
+	void fPaint(CDC* pDC);
+	void ActivateTooltip(BOOL bActivate = TRUE);
+	BOOL m_bBL;						// indicates if mouse is over the button
+	CSize m_ButtonSize;					// width and height of the button
+	CBitmap m_Bitmap;
+	BOOL m_bTracking;
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CBLButton)
+	protected:
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	BOOL LoadBitmap(UINT bitmapid, UINT uiImageCount);
+	virtual ~CBLButton();
+
+	// Generated message map functions
+protected:
+	CToolTipCtrl m_ToolTip;
+	void InitToolTip();
+	//{{AFX_MSG(CBLButton)
+	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+	afx_msg LRESULT OnMouseLeave(WPARAM wparam, LPARAM lparam);
+	afx_msg LRESULT OnMouseHOver(WPARAM wparam, LPARAM lparam) ;
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+
+private:
+	UINT m_uiImageCount;
+	CFont	m_Font;
+	LOGFONT		m_lf;
+	COLORREF m_RGBTextNormal;
+	COLORREF m_RGBTextDisable;
+	BOOL m_bIsDisable;	// Disable老 锭绰 臂磊祸阑 官操扁 困秦.
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_BLBUTTON_H__16C6D980_BD45_11D3_BDA3_00104B133581__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/BLFolderScheduling.h b/SourceCode/Bond/BLControlsSDK/include/BLFolderScheduling.h
new file mode 100644
index 0000000..9a1a2d7
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/BLFolderScheduling.h
@@ -0,0 +1,92 @@
+// BLFolderScheduling.h: interface for the CBLFolderScheduling class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_BLFOLDERSCHEDULING_H__2C8D9E82_222F_41FD_A78D_C17563334CA1__INCLUDED_)
+#define AFX_BLFOLDERSCHEDULING_H__2C8D9E82_222F_41FD_A78D_C17563334CA1__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define TARGETTYPE_FOLDER		1
+#define TARGETTYPE_FILE			2
+
+struct SSubPathInfo
+{
+	CString		s_strItemPath;
+	CString		s_strItemName;
+	long		s_nCreateDate;
+	int			s_nItemType;
+
+	SSubPathInfo()
+	{
+		Reset();
+	}
+	void Reset()
+	{
+		s_strItemPath = _T("");
+		s_strItemName = _T("");
+		s_nCreateDate = 0;
+		s_nItemType = 0;
+	}
+	
+	// 汗荤 积己磊.
+	SSubPathInfo(const SSubPathInfo& rhs)
+	{
+		if(this != &rhs)
+		{
+			s_strItemPath = rhs.s_strItemPath;
+			s_strItemName = rhs.s_strItemName;
+			s_nCreateDate = rhs.s_nCreateDate;
+			s_nItemType = rhs.s_nItemType;
+		}
+	}
+
+	// 措涝楷魂磊 坷滚肺爹.
+    SSubPathInfo& operator=(const SSubPathInfo& rhs)
+	{
+		if(this != &rhs)
+		{
+			s_strItemPath = rhs.s_strItemPath;
+			s_strItemName = rhs.s_strItemName;
+			s_nCreateDate = rhs.s_nCreateDate;
+			s_nItemType = rhs.s_nItemType;
+		}
+		return *this;
+	}
+};
+
+class AFX_EXT_CLASS CBLFolderScheduling  
+{
+public:
+	CBLFolderScheduling();
+	CBLFolderScheduling(CString strPath);
+	CBLFolderScheduling(CString strPath, int nTargetType);
+	virtual ~CBLFolderScheduling();
+
+	BOOL SetRemainDelete(CString strPath, int nTargetType, int nRemainItemCount);
+	BOOL CommitSchedule();
+	void ResetSchedule();
+
+protected:
+	
+	BOOL SearchSubItem(const CString &strMainPath, BOOL bIsAscending);
+	BOOL SortSubItem(BOOL bIsAscending);	// 坷抚瞒鉴 TRUE, 郴覆瞒鉴 FALSE
+	BOOL DeleteFolder(const CString &strFolder);
+
+	// 包府甫 且 弥惑困 版肺.
+	CString				m_strMainPath;
+	BOOL				m_bTargetFolder;
+	BOOL				m_bTargetFile;
+	BOOL				m_bIsAscending;
+
+	// 老何父 巢扁绊 昏力.
+	int					m_nRemainItemCount;
+
+	// 包府 措惑 沥焊
+	SSubPathInfo*		m_pPathInfo;
+	int					m_nSubItemCount;
+};
+
+#endif // !defined(AFX_BLFOLDERSCHEDULING_H__2C8D9E82_222F_41FD_A78D_C17563334CA1__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/BLJogBtn2Parent.h b/SourceCode/Bond/BLControlsSDK/include/BLJogBtn2Parent.h
new file mode 100644
index 0000000..5d40f9c
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/BLJogBtn2Parent.h
@@ -0,0 +1,7 @@
+// by ChaeBL
+
+typedef struct _BLJOGBTN2PARENT
+{
+	virtual BOOL SendMessageToParent(LPCTSTR message) = 0;
+	virtual BOOL SendMessageToParent(int nMsg) = 0;
+} BLJogBtn2Parent, *pBLJogBtn2Parent;
\ No newline at end of file
diff --git a/SourceCode/Bond/BLControlsSDK/include/BLJogButton.h b/SourceCode/Bond/BLControlsSDK/include/BLJogButton.h
new file mode 100644
index 0000000..e062f61
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/BLJogButton.h
@@ -0,0 +1,63 @@
+#if !defined(AFX_BLJOGBUTTON_H__51BB375B_98EA_4921_B964_90AC2D952D70__INCLUDED_)
+#define AFX_BLJOGBUTTON_H__51BB375B_98EA_4921_B964_90AC2D952D70__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// BLJogButton.h : header file
+//
+
+#include "BLJogBtn2Parent.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// CBLJogButton window
+
+class AFX_EXT_CLASS CBLJogButton : public CButton
+{
+// Construction
+public:
+	CBLJogButton();
+
+// Attributes
+public:
+
+// Operations
+public:
+	void SetJ2M(pBLJogBtn2Parent pJ2M)			{ m_pJ2M = pJ2M; }
+	void SetStringDown(CString strMsg)			{ m_strMessageDown = strMsg; }
+	void SetStringUp(CString strMsg)			{ m_strMessageUp = strMsg; }
+	void SetIntDown(int nMsg)					{ m_nMessageDown = nMsg; }
+	void SetIntUp(int nMsg)						{ m_nMessageUp = nMsg; }
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CBLJogButton)
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	virtual ~CBLJogButton();
+
+	// Generated message map functions
+protected:
+	//{{AFX_MSG(CBLJogButton)
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+
+private:
+	pBLJogBtn2Parent	m_pJ2M;
+	CString				m_strMessageDown;
+	CString				m_strMessageUp;
+	int					m_nMessageDown;
+	int					m_nMessageUp;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_JOGBUTTON_H__51BB375B_98EA_4921_B964_90AC2D952D70__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/BLLabel.h b/SourceCode/Bond/BLControlsSDK/include/BLLabel.h
new file mode 100644
index 0000000..c0ef631
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/BLLabel.h
@@ -0,0 +1,77 @@
+#if !defined(AFX_BLLABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_)
+#define AFX_BLLABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+// Label.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CBLLabel window
+enum FlashType {None, Text, Background };
+
+class AFX_EXT_CLASS CBLLabel : public CStatic
+{
+// Construction
+public:
+	CBLLabel();
+	CBLLabel& SetBkColor(COLORREF crBkgnd);
+	CBLLabel& SetTextColor(COLORREF crText);
+	CBLLabel& SetText(const CString& strText);
+	CBLLabel& SetFontBold(BOOL bBold);
+	CBLLabel& SetFontName(const CString& strFont);
+	CBLLabel& SetFontUnderline(BOOL bSet);
+	CBLLabel& SetFontItalic(BOOL bSet);
+	CBLLabel& SetFontSize(int nSize);
+	CBLLabel& SetSunken(BOOL bSet);
+	CBLLabel& SetBorder(BOOL bSet);
+	CBLLabel& FlashText(BOOL bActivate);
+	CBLLabel& FlashBackground(BOOL bActivate);
+	CBLLabel& SetLink(BOOL bLink);
+	CBLLabel& SetLinkCursor(HCURSOR hCursor);
+
+// Attributes
+public:
+protected:
+	void ReconstructFont();
+	COLORREF	m_crText;
+	HBRUSH		m_hBrush;
+	HBRUSH		m_hwndBrush;
+	LOGFONT		m_lf;
+	CFont		m_font;
+	CString		m_strText;
+	BOOL		m_bState;
+	BOOL		m_bTimer;
+	BOOL		m_bLink;
+	FlashType	m_Type;
+	HCURSOR		m_hCursor;
+			// Operations
+public:
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CBLLabel)
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	virtual ~CBLLabel();
+
+	// Generated message map functions
+protected:
+	//{{AFX_MSG(CBLLabel)
+	afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_BLLABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/BLListBoxLog.h b/SourceCode/Bond/BLControlsSDK/include/BLListBoxLog.h
new file mode 100644
index 0000000..276dae8
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/BLListBoxLog.h
@@ -0,0 +1,96 @@
+#if !defined(AFX_BLLISTBOXLOG_H__60501A52_5401_435F_996E_F3EABB095333__INCLUDED_)
+#define AFX_BLLISTBOXLOG_H__60501A52_5401_435F_996E_F3EABB095333__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// cBLListBoxLog.h : header file
+//
+
+#include "BLFolderScheduling.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// CBLListBoxLog window
+
+#define LOG_NORMAL		1
+#define LOG_HISTORY		2
+#define LOG_WARNING		3
+#define LOG_ERROR		4
+#define LOG_DEBUG		5
+
+#define STRINGBUFFER_COUNT		200
+class AFX_EXT_CLASS CBLListBoxLog : public CListBox
+{
+// Construction
+public:
+	CBLListBoxLog();
+	virtual ~CBLListBoxLog();
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CBLListBoxLog)
+	//}}AFX_VIRTUAL
+
+	//////////////////////////////////////////////////////////////////////////
+	// Logging
+	void	SetPath(CString& strPath, CString& strName, BOOL bDelete, int nRemainCount);
+	void	DisplayMessages(BOOL bAddMsgBox, int nLevel, TCHAR *str, ...);
+	void	DisplayMessages(BOOL bAddMsgBox, TCHAR *str, ...);
+	void	DisplayMessage(BOOL bAddMsgBox, int nLevel, TCHAR *str);
+	void	DisplayMessage(BOOL bAddMsgBox, TCHAR *str);
+	void	SetTextColor(long clbg1 = RGB(255,255,255), long clbg2 = RGB(255,255,255), long clText = RGB(0,0,0));
+	virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);
+	// Generated message map functions
+protected:
+	//{{AFX_MSG(CBLListBoxLog)
+	afx_msg LRESULT OnDisplayMessage(WPARAM wParam, LPARAM lParam);
+	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+
+	//////////////////////////////////////////////////////////////////////////
+	// Folder Management
+	CBLFolderScheduling	m_FolderSchedule;
+		
+	//////////////////////////////////////////////////////////////////////////
+	// Logging
+	CString				m_strLogDir;
+	CString				m_strFileName;
+
+	CString				m_strLogPath;
+	CString				m_strLogFile;
+	CTime				m_TimeLogFile;
+	CFile*				m_pFileLog;
+
+	TCHAR				m_strBuffer[512];
+
+	BOOL				MakeLogFile();
+	BOOL				WriteToFile(CTime& time, CString& strContents);
+	BOOL				WriteToFile(CTime& time, TCHAR* strContents);
+
+	DWORD				m_dwThreadID;
+
+	CString				m_strArray[STRINGBUFFER_COUNT];
+	BOOL				m_bMustDisplay[STRINGBUFFER_COUNT];
+	int					m_nAddIndex;
+	int					m_nReadIndex;
+	CRITICAL_SECTION	m_csLog;
+
+	long				m_clBG1;
+	long				m_clBG2;
+	long				m_clText;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_BLLISTBOXLOG_H__60501A52_5401_435F_996E_F3EABB095333__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/BLListCtrlExt.h b/SourceCode/Bond/BLControlsSDK/include/BLListCtrlExt.h
new file mode 100644
index 0000000..4794116
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/BLListCtrlExt.h
@@ -0,0 +1,137 @@
+#if !defined(AFX_BLLISTCTRLEXT_H__516D59C3_2F02_47C6_8F4A_D6A78DCDD44A__INCLUDED_)
+#define AFX_BLLISTCTRLEXT_H__516D59C3_2F02_47C6_8F4A_D6A78DCDD44A__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// BLListCtrlExt.h : header file
+//
+
+#include <afxtempl.h>
+
+#include "InPlaceEdit.h"
+#include "InPlaceComboBox.h"
+
+#define EDITDISABLE_NONE	0
+#define EDITDISABLE_ROWS	1
+#define EDITDISABLE_COLS	2
+#define EDITDISABLE_ROWCOL	3
+
+#define INPLACECTRL_EDIT	4
+#define INPLACECTRL_COMBO	5
+#define INPLACECTRL_EDIT_COMBO	6
+
+#define EDITDISABLE_ROWS_ARRAY	7
+#define EDITDISABLE_COLS_ARRAY	8
+
+#define COMBODATASTATE_SINGLE 9
+#define COMBODATASTATE_MULTI  10
+
+/////////////////////////////////////////////////////////////////////////////
+// CBLListCtrlExt window
+
+typedef struct _LISTROWCOLOR
+{
+	int			s_nRow;
+	COLORREF	s_Color;
+} ListRowColor, *pListRowColor;
+
+class AFX_EXT_CLASS CBLListCtrlExt : public CListCtrl
+{
+// Construction
+public:
+	CBLListCtrlExt();
+	virtual ~CBLListCtrlExt();
+
+// Attributes
+public:
+
+// Operations
+public:
+	void SetComboCtrlCols(CString strCols,int nLength);
+	void SetEditCtrlCols(CString strCols,int nLength);
+	void SetComboData(TCHAR *pData[],int nState,int nLength);
+	void SetComboData(CStringList *pList, int nState);
+	void EditDisableRows(CString strRows,int nLength);
+	void EditDisableCols(CString strCols,int nLength);
+	BOOL GetEnableSortList();
+	void SetEnableSortList(BOOL nEnable);
+	void SortListCtrl(int nCol);
+	void InitListHeader(TCHAR *colList[],int *widthList,int nLength, int nHeight);
+	void SetInPlaceCtrl(int nCtrl);
+	void SetDefaultEditText(CString strInitText);
+	void SetEditDisableState(int nState);
+	int GetEditDisableCols();
+	int GetEditDisableRows();
+	int GetEditDisableState();
+	void EditDisableRowCol(int nRow,int nCol);
+	void EditDisableCols(int nCols);
+	void EditDisableRows(int nRows);
+	void SetColNum(int nColNum);
+	void AddBlankItem();
+	CImageList* SetImageList(CImageList* pImageList, int nImageListType);
+		
+	void InsertListItemEx(int nRow, int nCol, const CString& strString);
+	void InsertListItemEx(int nRow, int nCol, int nValue);
+	void InsertListItemEx(int nRow, int nCol, double dValue, int nRight = 3);
+
+	void SetTextColor(int nRow, COLORREF clrText);
+	void SetBKColor(int nRow, COLORREF clrBK);
+	void ReleaseTextColor(int nRow);
+	void ReleaseBKColor(int nRow);
+	void ResetTextColor();
+	void ResetBKColor();
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CBLListCtrlExt)
+	//}}AFX_VIRTUAL
+
+protected:
+	CInPlaceEdit *m_pEdit;
+	CInPlaceComboBox *m_pComboBox;
+	int m_nInPlaceCtrl;
+	int m_nColNum;
+	int m_nEditDisableState;
+	int m_nDisableCol;
+	int m_nDisableRow;
+	BOOL m_bSortOrder;
+	CString m_strInitEditText;
+	BOOL m_bEnableSortList;
+	int *m_pEditDisableCols;
+	int *m_pEditDisableRows;
+	// Generated message map functions
+protected:
+	int m_nComboCtrlLength;
+	int m_nEditCtrlLength;
+	int *m_pComboCtrlCols;
+	int *m_pEditCtrlCols;
+	CStringList *m_pComboData;
+	int m_nLength;
+	int m_nComboDataState;
+	BOOL m_bSetImageList;
+
+// Implementation
+public:
+	CList<pListRowColor, pListRowColor>	m_ListColorText;
+	CList<pListRowColor, pListRowColor>	m_ListColorBk;
+
+	// Generated message map functions
+protected:
+	//{{AFX_MSG(CBLListCtrlExt)
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+	afx_msg void OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_BLLISTCTRLEXT_H__516D59C3_2F02_47C6_8F4A_D6A78DCDD44A__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/CellCtrl.h b/SourceCode/Bond/BLControlsSDK/include/CellCtrl.h
new file mode 100644
index 0000000..b8bc378
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/CellCtrl.h
@@ -0,0 +1,304 @@
+#ifndef _CELLCTRL_H_
+#define _CELLCTRL_H_
+#define _CELLCTRL_LIB_H_
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// CellCtrl.h : header file
+//
+#include "HeadCtrl.h"
+
+#ifndef  __AFXTEMPL_H
+#include <afxtempl.h>
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CCellCtrl window
+#define CCMSG_USE_EDIT			WM_USER+1
+#define CCMSG_MOVE_EDIT			WM_USER+2
+#define CCMSG_RECT_CHANGE		WM_USER+3
+//#define CCMSG_SEL_PRINT		WM_USER+4
+#define CCMSG_LIST_PRINT		WM_USER+5
+#define CCMSG_FONT_CHANGE		WM_USER+6
+#define CCMSG_SAVE_FILE			WM_USER+7
+#define CCMSG_OPEN_EXCEL		WM_USER+8
+#define CCMSG_OPEN_LIST			WM_USER+9
+#define CCMSG_MODIFY_EDIT		WM_USER+10
+#define CCMSG_COPY_CLIPBOARD	WM_USER+11
+#define CCMSG_PASTE_CLIPBOARD	WM_USER+12
+#define CCMSG_CUT_CLIPBOARD		WM_USER+13
+#define CCMSG_SELITEM_DELETE	WM_USER+14
+#define CCMSG_BACK_COLOR		WM_USER+15
+#define CCMSG_TEXT_COLOR		WM_USER+16
+#define CCMSG_LIST				WM_USER-1
+
+const COLORREF clrTEXT=0x00000000;
+const COLORREF clrBACK=0x00FFFFFF;
+
+class AFX_EXT_CLASS CCellCtrl : public CListCtrl
+{
+public:
+	struct LOCATION
+	{
+		int nItem;
+		int nSubItem;
+	};
+
+	struct CELLCOLOR
+	{
+		COLORREF txtclr;
+		COLORREF bkgclr;
+	};
+
+	struct CELLINFO
+	{
+		int nId;			//CONTROL ID
+		int nItem;			//LIST ITEM
+		int nSubItem;		//LIST SUBITEM
+		CELLCOLOR oldClr;	//汲沥傈狼 祸
+		CELLCOLOR newClr;	//汲沥饶狼 祸
+		LPWSTR lpstrOld;	//涝仿傈 巩磊凯
+		LPWSTR lpstrNew;	//涝仿茄 巩磊凯
+	};
+
+	struct CELLDATA
+	{
+		COLORREF txtclr;//臂磊祸
+		COLORREF bkgclr;//硅版祸
+		bool	 bUseCtl;//牧飘费 荤侩
+		bool	 bTurn; //馆娄馆娄
+		DWORD    dwData;
+	};
+
+	class CCellData : public CELLDATA
+	{
+	public:
+		CCellData()
+		{
+			bTurn =false;
+			bUseCtl=false;//牧飘费 荤侩
+			txtclr=clrTEXT;
+			bkgclr=clrBACK;
+			dwData=0;
+		}
+
+		CCellData(COLORREF TextColor, COLORREF BackColor,
+				  bool bTurning, DWORD dwUserData=0)
+		{
+			bTurn =bTurning;
+			bUseCtl=false;//牧飘费 荤侩
+			txtclr=TextColor;
+			bkgclr=BackColor;
+			dwData=dwUserData;
+		}
+		virtual ~CCellData(){;}
+		void operator=(const CELLDATA& cc)
+		{
+			(CELLDATA)*this=cc;	
+		}
+	};
+	typedef CArray<CCellData, CCellData&> CCSArray;
+	virtual void SerializeAllInfo(CArchive& ar);
+
+protected:
+	CBrush m_brush;		//俊叼飘冠胶狼 硅版
+	CEdit  m_edit;		//俊叼飘 冠胶
+	BOOL	m_bCanEdit;
+	CFont* m_pFont;		//府胶飘 迄飘
+
+protected:
+	void Printing(CDC* pDC);//府胶飘甫 橇赴飘肺 免仿茄促.
+	CRect GetLogRect(CDC* pDC, int nItem, int nSubItem);//府胶飘 伎Rect阑 厚啦俊 蝶扼 函券茄促.
+	void SetCrtToPrintRate(CDC* pDC);//拳搁苞 厘钎狼 厚啦阑 备茄促.
+	int  GetCrtWidth();//拳搁(府胶飘)狼 气蔼阑 府畔茄促.
+
+protected:
+	BOOL m_bSort;//Sort Flag
+	BOOL m_bTime;//SetTimer(,,)甫 汲沥沁绰瘤 咯何
+	BOOL m_bTurnDraw;//府胶飘 盎脚矫 伎狼 祸彬捞 函秦具窍绰瘤 咯何
+	UINT  m_nClipOptin;//努赋焊靛 可记
+	CHeadCtrl m_head;//HeaderCtrl
+	LOCATION m_mcLct;//right mouse click
+	LOCATION m_edLct;//edit location
+	UINT m_nStartColEdit;
+	UINT m_nEndColEdit;
+	CMenu m_menu;//府胶飘 皋春 
+	CMenu* m_pUmenu;//荤侩磊 沥狼 皋春
+	CELLINFO* m_pInfo;
+
+	//汲沥等 Item Data甫 昏力茄促.
+	void DeleteItemData(int nItem);
+	void DeleteAllItemData();
+
+	//俊叼飘冠胶狼 Data甫 荐沥沁绰瘤 咯何甫 眉农窍绊 
+	//何葛扩档快肺 皋矫瘤甫 焊辰促.
+	BOOL IsModifyEdit(int nItem, int nSubItem);
+
+	//酒捞袍狼 康开捞 函沁阑 版快俊 俊叼飘冠胶狼 农扁档 函秦具 窍骨肺
+	//促澜窃荐甫 捞侩窍咯 俊叼飘冠胶甫 盎脚茄促.
+	void UpdateEdit(int nItem, int nSubItem);
+
+	//伎狼 康开阑 盎脚茄促.
+	void UpdateCell(int nItem, int nSubItem);
+
+	//伎狼 拿矾啊 函窍档废 汲沥登绢 乐绰瘤 咯何
+	bool IsTurning(int nItem, int nSubItem);
+
+	//府胶飘狼 沥纺 left,right,center 屈侥阑 备茄促.
+	int  GetColumnFmt(int nSubItem);	
+
+public:
+	enum ListOption
+	{
+		//MENU OPTION
+		menuNO		=	0x00000000,
+		menuEXCEL	=	0x00000001,
+		menuLIST	=	0x00000002,
+		menuPRINT	=	0x00000004,
+		menuINPUT	=	0x00000010,
+		menuSAVE	=	0x00000020,
+		menuFONT	=	0x00000040,
+		menuBACKCOLOR=	0x00000100,
+		menuTEXTCOLOR=	0x00000200,
+		menuCOPY	=	0x00010000,
+		menuPASTE	=	0x00020000,
+		menuCUT		=	0x00040000,
+		menuDELETE	=	0x00080000,
+		menuCOMMON	=	0x000000FF,
+		menuCLIP	=	0x000F0000,
+		menuALL		=	0x000FFFFF,
+		menuAceept  =   0x00010000,
+
+		//CLIPBOARD OPTION
+		clipNO		=	0x00000000,
+		clipCOPY	=	0x00000001,
+		clipPASTE	=	0x00000002,
+		clipCUT		=	0x00000004,
+		clipDELETE	=	0x00000008,
+		clipALL		=	0x0000FFFF,
+	};
+	CCellCtrl();
+
+	//Sort function
+	void EnableSort(BOOL bSort=TRUE){m_bSort=bSort;}
+	void EnableEdit(BOOL bCanEdit)	{ m_bCanEdit = bCanEdit; }
+
+	//menu function
+	BOOL CCellCtrl::SetMenu(CMenu* pMenu=NULL){m_pUmenu=pMenu; return TRUE;}
+	void UseMenu( UINT nOption=menuCOMMON/*default=menuCOMMON*/);
+
+	//editbox function
+	BOOL SetEditMovable( int nStartCol, int nEndCol);
+	BOOL UseEdit( int nItem, int nSubItem);
+	void EditCtrl( MSG pMsg );
+
+	//Rect捞 函沁绰瘤 魄窜茄促.
+	BOOL IsSubRectChange();	
+
+	//府胶飘甫 橇赴飘肺 免仿茄促.
+	BOOL ListPrinting(BOOL bDialog, int Orientation=1/*啊肺=1, 技肺=2*/);
+
+	//keystate function 
+	BOOL IsMultiKey();//shift虐, ctrl虐殿捞 喘矾脸绰瘤 check茄促
+
+	//font function
+	void SetLogFont(LOGFONT logfont);//厘钎 迄飘
+	void SetListFont(LOGFONT* logfont);//府胶飘 迄飘
+
+	//
+	int GetSubItemCount();		//拿烦荐甫 备茄促.
+	int GetLeftSubItem();		//谅螟栏肺何磐 劝己拳等 拿烦阑 茫绰促.
+	int GetRightSubItem();		//快螟栏肺何磐 劝己拳等 拿烦阑 茫绰促.
+	
+	//荤侩磊啊 鞘夸茄 蔼阑 历厘窍绊 阂矾棵荐 乐绰 窃荐捞促.
+	BOOL SetCellData(int nItem, int nSubItem, DWORD dwData);
+	DWORD GetCellData(int nItem, int nSubItem);
+
+	//color function
+	BOOL SetItemTextColor(int nItem, COLORREF color);
+	BOOL SetItemTextColor(int nItem, int nSubItem, COLORREF color);
+	BOOL SetItemBkColor(int nItem, COLORREF color, bool bTurn=false);
+	BOOL SetItemBkColor(int nItem, int nSubItem, COLORREF color, bool bTurn=false);
+	BOOL GetItemColor(int nItem, int nSubItem, CELLCOLOR* pCellClr);
+
+	//Clipboard function
+	void UseClipboard( UINT nOption=clipALL/*default=clipALL*/){m_nClipOptin=nOption;}
+	void CopyClipboard();// Ctrl C (select item copy)
+	void PasteClipboard();//Ctrl V (paste)
+	void CutClipboard();//Ctrl V (paste)
+	void SelectItemDelete();
+
+	BOOL DeleteColumn( int nCol );
+	int  InsertColumn(int nCol, LPCTSTR lpstTxt,int nFormat=LVCFMT_LEFT, 
+						int nWidth = -1, int nSubItem = -1);
+
+	//HeaderCtrl function
+	BOOL GetSafeHead();
+	int  GetHeadHeight();
+	int  GetHeadItemCount();
+	void SetHeadItemCount(int nCount);
+	void SetHeadItemText(int nItem, int nSubItem, LPCTSTR lpstTxt);
+	CString GetHeadItemText(int nItem, int nSubItem);
+	void SetHeadItemMerge(int nsItem, int nsSubItem, 
+						  int neItem, int neSubItem);
+
+protected:
+
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CCellCtrl)
+	public:
+	virtual void Serialize(CArchive& ar);
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	protected:
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	void SaveFile();
+	virtual ~CCellCtrl();
+
+	// Generated message map functions
+protected:
+
+	//{{AFX_MSG(CCellCtrl)
+//	afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
+	afx_msg void OnRclick(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+	afx_msg void OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+	afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
+	afx_msg void OnInsertitem(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg void OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg void OnDeleteallitems(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+	afx_msg void OnDestroy();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	//}}AFX_MSG
+	afx_msg void OnCustomdrawList ( NMHDR* pNMHDR, LRESULT* pResult );
+	afx_msg void OnSaveFile();
+	afx_msg void OnOpenExcel();
+	afx_msg void OnOpenList();
+	afx_msg void OnUseEdit();
+	afx_msg void OnMoveEdit();
+	afx_msg void OnRectchange();
+	afx_msg void OnListPrint();
+	afx_msg void OnFontChange();
+	afx_msg void OnBackColor();
+	afx_msg void OnTextColor();
+
+	afx_msg void OnCopyClipboard()	{	CopyClipboard();	}
+	afx_msg void OnPasteClipboard()	{	PasteClipboard();	}
+	afx_msg void OnCutClipboard()	{	CutClipboard();		}
+	afx_msg void OnSelItemDelete()	{	SelectItemDelete();	}
+
+	DECLARE_MESSAGE_MAP()
+};
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(_CELLCTRL_H_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/ColorButton.h b/SourceCode/Bond/BLControlsSDK/include/ColorButton.h
new file mode 100644
index 0000000..65c1c8b
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/ColorButton.h
@@ -0,0 +1,101 @@
+// Written by Marius Bancila (mbancila@yahoo.com)
+// Copyright (c) 2004.
+//
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is 
+// not sold for profit without the authors written consent, and 
+// providing that this notice and the authors name is included. If 
+// the source code in  this file is used in any commercial application 
+// then acknowledgement must be made to the author of this file 
+// (in whatever form you wish).
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
+// IN THE SOFTWARE.
+// 
+// Please use and enjoy. Please let me know of any bugs/mods/improvements 
+// that you have found/implemented and I will fix/incorporate them into this
+// file. 
+
+
+#if !defined(AFX_COLORBUTTON_H__EB5FACDB_272F_4883_A997_659DDA42FD38__INCLUDED_)
+#define AFX_COLORBUTTON_H__EB5FACDB_272F_4883_A997_659DDA42FD38__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// ColorButton.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CColorButton window
+
+class AFX_EXT_CLASS CColorButton : public CButton
+{
+private:
+	enum {	BUTTON_IN			= 0x01,
+			BUTTON_OUT			= 0x02,
+			BUTTON_BLACK_BORDER	= 0x04,};
+	
+// Construction
+public:
+	CColorButton();
+	CColorButton(COLORREF text, COLORREF bkgnd);
+	CColorButton(COLORREF text, COLORREF bkgnd, COLORREF disabled);
+	CColorButton(COLORREF text, COLORREF bkgnd, COLORREF disabled, COLORREF light, COLORREF highlight, COLORREF shadow, COLORREF darkShadow);
+	
+// Attributes
+public:
+
+private:
+	COLORREF m_TextColor;
+	COLORREF m_BkgndColor;
+	COLORREF m_DisabledBkgndColor;
+	COLORREF m_Light;
+	COLORREF m_Highlight;
+	COLORREF m_Shadow;
+	COLORREF m_DarkShadow;
+	
+// Operations
+public:
+	void SetColor(COLORREF text, COLORREF bkgnd);
+	void SetColor(COLORREF text, COLORREF bkgnd, COLORREF disabled);
+	void SetColor(COLORREF text, COLORREF bkgnd, COLORREF disabled, COLORREF light, COLORREF highlight, COLORREF shadow, COLORREF darkShadow);
+	void SetColorToWindowsDefault();
+	
+private:
+	void DrawFrame(CDC *pDC, CRect rc, int state);
+	void DrawFilledRect(CDC *pDC, CRect rc, COLORREF color);
+	void DrawLine(CDC *pDC, long sx, long sy, long ex, long ey, COLORREF color);
+	void DrawButtonText(CDC *pDC, CRect rc, CString strCaption, COLORREF textcolor);
+	
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CColorButton)
+	public:
+	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	virtual ~CColorButton();
+
+	// Generated message map functions
+protected:
+	//{{AFX_MSG(CColorButton)
+	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_COLORBUTTON_H__EB5FACDB_272F_4883_A997_659DDA42FD38__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/DefectMap.h b/SourceCode/Bond/BLControlsSDK/include/DefectMap.h
new file mode 100644
index 0000000..7dce318
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/DefectMap.h
@@ -0,0 +1,124 @@
+// DefectMap.h: interface for the CDefectMap class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_DEFECTMAP_H__CF34B34E_7A0E_4CBB_880F_4C41FF83A64B__INCLUDED_)
+#define AFX_DEFECTMAP_H__CF34B34E_7A0E_4CBB_880F_4C41FF83A64B__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define ORIGIN_LEFTTOP		1
+#define ORIGIN_LEFTBOTTOM	0
+#define ORIGIN_RIGHTTOP		2
+#define ORIGIN_RIGHTBOTTOM	3
+
+#define UM_MAP_CHANGED			5573
+
+enum OriginDirection		{ OD_LeftTop = 0, OD_RightTop = 1, OD_LeftBottom = 10, OD_RightBottom = 11 };
+
+class AFX_EXT_CLASS CDefectMap  : public CStatic
+{
+public:
+	CDefectMap();
+	virtual ~CDefectMap();
+
+public:
+	void				InitGlass(CWnd* pParent, int nMapWidth, int nMapHeight, int nMapMargin);	// Pixel 窜困 付柳.
+	void				DeinitGlass();
+	int					GetMapTotalWidth()		{ return m_nMapTotalWidth; }
+	int					GetMapTotalHeight()		{ return m_nMapTotalHeight; }
+	int					GetMapWidth()			{ return m_nMapWidth; }
+	int					GetMapHeight()			{ return m_nMapHeight; }
+	
+	void				SetMiniMap(BOOL bIsMiniMap, int nUnitSize)	{ m_bIsMiniMap = bIsMiniMap; m_nUnitSize = nUnitSize; }
+	int					GetUnitSize()			{ return m_nUnitSize; }
+	
+	virtual void		DrawGlass(CDC* pDC)						{ }
+	virtual void		MouseRBtnDwn(CPoint& point)				{ }
+	virtual void		MouseLBtnDwn(CPoint& point)				{ }
+	virtual void		MouseLBtnUp(CPoint& point)				{ }
+	virtual void		MouseLBtnMove(CPoint& point)			{ }
+	virtual void		MouseLBtnDblClk(CPoint& point)			{ }
+	virtual void		Timer(UINT_PTR nIDEvent)					{ }
+	
+	// 犬措/绵家
+	void				IncreaseRatio();
+	void				DecreaseRatio();
+	void				ResetRatio();
+	
+	CPoint&				GetDisplayStart()		{ return m_PointGlassStart; }
+	CPoint&				GetDisplayEnd()			{ return m_PointGlassEnd; }
+	
+	void				SetDisplayRect(CPoint& PointStart, CPoint& PointEnd);
+	void				SetShowShot(BOOL bShow)	{ m_bShowShot = bShow; }
+	
+	void				ConvertGlassToView(CRect &rect);
+	void				ConvertGlassToView(CPoint &pt);
+	CRect				ConvertViewToGlass(CRect &rect);
+	CPoint				ConvertViewToGlass(CPoint &pt);
+
+	// 历厘
+	void				SaveMapToFile(CString strFileName);
+	
+	// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CStaticMap)
+	//}}AFX_VIRTUAL
+
+protected:
+	CWnd*				m_pParentWnd;
+	int					m_nMapTotalWidth;
+	int					m_nMapTotalHeight;
+	int					m_nMapWidth;
+	int					m_nMapHeight;
+	CRect				m_RectWnd;
+	CRect				m_RectMap;
+	
+	//////////////////////////////////////////////////////////////////////////
+	// 弊府扁 沥焊
+	HBITMAP				m_hDrawingSurface;
+	BITMAPINFOHEADER	m_BMIH;
+	CRect				m_RectDrawingSurface;
+	BYTE*				m_pDrawingSurfaceBits;
+	
+	OriginDirection		m_OriginDir;
+	int					m_nUnitSize;
+	
+	// Cell 弊府扁
+	BOOL				m_bShowShot;
+	
+	// 犬措/绵家
+	CRect				m_RectShowWnd;
+	
+	double				m_dWidthRatio;
+	double				m_dHeightRatio;
+	double				m_dRatio;
+	CPoint				m_PointWindowStart;
+	BOOL				m_bDragMove;
+	CPoint				m_PointDragStart;
+	BOOL				m_bIsMiniMap;			// Minimap篮 犬措/绵家甫 救茄促.
+	CPoint				m_PointGlassStart;		// Glass 吝 泅犁 焊咯瘤绰 康开.
+	CPoint				m_PointGlassEnd;
+	
+	CPoint				m_PointCCut[3];			//内呈钠 弊府扁 谅钎
+	int					m_nCCutSize;
+	int					m_nCoordGabX;			// 谅钎甫 谎副 芭府.
+	int					m_nCoordGabY;			// 谅钎甫 谎副 芭府.
+	
+	//{{AFX_MSG(CStaticGlass)
+	afx_msg void OnPaint();
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+	afx_msg long OnUpdateMap(WPARAM wParam, LPARAM lParam);
+	//}}AFX_MSG
+	
+	DECLARE_MESSAGE_MAP()
+};
+
+#endif // !defined(AFX_DEFECTMAP_H__CF34B34E_7A0E_4CBB_880F_4C41FF83A64B__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/FontStatic.h b/SourceCode/Bond/BLControlsSDK/include/FontStatic.h
new file mode 100644
index 0000000..35b2a33
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/FontStatic.h
@@ -0,0 +1,69 @@
+#pragma once
+
+// Defines for the font style
+#define FS_NORMAL			0x00
+#define FS_BOLD				0x01
+#define FS_ITALIC			0x02
+#define FS_UNDERLINED		0x04
+#define FS_STRIKETHROUGH	0x08
+#define FS_ANTIALIAS		0x10
+
+// Defines for horizontal alignment
+#define FS_CENTER			0x20
+#define FS_LEFT				0x40
+#define FS_RIGHT			0x80
+
+// CFontStatic
+
+class AFX_EXT_CLASS CFontStatic : 
+	public CStatic
+{
+	DECLARE_DYNAMIC(CFontStatic)
+
+public:
+	CFontStatic();
+
+	// Attributes
+public:
+	bool m_bBold;
+	bool m_bItalic;
+	bool m_bUnderlined;
+	bool m_bStrikethrough;
+	bool m_bAntialias;
+	bool m_bBgColor;
+
+	bool m_bCenter;
+	bool m_bLeft;
+	bool m_bRight;
+
+	CString m_szText;
+	CString m_szFont;
+	DWORD m_dwColor;
+	DWORD m_dwBgColor;
+	int m_nSize;
+
+	// Operations
+public:
+
+	// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CFontStatic)
+protected:
+	virtual void PreSubclassWindow();
+	//}}AFX_VIRTUAL
+
+	// Implementation
+public:
+	void SetWindowText(LPCTSTR a_lpstr);
+	void SetFontStyle(DWORD dwStyle);
+	void SetBackground(DWORD dwBgColor);
+	void SetFontStatic(CString szFont, int nSize, DWORD dwColor, DWORD dwStyle);
+	virtual ~CFontStatic();
+
+protected:
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnPaint();
+};
+
+
diff --git a/SourceCode/Bond/BLControlsSDK/include/GradientStatic.h b/SourceCode/Bond/BLControlsSDK/include/GradientStatic.h
new file mode 100644
index 0000000..d7c72a7
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/GradientStatic.h
@@ -0,0 +1,149 @@
+#pragma once
+
+
+// CGradientStatic
+typedef UINT (CALLBACK* LPFNDLLFUNC1)(HDC,CONST PTRIVERTEX,DWORD,CONST PVOID,DWORD,DWORD);
+
+class CDoubleBuff : public CDC {
+private:	
+	CBitmap		m_bitmap;		// Offscreen bitmap
+	CBitmap*	m_oldBitmap;	// bitmap originally found in CDoubleBuff
+	CDC*		m_pDC;			// Saves CDC passed in constructor
+	CRect		m_rect;			// Rectangle of drawing area.
+	BOOL		m_bMemDC;		// TRUE if CDC really is a Memory DC.
+public:
+
+	CDoubleBuff(CDC* pDC, const CRect* pRect = NULL) : CDC()
+	{
+		ASSERT(pDC != NULL); 
+
+		// Some initialization
+		m_pDC = pDC;
+		m_oldBitmap = NULL;
+		m_bMemDC = !pDC->IsPrinting();
+
+		// Get the rectangle to draw
+		if (pRect == NULL) {
+			pDC->GetClipBox(&m_rect);
+		} else {
+			m_rect = *pRect;
+		}
+
+		if (m_bMemDC) {
+			// Create a Memory DC
+			CreateCompatibleDC(pDC);
+			pDC->LPtoDP(&m_rect);
+
+			m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
+			m_oldBitmap = SelectObject(&m_bitmap);
+
+			SetMapMode(pDC->GetMapMode());
+
+			SetWindowExt(pDC->GetWindowExt());
+			SetViewportExt(pDC->GetViewportExt());
+
+			pDC->DPtoLP(&m_rect);
+			SetWindowOrg(m_rect.left, m_rect.top);
+		} else {
+			// Make a copy of the relevent parts of the current DC for printing
+			m_bPrinting = pDC->m_bPrinting;
+			m_hDC       = pDC->m_hDC;
+			m_hAttribDC = pDC->m_hAttribDC;
+		}
+
+		// Fill background 
+		FillSolidRect(m_rect, pDC->GetBkColor());
+	}
+
+	virtual ~CDoubleBuff()	
+	{		
+		if (m_bMemDC) {
+			// Copy the offscreen bitmap onto the screen.
+			m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
+				this, m_rect.left, m_rect.top, SRCCOPY);			
+
+			//Swap back the original bitmap.
+			SelectObject(m_oldBitmap);
+		} else {
+			// All we need to do is replace the DC with an illegal value,
+			// this keeps us from accidently deleting the handles associated with
+			// the CDC that was passed to the constructor.			
+			m_hDC = m_hAttribDC = NULL;
+		}	
+	}
+
+	// Allow usage as a pointer	
+	CDoubleBuff* operator->() 
+	{
+		return this;
+	}	
+
+	// Allow usage as a pointer	
+	operator CDoubleBuff*() 
+	{
+		return this;
+	}
+
+	CDC *GetOriginalDC()
+	{
+		return m_pDC;
+	}
+};
+
+class AFX_EXT_CLASS CGradientStatic : public CStatic
+{
+	DECLARE_DYNAMIC(CGradientStatic)
+
+public:
+	enum	EN_ANI_MODE{EN_ANI_NONE=0,EN_ANI_LEFTRIGHT,EN_ANI_LAMP};
+
+	CGradientStatic();
+	virtual ~CGradientStatic();
+	void SetWindowText(LPCTSTR a_lpstr);
+	void SetColor(long cl) {clLeft=cl;};
+	BOOL SetControlFont(int nHeight, int nWidth, int nEscapement,
+		int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline,
+		BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision,
+		BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily,
+		LPCTSTR lpszFacename);
+	void SetGradientColor(long cl) {clRight=cl; SetDrawColor(clLeft, clRight); };
+	void SetTextColor(long cl) {clText=cl;};
+	void SetReverseGradient();
+	void SetLeftSpacing(int iNoOfPixels) { m_iLeftSpacing = iNoOfPixels; };
+	void SetTextAlign(int iAlign ) { m_iAlign = iAlign; }; //0 - left, 1 - center, 2 -right
+	void SetVerticalGradient(BOOL a_bVertical = TRUE) { m_bVertical = a_bVertical; };
+	void SetOulineColor(long cl1, long cl2) { clOut1 = cl1; clOut2 = cl2; m_bDrawOutLine = TRUE; }
+	void SetDrawColor(long cl1, long cl2);
+	void MoveDrawColor();
+	void SetAnimationMode(int nMode, int nTime, int nIndex);
+	static void DrawGradRect(CDC *pDC, CRect r, COLORREF cLeft, COLORREF cRight, BOOL a_bVertical);
+	void DrawGradRect(CDC *pDC, CRect r, BOOL a_bVertical, COLORREF *cl);
+
+protected:
+	CString m_sTEXT;
+	int m_iLeftSpacing;
+	long clLeft;
+	long clRight;
+	long clText;
+	long clOut1;
+	long clOut2;
+	COLORREF clDrawColor[510];
+	int m_iAlign;
+	BOOL m_bDrawOutLine;
+	EN_ANI_MODE m_enAnimation;
+	int m_nAniColorCount;
+	HINSTANCE hinst_msimg32;
+	BOOL m_bCanDoGradientFill;
+	BOOL m_bVertical;
+	LPFNDLLFUNC1 dllfunc_GradientFill;
+
+	CFont m_font;
+
+	afx_msg void OnPaint();
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+
+	DECLARE_MESSAGE_MAP()
+public:
+};
+
+
diff --git a/SourceCode/Bond/BLControlsSDK/include/HeadCtrl.h b/SourceCode/Bond/BLControlsSDK/include/HeadCtrl.h
new file mode 100644
index 0000000..2992da0
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/HeadCtrl.h
@@ -0,0 +1,104 @@
+#if !defined(AFX_HEADCTRL_H__E483AE98_F737_4DBF_8508_8E934A8F6988__INCLUDED_)
+#define AFX_HEADCTRL_H__E483AE98_F737_4DBF_8508_8E934A8F6988__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// HeadCtrl.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CHeadCtrl window
+#ifndef __AFXTEMPL_H
+#include <afxtempl.h>
+#endif
+
+class CHeadCtrl : public CHeaderCtrl
+{
+// Construction
+public:
+	struct HEADCELL
+	{
+		DWORD   state;
+		CString string;
+	};
+	class CHeadCell : public HEADCELL
+	{
+	public:
+		CHeadCell()
+		{
+			state=0;
+			string="";
+		}
+		CHeadCell(HEADCELL& hcell)
+		{
+			*this=hcell;
+		}
+		CHeadCell operator=(HEADCELL& hcell)
+		{
+			state=hcell.state;
+			string=hcell.string;
+			return *this;
+		}
+	};
+
+	typedef CArray<CHeadCell,CHeadCell&> CHeadItem;
+	typedef CArray<CHeadItem,CHeadItem&> CHeadInfo;
+
+public:
+	CHeadCtrl();
+	void SetCount(int nCount, CFont* pFont);
+	int  GetCount(){return m_count;}
+	int  GetHeadHeight();
+
+
+	void InsertColumn(int nCol);
+	void DeleteColumn(int nCol);
+	void FontChange(LOGFONT logfont);
+	BOOL SetItemText(int nItem, int nSubItem, LPCSTR lpcstr);
+	CString GetItemText(int nItem, int nSubItem);
+	BOOL SetItemMerge(int nsItem, int nsSubItem, int neItem, int neSubItem); 
+	UINT GetItemState(int nItem, int nSubItem, int& down, int& right);
+	BOOL GetRect(int nItem, int nSubItem, CRect& rect);
+protected:
+	BOOL m_bclick;
+	CPoint m_pnt;
+
+	CFont m_font;
+	int m_count;
+	CHeadInfo m_Info;
+	BOOL IsDraw(CRect rect);
+	BOOL GetTextRect(CDC* pDC, CString strText, CRect& rect);
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CHeadCtrl)
+	virtual void OnPaint();
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	virtual ~CHeadCtrl();
+
+	// Generated message map functions
+protected:
+	//{{AFX_MSG(CHeadCtrl)
+	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+};
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_HEADCTRL_H__E483AE98_F737_4DBF_8508_8E934A8F6988__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/InPlaceComboBox.h b/SourceCode/Bond/BLControlsSDK/include/InPlaceComboBox.h
new file mode 100644
index 0000000..4ad9dfa
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/InPlaceComboBox.h
@@ -0,0 +1,51 @@
+#if !defined(AFX_INPLACECOMBOBOX_H__2909C5E5_6C2D_42DE_AB56_904A78606462__INCLUDED_)
+#define AFX_INPLACECOMBOBOX_H__2909C5E5_6C2D_42DE_AB56_904A78606462__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// InPlaceComboBox.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CInPlaceComboBox window
+
+class CInPlaceComboBox : public CComboBox
+{
+// Construction
+public:
+	CInPlaceComboBox(int iItem,int iSubItem);
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CInPlaceComboBox)
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	virtual ~CInPlaceComboBox();
+
+	// Generated message map functions
+protected:
+	//{{AFX_MSG(CInPlaceComboBox)
+	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+	afx_msg void OnSelchange();
+	afx_msg void OnKillFocus(CWnd* pNewWnd);
+	//}}AFX_MSG
+	int m_iSubItem;
+	int m_iItem;
+	DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_INPLACECOMBOBOX_H__2909C5E5_6C2D_42DE_AB56_904A78606462__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/InPlaceEdit.h b/SourceCode/Bond/BLControlsSDK/include/InPlaceEdit.h
new file mode 100644
index 0000000..09d9bb2
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/InPlaceEdit.h
@@ -0,0 +1,59 @@
+#if !defined(AFX_INPLACEEDIT_H__89FB99E1_386B_11D3_B257_00104BBB4F35__INCLUDED_)
+#define AFX_INPLACEEDIT_H__89FB99E1_386B_11D3_B257_00104BBB4F35__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+// InPlaceEdit.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CInPlaceEdit window
+
+class CInPlaceEdit : public CEdit
+{
+// Construction
+public:
+	CInPlaceEdit(int iItem, int iSubItem, CString sInitText);
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CInPlaceEdit)
+	public:
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	CString m_strNewValue;
+	virtual ~CInPlaceEdit();
+
+	// Generated message map functions
+protected:
+	//{{AFX_MSG(CInPlaceEdit)
+	afx_msg void OnKillFocus(CWnd* pNewWnd);
+	afx_msg void OnNcDestroy();
+	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
+	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+private:
+	BOOL m_bESC;
+	CString m_sInitText;
+	int m_iSubItem;
+	int m_iItem;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_INPLACEEDIT_H__89FB99E1_386B_11D3_B257_00104BBB4F35__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/LogCtrl.h b/SourceCode/Bond/BLControlsSDK/include/LogCtrl.h
new file mode 100644
index 0000000..4b81fd1
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/LogCtrl.h
@@ -0,0 +1,213 @@
+//LogCtrl.h
+//LogCtrl.h
+#ifndef __LOGCTRL_H
+#define __LOGCTRL_H
+#define __LOGCTRL_LIB_H
+
+#ifndef __AFXTEMPL_H
+#include <afxtempl.h>
+#endif
+
+//LOG CELL STATE
+//MERGE
+#define LCS_NORML		0x0000
+#define LCS_MERGE		0x0001
+#define LCS_UNUSE		0x0002
+
+//LINE
+#define LCS_TLINE		0x0001	//TOP LINE DRAW
+#define LCS_BLINE		0x0002	//BOTTOM LINE DRAW
+#define LCS_LLINE		0x0004	//LEFT LINE DRAW
+#define LCS_RLINE		0x0008	//RIGHT LINE DRAW
+#define LCS_RECT		LCS_TLINE|LCS_BLINE|LCS_LLINE|LCS_RLINE
+
+//merge state
+#define SetFlag(n)  DWORD(BYTE(n)<<16)
+#define GetFlag(d)  int((d & 0x00FF0000)>>16)
+
+#define SetDown(n)  DWORD(BYTE(n)<<8)
+#define GetDown(d)  int((d & 0x0000FF00)>>8)
+
+#define SetRight(n) DWORD(BYTE(n))
+#define GetRight(d) int((d & 0x000000FF))
+
+#define LOGCHECK(b) if(b){return;}
+#define LOGCHECK0(b) if(b){return 0;}
+#define LOGCHECK1(b) if(b){return -1;}
+
+class CPrintDC;
+class CLogCell;
+class CLogPage;
+class CLogCtrl;
+
+typedef CArray<CLogCell,CLogCell&> CLogItem;
+typedef CArray<CLogItem,CLogItem&> CLogItemArray;
+typedef CArray<CLogPage,CLogPage&> CLogPageArray;
+
+typedef struct tagLOGCELL
+{
+	BYTE		m_nLine; //惑窍谅快 扼牢 
+	UINT		m_nState;//促弗伎苞 捍钦灯绰瘤 ..
+	UINT		m_nFormat;//沥纺葛靛
+	RECT		m_rect;  //伎狼 康开
+	COLORREF	m_txtclr;//臂磊祸
+	COLORREF	m_bkgclr;//硅版祸
+	CString		m_strTxt;//臂磊
+	CFont*		m_pfont; //迄飘
+	CBitmap*	m_pBitmap;//厚飘甘
+}LOGCELL;
+
+//Orientation=啊肺(1), 技肺(2)  bDialog=DoModal()
+class CPrintDC
+{
+public:
+	CPrintDC();
+	virtual ~CPrintDC();
+	CDC* GetPrintDC(int Orientation, BOOL bDialog=FALSE);
+protected:
+	CDC *m_pDC;
+};
+
+class CLogCell : public tagLOGCELL
+{
+public:
+	CLogCell();
+	CLogCell(LPCSTR lpstr,
+			CRect	rect,
+			int nFormat=DT_CENTER,
+			COLORREF textColor=0x00000000,
+			COLORREF backColor=0x00ffffff,
+			CFont* pf=NULL);
+
+	void operator=(const CLogCell& log);
+	void InitCell();
+	void Draw(CDC* pDC);
+};
+
+class CLogPage 
+{
+public:
+	CLogPage();
+	CLogPage(CPoint startPnt);
+	virtual ~CLogPage();
+	void RemoveAll();
+	void operator=(CLogPage& page);
+
+	//青,凯 肮荐甫 汲沥茄促.
+	void SetColCount(int nCount);
+	void SetRowCount(int nCount);
+	BOOL RemoveRow(int nRow);
+
+	//厘钎 免仿困摹
+	void SetStartPoint(CPoint startPnt);
+	CPoint GetStartPoint() const;
+
+	//青,凯 肮荐甫 府畔茄促.
+	int GetColCount() const;
+	int GetRowCount() const;
+
+	//气,臭捞甫 汲沥茄促.
+	BOOL SetColWidth(int nCol, int nWidth);
+	BOOL SetRowHeight(int nRow, int nHeight);
+
+	//迄飘甫 汲沥茄促.
+	BOOL SetCellFont(int nRow, int nCol, CFont* pf);
+	BOOL SetCellFont(int nsRow, int nsCol, int neRow, int neCol, CFont* pf);
+	CFont* GetCellFont(int nRow, int nCol);
+
+	//硅版祸阑 汲沥茄促.
+	BOOL SetCellBkgColor(int nRow, int nCol, COLORREF color);
+	COLORREF GetCellBkgColor(int nRow, int nCol);
+
+	//臂磊祸阑 汲沥茄促.
+	BOOL SetCellTxtColor(int nRow, int nCol, COLORREF color);
+	COLORREF GetCellTxtColor(int nRow, int nCol);
+
+	//臂磊困摹 汲沥
+	BOOL SetCellFormat(int nRow, int nCol, int nFormat);
+	int GetCellFormat(int nRow, int nCol);
+
+	//Rect阑 汲沥茄促.
+	BOOL SetCellRect(int nRow, int nCol, CRect rect);
+	BOOL GetCellRect(int nRow, int nCol, CRect& rect);
+
+	//BITMAP阑 汲沥茄促.
+	BOOL SetCellBmp(int nRow, int nCol, CBitmap* pBmp);
+	CBitmap* GetCellBmp(int nRow, int nCol);
+
+	//荤阿屈 弊副锭 绢蠢 困摹甫 弊副 巴牢啊 汲沥茄促. 
+	BOOL SetCellLine(int nRow, int nCol, int nState=LCS_RECT/*LCS_RECT*/);
+	int GetCellLine(int nRow, int nCol);
+
+	//伎俊 臂磊阑 涝仿茄促.
+	BOOL SetItemText(int nRow, int nCol, LPCTSTR lpstr, int nFormat=DT_CENTER|DT_VCENTER|DT_SINGLELINE);
+	CString GetItemText(int nRow, int nCol);
+
+	BOOL SetCell(int nRow, int nCol, CLogCell lc);
+	CLogCell* GetCell(int nRow, int nCol);
+
+	//伎阑 捍钦茄促.
+	BOOL CellMerge(int nsCol, int nsRow, int neCol ,int neRow );
+
+	//免仿茄促.(nPageNO绰 其捞瘤 锅龋捞哥 0老 版快 免仿登瘤 臼绰促.)
+	void Draw(CDC* pDC, int nPageNO=0);
+
+	//SetPageRect(,)窃荐甫 荤侩矫 
+	//Draw(CDC* pDC, int nPageNO=0);窃荐甫 龋免窍扁 官肺傈俊 荤侩秦具窃
+	//侩档: 
+	//   <<page>>                                 <<device>>
+	//  0                               100      0                               1000  
+	//  ΓΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΔ        ΓΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΔ
+	//  Β  (10,10)              (90,10)Β        Β (100,100)           (900,100)Β
+	//  Β  ΓΑΑΑΑΑΑΑΑΑΑΑΔ  Β        Β  ΓΑΑΑΑΑΑΑΑΑΑΑΔ  Β
+	//  Β  Β                      Β  Β        Β  Β                      Β  Β
+	//  Β  Β                      Β ΜΜΜΜΜΜΜ>Β                      Β  Β
+	//  Β  Β                      Β  Β        Β  Β                      Β  Β
+	//  Β  Β                      Β  Β        Β  Β                      Β  Β
+	//  Β  ΖΑΑΑΑΑΑΑΑΑΑΑΕ  Β        Β  ΖΑΑΑΑΑΑΑΑΑΑΑΕ  Β
+	//  Β  (10,40)              (90,40)Β        Β (100,400)           (900,400)Β
+	//  Β                              Β        Β                              Β
+	//  Β                              Β        Β                              Β
+	//  Β                              Β        Β                              Β
+	//  Β                              Β        Β                              Β
+	//  Β                              Β        Β                              Β
+	//  Β                              Β        Β                              Β
+	//  Β                              Β        Β                              Β
+	//  Β                              Β        Β                              Β
+	//  Β                              Β        Β                              Β
+	//  Β                              Β        Β                              Β
+	//  Β                              Β        Β                              Β
+	//  ΖΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΕ        ΖΑΑΑΑΑΑΑΑΑΑΑΑΑΑΑΕ
+	//  200                            100,200    2000                            1000,2000 
+	//  
+	//   CRect page(0,0,100,200);
+	//   CRect device(0,0,1000,2000);
+	//   咯归阑 炼陛 林妨搁: CRect device(100,100,900,1900);
+	//   SetPageRect(pDC, page, device);
+	BOOL SetPageRect(CDC* pDC, CRect page, CRect device);
+protected:
+	bool m_IsViewPort;
+	int m_RowCnt;
+	int m_ColCnt;
+	CPoint		  m_startPnt;
+	CLogItemArray m_liAry;
+};
+
+//厘钎 傈眉甫 包府茄促.
+//厘钎甫 免仿窍扁 困秦 怖 鞘夸窍柳 臼促.
+//CLogPage甫 荤侩秦档 公规窍促.
+class CLogCtrl
+{
+public:
+	CLogCtrl();
+	virtual ~CLogCtrl();
+	int  GetLogPageCount();
+	void AddLogPage(CLogPage& lp);
+	CLogPage* GetLogPage(int nPage);
+	void DelLogPage(int nPage);
+	void Draw(CDC* pDC, DOCINFO* pDocInfo);
+protected:
+	CLogPageArray m_log;
+};
+
+#endif
diff --git a/SourceCode/Bond/BLControlsSDK/include/SortClass.h b/SourceCode/Bond/BLControlsSDK/include/SortClass.h
new file mode 100644
index 0000000..b6b2d83
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/SortClass.h
@@ -0,0 +1,40 @@
+
+
+class CSortClass
+{
+public:
+	CSortClass(CListCtrl * _pWnd, const int _iCol, const bool _bIsNumeric);
+	//CSortClass(CListCtrl * _pWnd, const int _iCol, const bool _bIsNumeric, int iStartingItem, int iEndingItem );
+	virtual ~CSortClass();		
+	
+	int iCol;	
+	int m_iStartingItem;
+	int m_iEndingItem;
+
+	CListCtrl * pWnd;	
+	bool bIsNumeric;
+	
+	void Sort(const bool bAsc);	
+	
+	static int CALLBACK CompareAsc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
+	static int CALLBACK CompareDes(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
+	static int CALLBACK CompareAscI(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
+	static int CALLBACK CompareDesI(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
+
+public:	
+	class CSortItem	
+	{	
+		public:		
+			virtual  ~CSortItem();
+			CSortItem(const DWORD _dw, const CString &_txt);		
+			CString txt;		
+			DWORD dw;	
+	};
+	class CSortItemInt	
+	{	
+		public:
+			CSortItemInt(const DWORD _dw, const CString &_txt);		
+			int iInt ;		
+			DWORD dw;	
+	};
+};
\ No newline at end of file
diff --git a/SourceCode/Bond/BLControlsSDK/include/StaticMap.h b/SourceCode/Bond/BLControlsSDK/include/StaticMap.h
new file mode 100644
index 0000000..591e458
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/StaticMap.h
@@ -0,0 +1,149 @@
+#if !defined(AFX_STATICMAP_H__5A9433C1_E8A9_4393_9E0D_B7A996B9AF3F__INCLUDED_)
+#define AFX_STATICMAP_H__5A9433C1_E8A9_4393_9E0D_B7A996B9AF3F__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// StaticMap.h : header file
+//
+
+#define ORIGIN_LEFTTOP		1
+#define ORIGIN_LEFTBOTTOM	0
+#define ORIGIN_RIGHTTOP		2
+#define ORIGIN_RIGHTBOTTOM	3
+
+#define UM_MAP_CHANGED			5573
+#define _MENU_DEFECT_LIST_ID_			8000
+/////////////////////////////////////////////////////////////////////////////
+// CStaticMap window
+enum OriginDirection		{ OD_LeftTop = 0, OD_RightTop = 1, OD_LeftBottom = 10, OD_RightBottom = 11 };
+
+class AFX_EXT_CLASS CStaticMap : public CStatic
+{
+	// Construction
+public:
+	CStaticMap();
+
+	// Attributes
+public:
+
+	// Operations
+public:
+	void				InitGlass(CWnd* pParent, int nMapWidth, int nMapHeight, int nMapMargin);	// Pixel 窜困 付柳.
+	void				DeinitGlass();
+	int					GetMapTotalWidth()		{ return m_nMapTotalWidth; }
+	int					GetMapTotalHeight()		{ return m_nMapTotalHeight; }
+	int					GetMapWidth()			{ return m_nMapWidth; }
+	int					GetMapHeight()			{ return m_nMapHeight; }
+
+	void				SetMiniMap(BOOL bIsMiniMap, int nUnitSize)	{ m_bIsMiniMap = bIsMiniMap; m_nUnitSize = nUnitSize; }
+	int					GetUnitSize()			{ return m_nUnitSize; }
+
+	virtual void		DrawGlass(CDC* pDC)						{ }
+	virtual void		MouseLBtnDwn(CPoint& point)				{ }
+	virtual void		MouseLBtnUp(CPoint& point)				{ }
+	virtual void		MouseLBtnMove(CPoint& point)			{ }
+	virtual void		MouseLBtnDblClk(CPoint& point)			{ }
+	virtual void		MouseRBtnDwn(CPoint& point)				{ }
+	virtual void		MouseRBtnUp(CPoint& point)				{ }
+	virtual void		MouseRBtnDblClk(CPoint& point)			{ }
+	virtual void		RegistNoDefect()						{ }
+	virtual void		Timer(UINT nIDEvent)					{ }
+
+	// 犬措/绵家
+	void				IncreaseRatio();
+	void				DecreaseRatio();
+	void				ResetRatio();
+
+	CPoint&				GetDisplayStart()		{ return m_PointGlassStart; }
+	CPoint&				GetDisplayEnd()			{ return m_PointGlassEnd; }
+
+	void				SetDisplayRect(CPoint& PointStart, CPoint& PointEnd);
+	void				SetShowShot(BOOL bShow)	{ m_bShowShot = bShow; }
+
+	// 历厘
+	void				SaveMapToFile(CString strFileName);
+	void				SetBGColor(COLORREF color) { m_clBGColor = color; }
+
+	// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CStaticMap)
+	//}}AFX_VIRTUAL
+
+	// Implementation
+public:
+	virtual ~CStaticMap();
+
+	// Generated message map functions
+protected:
+	void				SetMappingMode(CDC *pDC);
+	CPoint				SetWindowToGlass(CPoint pt);
+	CPoint				SetGlassToWindow(CPoint pt);
+	void				ControlZoom(BOOL bZoomIn, CPoint ptMouse);
+
+	void				PopupMenu(int nBaseID, CPoint point);
+
+	CWnd*				m_pParentWnd;
+	int					m_nMapTotalWidth;
+	int					m_nMapTotalHeight;
+	int					m_nMapWidth;
+	int					m_nMapHeight;
+	int					m_nMapMarginWidth;
+	int					m_nMapMarginHeight;
+	CRect				m_RectWnd;
+	CRect				m_RectMap;
+	long				m_clBGColor;
+	long				m_clPatColor;
+	//////////////////////////////////////////////////////////////////////////
+	// 弊府扁 沥焊
+	HBITMAP				m_hDrawingSurface;
+	BITMAPINFOHEADER	m_BMIH;
+	CRect				m_RectDrawingSurface;
+	BYTE*				m_pDrawingSurfaceBits;
+
+	OriginDirection		m_OriginDir;
+	int					m_nUnitSize;
+
+	// Cell 弊府扁
+	BOOL				m_bShowShot;
+
+	// 犬措/绵家
+	CRect				m_RectShowWnd;
+
+	double				m_dRatio;
+	CPoint				m_PointWindowStart;
+	BOOL				m_bDragMove;
+	CPoint				m_PointDragStart;
+	BOOL				m_bIsMiniMap;			// Minimap篮 犬措/绵家甫 救茄促.
+	CPoint				m_PointGlassStart;		// Glass 吝 泅犁 焊咯瘤绰 康开.
+	CPoint				m_PointGlassEnd;
+
+	POINT				m_PointCCut[3];			//内呈钠 弊府扁 谅钎
+	int					m_nCCutSize;
+	int					m_nCoordGabX;			// 谅钎甫 谎副 芭府.
+	int					m_nCoordGabY;			// 谅钎甫 谎副 芭府.
+
+	//{{AFX_MSG(CStaticGlass)
+	afx_msg void OnPaint();
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+	afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
+	afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point);
+	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+	afx_msg long OnUpdateMap(WPARAM wParam, LPARAM lParam);
+	afx_msg void OnMenuChangeViewMode(UINT nID);
+	afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STATICMAP_H__5A9433C1_E8A9_4393_9E0D_B7A996B9AF3F__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/WKButton.h b/SourceCode/Bond/BLControlsSDK/include/WKButton.h
new file mode 100644
index 0000000..6dec8c3
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/WKButton.h
@@ -0,0 +1,119 @@
+#if !defined(AFX_WKBUTTON_H__99FB32BE_6D54_4845_BD51_1BC64E774CC6__INCLUDED_)
+#define AFX_WKBUTTON_H__99FB32BE_6D54_4845_BD51_1BC64E774CC6__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// WKButton.h : header file
+/******************************< 橇肺弊伐 沥焊 >****************************/
+/*   努 贰 胶 疙 : WKButton                                                */ 
+/*   滚       傈 :                                                         */
+/*   弥辆 荐沥老 : 2006. 05. 28                                            */
+/***************************************************************************/
+
+/////////////////////////////////< 沥  狼 >//////////////////////////////////
+
+// 滚瓢 屈怕
+#define		WK_BUTTON_SHPAE_RECTANGLE				0x0001
+#define		WK_BUTTON_SHAPE_CIRCLE					0x0002
+#define		WK_BUTTON_SHAPE_ROUNDRECT				0x0004
+
+// 滚瓢 祸惑
+#define		WK_BUTTON_COLOR_ONE						0x0001
+#define		WK_BUTTON_COLOR_TWO						0x0002
+#define		WK_BUTTON_COLOR_GRADATION_UP			0x0011
+#define		WK_BUTTON_COLOR_GRADATION_RIGHT			0x0012
+#define		WK_BUTTON_COLOR_GRADATION_DOWN			0x0014
+#define		WK_BUTTON_COLOR_GRADATION_LEFT			0x0018
+
+// 滚瓢 惑怕
+#define		WK_BUTTON_STATUS_MOUSEOVER				0x0001
+#define		WK_BUTTON_STATUS_MOUSELEAVE				0x0002
+#define		WK_BUTTON_STATUS_MOUSECLICK				0x0004
+
+
+///////////////////////////////< 努贰胶 备炼 >///////////////////////////////
+class AFX_EXT_CLASS CWKButton : public CButton
+{
+public://<<<<<<<<<<<<<<<<<<<<<< 寇何 立辟 窃荐 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+	CWKButton();
+	virtual ~CWKButton();
+
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CWKButton)
+	public:
+	virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
+	virtual BOOL Create(LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
+	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	virtual BOOL DestroyWindow();
+	protected:
+	virtual void PreSubclassWindow();
+	//}}AFX_VIRTUAL
+public:	
+/*****************************< 滚瓢 汲沥 窃荐 >****************************/
+	/* 咆胶飘 葛剧 棺 郴侩 瘤沥 */
+	BOOL SetButtonText(CString strCaption);
+	BOOL SetButtonText(CString strCaption, COLORREF rgbText);
+	BOOL SetButtonText(CString strCaption, CFont *font, COLORREF rgbText);
+	
+	/* 滚瓢 屈怕 棺 祸惑 瘤沥 */
+	BOOL SetButtonStyle(DWORD dShape, COLORREF rgbColor1);
+	BOOL SetButtonStyle(DWORD dShape, DWORD dStyle,	COLORREF rgbColor1,	COLORREF rgbColor2);
+	/***************************************************************************/
+
+protected://<<<<<<<<<<<<<<<< 郴何 贸府 窃荐 棺 函荐 >>>>>>>>>>>>>>>>>>>>>>>>>
+	/* 惑怕喊 滚瓢 捞固瘤 */
+	CBitmap m_bmpImage1;	//乞惑矫
+	CBitmap m_bmpImage2;	//付快胶 坷滚
+	CBitmap m_bmpImage3;	//努腐
+	
+	/* 惑怕喊 滚瓢 捞固瘤 积己 */
+	BOOL CreateButtonImage();
+
+	/* 滚瓢 屈怕 积己 */
+	BOOL DrawFormRectangle();	// 荤阿
+	BOOL DrawFormCircle();		// 盔
+	BOOL DrawFormRoundRect();	// 嫡辟荤阿
+
+	/* 捞固瘤 贸府 */
+	COLORREF LightValueControl(COLORREF rgb, int nValue);						// 祸惑 灌扁 炼例
+	void DrawGradation(CBitmap* bmpImage, COLORREF color1, COLORREF color2);	// 弊扼单捞记 捞固瘤 积己
+	BOOL DrawBorder(CBitmap* pbmpImage, COLORREF color1, COLORREF color2, int nWidth = 2);		// 滚瓢 抛滴府 弊府扁
+	BOOL DrawText(CBitmap* pBitmap, int nStatus);								// 滚瓢俊 臂揪 持扁
+
+	/* 滚瓢 捞固瘤 沥焊 */
+	DWORD m_dShape;			// 滚瓢 屈怕
+	DWORD m_dStyle;			// 拿矾 胶鸥老
+	COLORREF m_rgbColor1;	// 霉锅掳 拿矾
+	COLORREF m_rgbColor2;	// 滴锅掳 拿矾
+	CRect m_rtButton;		// 滚瓢农扁
+	int m_nWidth;			// 滚瓢 呈厚
+	int m_nHeight;			// 滚瓢 臭捞
+
+	/* 咆胶飘 沥焊 */
+	CString m_strCaption;	// 母记 郴侩
+	CFont m_Font;			// 母记 臂裁
+	COLORREF m_rgbText;		// 母记 祸惑
+	BOOL m_bValueChange;	// 母记 函版
+	
+	/* 滚瓢 惑怕 沥焊 */
+	DWORD m_dButtonStatus;
+	
+	//{{AFX_MSG(CWKButton)
+	afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
+	afx_msg void OnPaint();
+	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_WKBUTTON_H__99FB32BE_6D54_4845_BD51_1BC64E774CC6__INCLUDED_)
diff --git a/SourceCode/Bond/BLControlsSDK/include/XTabCtrl.h b/SourceCode/Bond/BLControlsSDK/include/XTabCtrl.h
new file mode 100644
index 0000000..2d25ef4
--- /dev/null
+++ b/SourceCode/Bond/BLControlsSDK/include/XTabCtrl.h
@@ -0,0 +1,90 @@
+#if !defined(AFX_XTABCTRL_H__A11951B3_2F95_11D3_A896_00A0C9B6FB28__INCLUDED_)
+#define AFX_XTABCTRL_H__A11951B3_2F95_11D3_A896_00A0C9B6FB28__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// XTabCtrl.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CXTabCtrl window
+#include <afxtempl.h>
+
+class AFX_EXT_CLASS CXTabCtrl : public CTabCtrl
+{
+// Construction
+public:
+	CXTabCtrl();
+
+// Attributes
+public:
+
+// Operations
+public:
+	void AddTab(CWnd* pWnd, LPTSTR lpszCaption, int iImage =0);
+	void AddTab(CWnd* pWnd, LPTSTR lpszCaption, int Width, int Height, int iImage =0);
+	void EnableTab(int iIndex, BOOL bEnable = TRUE);
+	BOOL SelectTab(int iIndex);
+	void DeleteAllTabs();
+	void DeleteTab(int iIndex);
+	void SetTopLeftCorner(CPoint pt);
+	BOOL IsTabEnabled(int iIndex);
+
+	void SetDisabledColor(COLORREF cr);
+	void SetSelectedColor(COLORREF cr);
+	void SetNormalColor(COLORREF cr);
+	void SetMouseOverColor(COLORREF cr);
+
+	void SetParentWnd(CWnd* pWnd)	{ m_pParentWnd = pWnd; }
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CXTabCtrl)
+	protected:
+	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
+	virtual void PreSubclassWindow();
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	virtual ~CXTabCtrl();
+
+	// Generated message map functions
+protected:
+	CArray<BOOL, BOOL> m_arrayStatusTab; //** enabled Y\N
+	int m_iSelectedTab;
+	POINT m_ptTabs;
+	COLORREF m_crSelected;
+	COLORREF m_crDisabled;
+	COLORREF m_crNormal;
+	COLORREF m_crMouseOver;
+	COLORREF m_crBKColor;
+
+	int m_iIndexMouseOver;
+	
+	bool m_bMouseOver;
+	bool m_bColorMouseOver;
+	bool m_bColorNormal;
+	bool m_bColorDisabled;
+	bool m_bColorSelected;
+	
+	//{{AFX_MSG(CXTabCtrl)
+	afx_msg void OnSelchange(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg void OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+
+	CWnd*		m_pParentWnd;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_XTABCTRL_H__A11951B3_2F95_11D3_A896_00A0C9B6FB28__INCLUDED_)
diff --git a/SourceCode/Bond/BondEq/AccordionWnd.cpp b/SourceCode/Bond/BondEq/AccordionWnd.cpp
new file mode 100644
index 0000000..fb8e2ee
--- /dev/null
+++ b/SourceCode/Bond/BondEq/AccordionWnd.cpp
@@ -0,0 +1,777 @@
+#include "stdafx.h"
+#include "AccordionWnd.h"
+
+
+#define ITEM_HEIGHT				32
+#define ITEM_SPACE				5
+#define TIMER_ID_CHECKHOVER		1
+#define EXPAND_ICON_WIDE		16
+
+#define BORDER			5
+#define SHADOWWIDE		5
+
+CAccordionWnd::CAccordionWnd()
+{
+	m_hWnd = NULL;
+	m_crFrame = GetSysColor(COLOR_WINDOWFRAME);
+	m_crBkgnd = RGB(255, 255, 255);//GetSysColor(COLOR_BTNFACE); ;
+	m_nPadding[PADDING_LEFT] = 5;
+	m_nPadding[PADDING_TOP] = 5;
+	m_nPadding[PADDING_RIGHT] = 5;
+	m_nPadding[PADDING_BOTTOM] = 5;
+	m_crItemBackground[0] = RGB(218, 218, 218);
+	m_crItemBackground[1] = RGB(34, 177, 76);
+	m_crItemFrame[0] = RGB(128, 128, 128);
+	m_crItemFrame[1] = RGB(128, 128, 128);
+	m_crItemText[0] = RGB(68, 84, 111);
+	m_crItemText[1] = RGB(0, 0, 0);
+	m_crSeparateLine = RGB(222, 222, 222);
+	m_crHoverItemBackground = RGB(244, 245, 247);
+	m_crHoverItemFrame = RGB(200, 222, 255);
+	m_hIconExpand = NULL;
+	m_hIconClose = NULL;
+	m_nHoverItem = -1;
+	m_nCheckHoverItem = -1;
+	m_bShadow = FALSE;
+	m_crShadowBkgnd = GetSysColor(COLOR_BTNFACE);
+}
+
+
+CAccordionWnd::~CAccordionWnd()
+{
+	for (size_t i = 0; i < m_vectorItems.size(); i++) {
+		delete m_vectorItems[i];
+	}
+	m_vectorItems.clear();
+}
+
+BOOL CAccordionWnd::RegisterWndClass()
+{
+	WNDCLASS wc;
+	wc.lpszClassName = ACCORDIONWND_CLASS;
+	wc.hInstance = AfxGetInstanceHandle();
+	wc.lpfnWndProc = WindowProc;
+	wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+	wc.hIcon = 0;
+	wc.lpszMenuName = NULL;
+	wc.hbrBackground = NULL;
+	wc.style = CS_GLOBALCLASS | CS_DBLCLKS;
+	wc.cbClsExtra = 0;
+	wc.cbWndExtra = 0;
+
+	// 注册自定义类
+	return (::RegisterClass(&wc) != 0);
+}
+
+CAccordionWnd * CAccordionWnd::FromHandle(HWND hWnd)
+{
+	CAccordionWnd *pAccordionWnd = (CAccordionWnd *)::GetProp(hWnd, ACCORDIONWND_TAG);
+	return pAccordionWnd;
+}
+
+CAccordionWnd* CAccordionWnd::Hook(HWND hWnd)
+{
+	CAccordionWnd* pAccordionWnd = (CAccordionWnd*)GetProp(hWnd, ACCORDIONWND_TAG);
+	if (pAccordionWnd == NULL) {
+		pAccordionWnd = new CAccordionWnd();
+		pAccordionWnd->m_hWnd = hWnd;
+
+		SetProp(hWnd, ACCORDIONWND_TAG, (HANDLE)pAccordionWnd);
+	}
+
+
+	return pAccordionWnd;
+}
+
+void CAccordionWnd::LoadExpandIcon(CString strExpandFile, CString strCloseFile)
+{
+	m_hIconExpand = (HICON)::LoadImage(AfxGetInstanceHandle(), strExpandFile, IMAGE_ICON, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE,
+		LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+	m_hIconClose = (HICON)::LoadImage(AfxGetInstanceHandle(), strCloseFile, IMAGE_ICON, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE,
+		LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+}
+
+void CAccordionWnd::Setpadding(int type, unsigned int nPadding)
+{
+	if (type >= PADDING_LEFT && PADDING_LEFT <= PADDING_BOTTOM) {
+		m_nPadding[type] = nPadding;
+	}
+}
+
+void CAccordionWnd::SetDefaultItemBackgroundColor(COLORREF crNormal, COLORREF crSel)
+{
+	m_crItemBackground[0] = crNormal;
+	m_crItemBackground[1] = crSel;
+}
+
+void CAccordionWnd::SetDefaultItemFrameColor(COLORREF crNormal, COLORREF crSel)
+{
+	m_crItemFrame[0] = crNormal;
+	m_crItemFrame[1] = crSel;
+}
+
+void CAccordionWnd::SetDefaultItemTextColor(COLORREF crNormal, COLORREF crSel)
+{
+	m_crItemText[0] = crNormal;
+	m_crItemText[1] = crSel;
+}
+
+void CAccordionWnd::Init()
+{
+}
+
+void CAccordionWnd::Release()
+{
+	// delete
+	delete this;
+}
+
+/*
+ * 添加项目
+ * pszName -- 名称
+ * pWnd -- 绑定的窗口
+ * nExpandHeight -- 展开高度,如果为0则自动设置为窗口高
+ */
+void CAccordionWnd::AddItem(char *pszName, CWnd *pWnd, int nExpandHeight, BOOL bExpand/* = TRUE*/, BOOL bEnable/* = TRUE*/)
+{
+	ACCORDIONITEM *pItem = new ACCORDIONITEM;
+	memset(pItem, 0, sizeof(ACCORDIONITEM));
+	pItem->pWnd = pWnd;
+	pItem->bExpand = bExpand;
+	pItem->bEnable = bEnable;
+	strcpy_s(pItem->text, sizeof(pItem->text), pszName);
+	if (nExpandHeight == 0) {
+		RECT rect;
+		pWnd->GetWindowRect(&rect);
+		pItem->nExpandHeight = rect.bottom - rect.top;
+	}
+	else if (nExpandHeight == -1) {
+		pItem->nExpandHeight = -1;
+	}
+	else {
+		pItem->nExpandHeight = nExpandHeight;
+	}
+	m_vectorItems.push_back(pItem);
+
+	
+	// 重新调整个子窗口的位置
+	ResizeItemWnd();
+}
+
+void CAccordionWnd::ResizeItemWnd()
+{
+	RECT rcClient, rcItemClient;
+	GetClientRect(m_hWnd, &rcClient);
+
+	for (size_t i = 0; i < m_vectorItems.size(); i++) {
+		ACCORDIONITEM *pItem = m_vectorItems.at(i);
+		if (pItem->pWnd != NULL) {
+			GetItemRect(rcClient, i, &rcItemClient);
+			rcItemClient.top += ITEM_HEIGHT;
+			if (pItem->nExpandHeight == -1) {
+				rcItemClient.bottom = rcClient.bottom;
+			}
+			else {
+				rcItemClient.bottom = rcItemClient.top + pItem->nExpandHeight;
+			}
+
+			pItem->pWnd->MoveWindow(&rcItemClient);
+			pItem->pWnd->ShowWindow(pItem->bExpand ? SW_SHOW : SW_HIDE);
+		}
+	}
+}
+
+BOOL CAccordionWnd::GetItemHeaderRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect)
+{
+	RECT rcItem;
+	if (!GetItemRect(rcClient, nIndex, &rcItem)) {
+		return FALSE;
+	}
+
+	rcItem.bottom = rcItem.top + ITEM_HEIGHT;
+	CopyRect(lpRect, &rcItem);
+	return TRUE;
+}
+
+BOOL CAccordionWnd::GetItemRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect)
+{
+	if (nIndex >= m_vectorItems.size()) {
+		return FALSE;
+	}
+
+	RECT rcItemHeader;
+	rcItemHeader.left = rcClient.left + m_nPadding[PADDING_LEFT];
+	rcItemHeader.right = rcClient.right - m_nPadding[PADDING_RIGHT];
+	rcItemHeader.top = rcClient.top + m_nPadding[PADDING_TOP];
+	rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT;
+	for (size_t i = 0; i < m_vectorItems.size(); i++) {
+		ACCORDIONITEM *pItem = m_vectorItems.at(i);
+		if (pItem->bExpand) {
+			rcItemHeader.bottom += pItem->nExpandHeight;
+		}
+
+		if (i == nIndex) {
+			break;;
+		}
+
+		rcItemHeader.top = rcItemHeader.bottom + ITEM_SPACE;
+		rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT;
+	}
+
+
+	CopyRect(lpRect, &rcItemHeader);
+	return TRUE;
+}
+
+int CAccordionWnd::HitTest(POINT pt, int &nHitTest)
+{
+	int nRet = -1;
+	nHitTest = -1;
+	RECT rcClient;
+	GetClientRect(m_hWnd, &rcClient);
+	if (PtInRect(&rcClient, pt)) {
+		nRet = 1;
+	}
+
+	int nItemIndex = -1;
+	RECT rcItemHeader;
+	for (size_t i = 0; i < m_vectorItems.size(); i++) {
+		GetItemHeaderRect(rcClient, (unsigned int)i, &rcItemHeader);
+
+		if (PtInRect(&rcItemHeader, pt)) {
+			nItemIndex = (unsigned int)i;
+
+			break;
+		}
+	}
+
+	if (nItemIndex != -1) {
+		nRet = 2;
+		nHitTest = nItemIndex;
+	}
+
+	return nRet;
+}
+
+BOOL CAccordionWnd::Togle(unsigned int nIndex)
+{
+	if (nIndex >= m_vectorItems.size()) {
+		return FALSE;
+	}
+
+	ACCORDIONITEM *pItem = m_vectorItems[nIndex];
+	pItem->bExpand = !pItem->bExpand;
+
+
+	// 重新调整个子窗口的位置
+	ResizeItemWnd();
+
+	RECT rcClient;
+	GetClientRect(m_hWnd, &rcClient);
+	::InvalidateRect(m_hWnd, &rcClient, TRUE);
+
+	return TRUE;
+}
+
+void CAccordionWnd::Notify(int nCode, int dwData, int dwData1/* = 0*/, int dwData2/* = 0*/)
+{
+	HWND hParent;
+	hParent = GetParent(m_hWnd);
+	if (hParent != NULL) {
+		ACCORDION_NMHDR accordionWndnmhdr;
+		accordionWndnmhdr.nmhdr.hwndFrom = m_hWnd;
+		accordionWndnmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
+		accordionWndnmhdr.nmhdr.code = nCode;
+		accordionWndnmhdr.dwData = dwData;
+		accordionWndnmhdr.dwData1 = dwData1;
+		accordionWndnmhdr.dwData2 = dwData2;
+		SendMessage(hParent, WM_NOTIFY, (WPARAM)accordionWndnmhdr.nmhdr.idFrom, (LPARAM)&accordionWndnmhdr);
+	}
+}
+
+/*
+ * 拦截窗口消息函数
+ */
+LRESULT CALLBACK CAccordionWnd::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+	CAccordionWnd* pAccordionWnd = (CAccordionWnd *)GetProp(hWnd, ACCORDIONWND_TAG);
+	if (pAccordionWnd == NULL && uMsg != WM_NCCREATE)
+	{
+		return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
+	}
+
+
+	// 如果Hook则响应消息
+	ASSERT(hWnd);
+	switch (uMsg)
+	{
+	case WM_NCCREATE:
+		return CAccordionWnd::OnNcCreate(hWnd, wParam, lParam);
+
+	case WM_DESTROY:
+		return pAccordionWnd->OnDestroy(wParam, lParam);
+
+	case WM_NCCALCSIZE:
+		return pAccordionWnd->OnNcCalcsize(wParam, lParam);
+
+	case WM_NCPAINT:
+		return pAccordionWnd->OnNcPaint(wParam, lParam);
+
+	case WM_PAINT:
+		return pAccordionWnd->OnPaint(wParam, lParam);
+
+	case WM_TIMER:
+		return pAccordionWnd->OnTimer(wParam, lParam);
+
+	case WM_MOUSEMOVE:
+		return pAccordionWnd->OnMouseMove(wParam, lParam);
+
+	case WM_LBUTTONDOWN:
+		return pAccordionWnd->OnLButtonDown(wParam, lParam);
+
+	case WM_LBUTTONUP:
+		return pAccordionWnd->OnLButtonUp(wParam, lParam);
+
+	case WM_MOUSEWHEEL:
+		return pAccordionWnd->OnMouseWheel(wParam, lParam);
+
+	case WM_SIZE:
+		return pAccordionWnd->OnSize(wParam, lParam);
+
+	case WM_GETDLGCODE:
+		return DLGC_WANTALLKEYS;
+
+	default:
+		break;
+	}
+
+	return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+/*
+ * WM_NCCREATE
+ * 窗口创建前的初始化工作
+ */
+LRESULT CAccordionWnd::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+	CAccordionWnd* pAccordionWnd = (CAccordionWnd *)GetProp(hWnd, ACCORDIONWND_TAG);
+	ASSERT(pAccordionWnd == NULL);
+
+	Hook(hWnd);
+	return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam);
+}
+
+/*
+ * WM_NCCALCSIZE
+ */
+LRESULT CAccordionWnd::OnNcCalcsize(WPARAM wParam, LPARAM lParam)
+{
+	if (!m_bShadow) {
+		return ::DefWindowProc(m_hWnd, WM_NCCALCSIZE, wParam, lParam);
+	}
+
+
+	LPRECT lprcWnd = (LPRECT)lParam;
+	lprcWnd->left += BORDER;
+	lprcWnd->top += BORDER;
+	lprcWnd->right -= (BORDER + SHADOWWIDE);
+	lprcWnd->bottom -= (BORDER + SHADOWWIDE);
+
+	return 0;
+}
+
+/*
+ * WM_DESTROY
+ * 窗口销毁时
+ */
+LRESULT CAccordionWnd::OnDestroy(WPARAM wParam, LPARAM lParam)
+{
+	Release();
+	return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam);
+}
+
+
+/*
+ * WM_TIMER
+ */
+LRESULT CAccordionWnd::OnTimer(WPARAM wParam, LPARAM lParam)
+{
+	int nTimerId = (int)wParam;
+	if (m_nTimerId == nTimerId) {
+
+		POINT pt;
+		::GetCursorPos(&pt);
+		::ScreenToClient(m_hWnd, &pt);
+
+		int nRet, nHitTest;
+		nRet = HitTest(pt, nHitTest);
+		if (m_nCheckHoverItem != nHitTest) {
+			KillTimer(m_hWnd, m_nTimerId);
+			m_nHoverItem = nHitTest;
+			m_nCheckHoverItem = nHitTest;
+
+			RECT rcClient;
+			GetClientRect(m_hWnd, &rcClient);
+			::InvalidateRect(m_hWnd, &rcClient, TRUE);
+		}
+	}
+
+
+	return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam);
+}
+
+/*
+ * WM_MOUSEMOVE
+ * 鼠标移动时,检测鼠标位置并回调给主窗口
+ */
+LRESULT CAccordionWnd::OnMouseMove(WPARAM wParam, LPARAM lParam)
+{
+	POINT pt;
+	pt.x = (int)LOWORD(lParam);
+	pt.y = (int)HIWORD(lParam);
+
+	int nRet, nHitTest;
+	nRet = HitTest(pt, nHitTest);
+
+	if (nRet == 2) {
+		ACCORDIONITEM *pItem = m_vectorItems[nHitTest];
+		if (pItem != NULL && pItem->bEnable) {
+			::SetCursor(LoadCursor(NULL, IDC_HAND));
+		}
+	}
+	else {
+		::SetCursor(LoadCursor(NULL, IDC_ARROW));
+	}
+
+	int nLastItem = m_nHoverItem;
+	if (m_nHoverItem != nHitTest) {
+		m_nHoverItem = nHitTest;
+
+		RECT rcClient, rcLastItemClient, rcCurItemClient;
+		GetClientRect(m_hWnd, &rcClient);
+		GetItemRect(rcClient, nLastItem, &rcLastItemClient);
+		::InvalidateRect(m_hWnd, &rcLastItemClient, nHitTest < 0);
+
+		if (nHitTest >= 0) {
+			ACCORDIONITEM *pItem = m_vectorItems.at(nHitTest);
+			if (!pItem->bEnable) {
+				m_nHoverItem = -1;
+			}
+			else {
+				KillTimer(m_hWnd, m_nTimerId);
+				m_nTimerId = SetTimer(m_hWnd, TIMER_ID_CHECKHOVER, 200, NULL);
+				m_nCheckHoverItem = m_nHoverItem;
+
+				GetItemRect(rcClient, m_nHoverItem, &rcCurItemClient);
+				::InvalidateRect(m_hWnd, &rcCurItemClient, TRUE);
+			}
+		}
+	}
+
+
+	return ::DefWindowProc(m_hWnd, WM_MOUSEMOVE, wParam, lParam);
+}
+
+/*
+ * WM_LBUTTONDOWN
+ * 鼠标左键下压
+ */
+LRESULT CAccordionWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam)
+{
+	POINT pt;
+	pt.x = (int)LOWORD(lParam);
+	pt.y = (int)HIWORD(lParam);
+
+	int nRet, nHitTest;
+	nRet = HitTest(pt, nHitTest);
+
+	if (nRet == 2) {
+		ACCORDIONITEM *pItem = m_vectorItems[nHitTest];
+		if (pItem != NULL && pItem->bEnable) {
+			::SetCursor(LoadCursor(NULL, IDC_HAND));
+		}
+	}
+	else {
+		::SetCursor(LoadCursor(NULL, IDC_ARROW));
+	}
+
+
+	return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam);
+}
+
+/*
+ * WM_LBUTTONUP
+ * 鼠标左键释放
+ */
+LRESULT CAccordionWnd::OnLButtonUp(WPARAM wParam, LPARAM lParam)
+{
+	POINT pt;
+	pt.x = (int)LOWORD(lParam);
+	pt.y = (int)HIWORD(lParam);
+
+	int nRet, nHitTest;
+	nRet = HitTest(pt, nHitTest);
+
+	if (nRet == 2) {
+		ACCORDIONITEM *pItem = m_vectorItems[nHitTest];
+		if (pItem != NULL && pItem->bEnable) {
+			::SetCursor(LoadCursor(NULL, IDC_HAND));
+			Togle(nHitTest);
+		}
+	}
+	else {
+		::SetCursor(LoadCursor(NULL, IDC_ARROW));
+	}
+
+
+	return ::DefWindowProc(m_hWnd, WM_LBUTTONUP, wParam, lParam);
+}
+
+/*
+ * WM_MOUSEWHEEL
+ * 鼠标滚轮滚动时,缩放图像
+ */
+LRESULT CAccordionWnd::OnMouseWheel(WPARAM wParam, LPARAM lParam)
+{
+	return ::DefWindowProc(m_hWnd, WM_MOUSEWHEEL, wParam, lParam);
+}
+
+/*
+ * WM_NCPAINT
+ */
+LRESULT CAccordionWnd::OnNcPaint(WPARAM wParam, LPARAM lParam)
+{
+	LRESULT lRet = ::DefWindowProc(m_hWnd, WM_NCPAINT, wParam, lParam);
+
+
+	// 然后画边框
+	long styleEx = GetWindowLong(m_hWnd, GWL_EXSTYLE);
+	if ((styleEx & WS_EX_CLIENTEDGE) == WS_EX_CLIENTEDGE) {
+
+		RECT rcWindow, rcClient;
+		GetClientRect(m_hWnd, &rcClient);
+		::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.left);
+		::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.right);
+		GetWindowRect(m_hWnd, &rcWindow);
+		::OffsetRect(&rcClient, -rcWindow.left, -rcWindow.top);
+		::OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
+
+		HRGN hRgnWnd = CreateRectRgnIndirect(&rcWindow);
+		HRGN hRgnClient = CreateRectRgnIndirect(&rcClient);
+
+		HDC hDC = GetWindowDC(m_hWnd);
+		::SelectClipRgn(hDC, hRgnWnd);
+		::ExtSelectClipRgn(hDC, hRgnClient, RGN_DIFF);
+
+
+		// 没有阴影的边框
+		if (!m_bShadow) {
+			HBRUSH hBrushBK, hBrushFrame;
+			hBrushBK = CreateSolidBrush(m_crBkgnd);
+			::FillRect(hDC, &rcWindow, hBrushBK);
+			DeleteObject(hBrushBK);
+
+			hBrushFrame = CreateSolidBrush(m_crFrame);
+			::FrameRect(hDC, &rcWindow, hBrushFrame);
+			DeleteObject(hBrushFrame);
+		}
+
+		// 有阴影的边框
+		else {
+
+			RECT rcFrame0, rcFrame1;
+			rcFrame0.left = rcWindow.left + SHADOWWIDE;
+			rcFrame0.top = rcWindow.top + SHADOWWIDE;
+			rcFrame0.right = rcWindow.right;
+			rcFrame0.bottom = rcWindow.bottom;
+			rcFrame1.left = rcWindow.left;
+			rcFrame1.top = rcWindow.top;
+			rcFrame1.right = rcWindow.right - SHADOWWIDE;
+			rcFrame1.bottom = rcWindow.bottom - SHADOWWIDE;
+
+
+			// 背景框和对话框(父窗体)背景色一致
+			HBRUSH hBrushBK, hBrushFrame;
+			hBrushBK = CreateSolidBrush(m_crShadowBkgnd);
+			::FillRect(hDC, &rcWindow, hBrushBK);
+			DeleteObject(hBrushBK);
+
+
+			// 阴影框
+			BYTE r = GetRValue(m_crShadowBkgnd);
+			BYTE g = GetGValue(m_crShadowBkgnd);
+			BYTE b = GetBValue(m_crShadowBkgnd);
+			BYTE rstep = (r - GetRValue(m_crFrame)) / SHADOWWIDE;
+			BYTE gstep = (r - GetGValue(m_crFrame)) / SHADOWWIDE;
+			BYTE bstep = (r - GetBValue(m_crFrame)) / SHADOWWIDE;
+
+			for (int i = 0; i < SHADOWWIDE; i++) {
+				hBrushBK = CreateSolidBrush(RGB(r - i*rstep, g - i*gstep, b - i*bstep));
+				::FillRect(hDC, &rcFrame0, hBrushBK);
+				DeleteObject(hBrushBK);
+				rcFrame0.bottom -= 1;
+				rcFrame0.right -= 1;
+			}
+
+
+			// 前景框
+			hBrushBK = CreateSolidBrush(m_crBkgnd);
+			::FillRect(hDC, &rcFrame1, hBrushBK);
+			DeleteObject(hBrushBK);
+
+			hBrushFrame = CreateSolidBrush(m_crFrame);
+			::FrameRect(hDC, &rcFrame1, hBrushFrame);
+			DeleteObject(hBrushFrame);
+		}
+
+
+		::DeleteObject(hRgnWnd);
+		::DeleteObject(hRgnClient);
+		ReleaseDC(m_hWnd, hDC);
+	}
+
+	return lRet;
+}
+
+/*
+ * WM_PAINT
+ */
+LRESULT CAccordionWnd::OnPaint(WPARAM wParam, LPARAM lParam)
+{
+	HDC hDC, hMemDC;
+	HBITMAP hBitmap;
+	RECT rcClient;
+	CString strText;
+	HFONT hFont;
+	HBRUSH hBrushBK;
+
+
+	// BeginPaint
+	PAINTSTRUCT ps;
+	hDC = BeginPaint(m_hWnd, &ps);
+	GetClientRect(m_hWnd, &rcClient);
+
+	hMemDC = ::CreateCompatibleDC(hDC);
+	hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left,
+		rcClient.bottom - rcClient.top);
+	::SelectObject(hMemDC, hBitmap);
+	::SetBkMode(hMemDC, TRANSPARENT);
+
+
+	// 背景颜色
+	hBrushBK = CreateSolidBrush(m_crBkgnd);
+	::FillRect(hMemDC, &rcClient, hBrushBK);
+	DeleteObject(hBrushBK);
+
+
+	// 绘子项列表
+	hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+	::SelectObject(hMemDC, hFont);
+
+	HPEN hPenSeparate = ::CreatePen(PS_SOLID, 1, m_crSeparateLine);
+	RECT rcItem, rcItemHeader;
+	for (size_t i = 0; i < m_vectorItems.size(); i++) {
+		ACCORDIONITEM *pItem = m_vectorItems[i];
+		GetItemRect(rcClient, i, &rcItem);
+		GetItemHeaderRect(rcClient, i, &rcItemHeader);
+
+
+		// 热点项的背景色和边框
+		if (m_nHoverItem == (int)i) {
+			HBRUSH hbrItemHeaderBackground = CreateSolidBrush(m_crHoverItemBackground);
+			HBRUSH hbrItemFrame = CreateSolidBrush(m_crHoverItemFrame);
+
+			HRGN hRgn = CreateRoundRectRgn(rcItemHeader.left, rcItemHeader.top, rcItemHeader.right, rcItemHeader.bottom, 2, 2);
+			::FillRgn(hMemDC, hRgn, hbrItemHeaderBackground);
+			::FrameRgn(hMemDC, hRgn, hbrItemFrame, 1, 1);
+			::DeleteObject(hbrItemHeaderBackground);
+			::DeleteObject(hbrItemFrame);
+			::DeleteObject(hRgn);
+		}
+
+
+		// 箭头
+		BOOL bDrawIcon = DrawIconEx(hMemDC, rcItemHeader.left + (ITEM_HEIGHT - EXPAND_ICON_WIDE) / 2, rcItemHeader.top + (ITEM_HEIGHT - EXPAND_ICON_WIDE)/2,
+			pItem->bExpand ? m_hIconExpand : m_hIconClose, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE, 0, 0, DI_NORMAL);
+
+
+		// 文本
+		::SetTextColor(hMemDC, m_nHoverItem == (int)i ? m_crItemText[1] : m_crItemText[0]);
+		RECT rcText;
+		rcText.left = rcItemHeader.left + (bDrawIcon ? ITEM_HEIGHT : (ITEM_HEIGHT - EXPAND_ICON_WIDE) / 2);
+		rcText.top = rcItemHeader.top;
+		rcText.right = rcItemHeader.right;
+		rcText.bottom = rcItemHeader.bottom;
+		::DrawText(hMemDC, pItem->text, (int)strlen(pItem->text), &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+
+
+		// 文本右边分隔线
+		SIZE sizeText;
+		GetTextExtentPoint32(hMemDC, pItem->text, (int)strlen(pItem->text), &sizeText);
+
+
+		HPEN hOldPen = (HPEN)::SelectObject(hMemDC, hPenSeparate);
+		MoveToEx(hMemDC, rcText.left + sizeText.cx + 10, rcItemHeader.top+(rcItemHeader.bottom- rcItemHeader.top-1)/2, NULL);
+		LineTo(hMemDC, rcItemHeader.right-10, rcItemHeader.top+(rcItemHeader.bottom - rcItemHeader.top - 1) / 2);
+		::SelectObject(hMemDC, hOldPen);
+
+
+		rcItemHeader.top = rcItemHeader.bottom + ITEM_SPACE;
+		rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT;
+	}
+	::DeleteObject(hPenSeparate);
+
+
+	// EndPaint
+	::BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
+		hMemDC, 0, 0, SRCCOPY);
+	EndPaint(m_hWnd, &ps);
+	::DeleteObject(hBitmap);
+	::DeleteDC(hMemDC);
+
+
+	return 1;
+}
+
+/*
+ * WM_SIZE
+ */
+LRESULT CAccordionWnd::OnSize(WPARAM wParam, LPARAM lParam)
+{
+	LRESULT lRet = ::DefWindowProc(m_hWnd, WM_SIZE, wParam, lParam);
+
+	ResizeItemWnd();
+
+	return lRet;
+}
+
+/*
+ * 设置背景色
+ * color -- 背景色
+ */
+void CAccordionWnd::SetBkgndColor(COLORREF color)
+{
+	m_crBkgnd = color;
+}
+
+
+/*
+ * 设置阴影的背景色(即父窗口的背景)
+ * color -- 背景色
+ */
+void CAccordionWnd::SetShadowBkgnd(COLORREF color)
+{
+	m_crShadowBkgnd = color;
+}
+
+/*
+ * 设置边框颜色
+ * color -- 边框颜色
+ */
+void CAccordionWnd::SetFrameColor(COLORREF color, BOOL bShadow/* = FALSE*/)
+{
+	m_crFrame = color;
+	m_bShadow = bShadow;
+	SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+}
+
diff --git a/SourceCode/Bond/BondEq/AccordionWnd.h b/SourceCode/Bond/BondEq/AccordionWnd.h
new file mode 100644
index 0000000..5a674b2
--- /dev/null
+++ b/SourceCode/Bond/BondEq/AccordionWnd.h
@@ -0,0 +1,129 @@
+#pragma once
+#include <functional>
+#include <vector>
+
+#ifndef ACCORDIONWND_TAG
+
+#ifdef _WIN32
+
+#define ACCORDIONWND_CLASSA		"AccordionWnd"
+#define ACCORDIONWND_CLASSW		L"AccordionWnd"
+
+#ifdef UNICODE
+#define ACCORDIONWND_CLASS		ACCORDIONWND_CLASSW
+#else
+#define ACCORDIONWND_CLASS		ACCORDIONWND_CLASSA
+#endif
+
+#else
+#define ACCORDIONWND_CLASS      "AccordionWnd"
+#endif
+
+
+#define ACCORDIONWND_TAG		_T("ACCORDIONWND_TAG")
+
+#define ACCORDIONWND_FIRST		(0U-3590U)
+#define ACCORDIONWND_LAST		(0U-5350U)
+#define ACCORDIONWND_			(ACCORDIONWND_FIRST - 1)
+
+typedef struct tagACCORDION_NMHDR
+{
+	NMHDR		nmhdr;
+	DWORD		dwData;
+	DWORD		dwData1;
+	DWORD		dwData2;
+} ACCORDION_NMHDR;
+
+typedef struct tagACCORDIONITEM
+{
+	unsigned int id;
+	int nExpandHeight;
+	COLORREF crBackground[2];
+	COLORREF crFrame[2];
+	COLORREF crText[2];
+	char text[256];
+	CWnd *pWnd;
+	BOOL bExpand;
+	BOOL bEnable;				// 是否可以点击展开和收起
+} ACCORDIONITEM;
+
+#endif
+
+#define PADDING_LEFT		0
+#define PADDING_TOP			1
+#define PADDING_RIGHT		2
+#define PADDING_BOTTOM		3
+
+class CAccordionWnd
+{
+public:
+	CAccordionWnd();
+	~CAccordionWnd();
+
+
+public:
+	static BOOL RegisterWndClass();
+	static CAccordionWnd * FromHandle(HWND hWnd);
+	void SetFrameColor(COLORREF color, BOOL bShadow = FALSE);
+	void SetBkgndColor(COLORREF color);
+	void SetShadowBkgnd(COLORREF color);
+
+public:
+	void LoadExpandIcon(CString strExpandFile, CString strCloseFile);
+	void Setpadding(int type, unsigned int nPadding);
+	void SetDefaultItemBackgroundColor(COLORREF crNormal, COLORREF crSel);
+	void SetDefaultItemFrameColor(COLORREF crNormal, COLORREF crSel);
+	void SetDefaultItemTextColor(COLORREF crNormal, COLORREF crSel);
+	void AddItem(char *pszName, CWnd *pWnd, int nExpandHeight, BOOL bExpand = TRUE, BOOL bEnable = TRUE);
+	BOOL Togle(unsigned int nIndex);
+
+private:
+	void Init();
+	void Notify(int nCode, int dwData, int dwData1 = 0, int dwData2 = 0);
+	void Release();
+	void ResizeItemWnd();
+	static CAccordionWnd* Hook(HWND hWnd);
+	static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+	static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
+	LRESULT OnDestroy(WPARAM wParam, LPARAM lParam);
+	LRESULT OnTimer(WPARAM wParam, LPARAM lParam);
+	LRESULT OnNcPaint(WPARAM wParam, LPARAM lParam);
+	LRESULT OnNcCalcsize(WPARAM wParam, LPARAM lParam);
+	LRESULT OnPaint(WPARAM wParam, LPARAM lParam);
+	LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam);
+	LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
+	LRESULT OnLButtonUp(WPARAM wParam, LPARAM lParam);
+	LRESULT OnMouseWheel(WPARAM wParam, LPARAM lParam);
+	LRESULT OnSize(WPARAM wParam, LPARAM lParam);
+
+private:
+	HWND		m_hWnd;
+	COLORREF	m_crBkgnd;
+	COLORREF	m_crFrame;
+	HICON		m_hIconClose;
+	HICON		m_hIconExpand;
+	int			m_nHoverItem;
+	int			m_nCheckHoverItem;
+	BOOL		m_bShadow;				// 阴影
+	COLORREF	m_crShadowBkgnd;		// 阴影背景色(即父窗口的颜色)
+
+private:
+	unsigned int m_nPadding[4];
+	COLORREF m_crItemBackground[2];
+	COLORREF m_crItemFrame[2];
+	COLORREF m_crItemText[2];
+	COLORREF m_crSeparateLine;
+	COLORREF m_crHoverItemBackground;
+	COLORREF m_crHoverItemFrame;
+	CString m_strExpandIconFilepath[2];
+
+private:
+	std::vector<ACCORDIONITEM *> m_vectorItems;
+	int m_nTimerId;
+
+private:
+	int HitTest(POINT pt, int &nHitTest);
+	BOOL GetItemHeaderRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect);
+	BOOL GetItemRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect);
+};
+
diff --git a/SourceCode/Bond/BondEq/ApredTreeCtrl.cpp b/SourceCode/Bond/BondEq/ApredTreeCtrl.cpp
new file mode 100644
index 0000000..163b19e
--- /dev/null
+++ b/SourceCode/Bond/BondEq/ApredTreeCtrl.cpp
@@ -0,0 +1,466 @@
+#include "stdafx.h"
+#include "ApredTreeCtrl.h"
+
+
+#define ROFFSET 7
+#define WIDE	10
+#define WIDE2	5
+#define EXPANDED_WIDE	8
+
+#define BADGE_HIDE                  0
+#define BADGE_DOT                   1
+#define BADGE_NUMBER                2
+#define BADGE_DOT_WIDTH             12
+#define BADGE_NUMBER_WIDTH          20
+
+
+IMPLEMENT_DYNAMIC(CApredTreeCtrl, CTreeCtrl)
+
+CApredTreeCtrl::CApredTreeCtrl()
+{
+	m_hBrushItem[0] = NULL;
+	m_hBrushItem[1] = NULL;
+	m_hBrushItem[2] = NULL;
+	m_hPenItem[0] = nullptr;
+	m_hPenItem[1] = nullptr;
+	m_hPenItem[2] = nullptr;
+	m_hBrushBtn[0] = nullptr;
+	m_hBrushBtn[1] = nullptr;
+	m_hBrushBtn[2] = nullptr;
+	m_crItemBk[0] = RGB(255,255,255);
+	m_crItemBk[1] = RGB(228, 229, 234);
+	m_crItemBk[2] = RGB(236, 237, 241);
+	m_crText[0] = RGB(28, 28, 28);
+	m_crText[1] = RGB(28, 28, 28);
+	m_crText[2] = RGB(28, 28, 28);
+	m_hHoverItem = nullptr;
+	m_bTracking = FALSE;
+}
+
+CApredTreeCtrl::~CApredTreeCtrl()
+{
+	if (m_hBrushItem[0] != NULL) {
+		::DeleteObject(m_hBrushItem[0]);
+	}
+	if (m_hBrushItem[1] != NULL) {
+		::DeleteObject(m_hBrushItem[1]);
+	}
+	if (m_hBrushItem[2] != NULL) {
+		::DeleteObject(m_hBrushItem[2]);
+	}
+	if (m_hBrushBtn[0] != NULL) {
+		::DeleteObject(m_hBrushBtn[0]);
+	}
+	if (m_hBrushBtn[1] != NULL) {
+		::DeleteObject(m_hBrushBtn[1]);
+	}
+	if (m_hBrushBtn[2] != NULL) {
+		::DeleteObject(m_hBrushBtn[2]);
+	}
+	if (m_hPenItem[0] != nullptr) {
+		::DeleteObject(m_hPenItem[0]);
+	}
+	if (m_hPenItem[1] != nullptr) {
+		::DeleteObject(m_hPenItem[1]);
+	}
+	if (m_hPenItem[2] != nullptr) {
+		::DeleteObject(m_hPenItem[2]);
+	}
+}
+
+BEGIN_MESSAGE_MAP(CApredTreeCtrl, CTreeCtrl)
+	ON_WM_PAINT()
+	ON_WM_MOUSEMOVE()
+	ON_WM_MOUSEHOVER()
+	ON_WM_MOUSELEAVE()
+	ON_WM_TIMER()
+	ON_WM_LBUTTONDOWN()
+	ON_WM_CREATE()
+END_MESSAGE_MAP()
+
+void CApredTreeCtrl::DrawItemButton(HTREEITEM hItem, HDC hDC, CRect* pRect)
+{
+	// 按钮要刷一下
+	POINT pt[3];
+	if ((GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED) == TVIS_EXPANDED) {
+		int nBottomOffset = (pRect->Height() - EXPANDED_WIDE) / 2;
+		pt[0].x = pRect->right - ROFFSET - EXPANDED_WIDE;
+		pt[0].y = pRect->bottom - nBottomOffset;
+		pt[1].x = pRect->right - ROFFSET;
+		pt[1].y = pRect->bottom - nBottomOffset;
+		pt[2].x = pRect->right - ROFFSET;
+		pt[2].y = pRect->bottom - nBottomOffset - EXPANDED_WIDE;
+	}
+	else {
+		int nBottomOffset = (pRect->Height() - WIDE) / 2;
+		pt[0].x = pRect->right - ROFFSET - WIDE2;
+		pt[0].y = pRect->bottom - nBottomOffset - WIDE;
+		pt[1].x = pRect->right - ROFFSET - WIDE2;
+		pt[1].y = pRect->bottom - nBottomOffset;
+		pt[2].x = pRect->right - ROFFSET;
+		pt[2].y = pRect->bottom - nBottomOffset - WIDE2;
+	}
+
+	::Polygon(hDC, pt, 3);
+}
+
+void CApredTreeCtrl::OnPaint()
+{
+	HDC hDC, hMemDC;
+	HBITMAP hBitmap;
+	RECT rcClient;
+	CString strText;
+	HFONT hFont;
+	HBRUSH hBrushBK;
+
+
+	if (m_hBrushItem[0] == nullptr) {
+		m_hBrushItem[0] = CreateSolidBrush(m_crItemBk[0]);
+	}
+	if (m_hBrushItem[1] == nullptr) {
+		m_hBrushItem[1] = CreateSolidBrush(m_crItemBk[1]);
+	}
+	if (m_hBrushItem[2] == nullptr) {
+		m_hBrushItem[2] = CreateSolidBrush(m_crItemBk[2]);
+	}
+	if (m_hBrushBtn[0] == nullptr) {
+		m_hBrushBtn[0] = CreateSolidBrush(m_crText[0]);
+	}
+	if (m_hBrushBtn[1] == nullptr) {
+		m_hBrushBtn[1] = CreateSolidBrush(m_crText[1]);
+	}
+	if (m_hBrushBtn[2] == nullptr) {
+		m_hBrushBtn[2] = CreateSolidBrush(m_crText[2]);
+	}
+	if (m_hPenItem[0] == nullptr) {
+		m_hPenItem[0] = ::CreatePen(PS_SOLID, 1, m_crText[0]);
+	}
+	if (m_hPenItem[1] == nullptr) {
+		m_hPenItem[1] = ::CreatePen(PS_SOLID, 1, m_crText[1]);
+	}
+	if (m_hPenItem[2] == nullptr) {
+		m_hPenItem[2] = ::CreatePen(PS_SOLID, 1, m_crText[2]);
+	}
+
+	// BeginPaint
+	PAINTSTRUCT ps;
+	hDC = ::BeginPaint(m_hWnd, &ps);
+	GetClientRect(&rcClient);
+
+	hMemDC = ::CreateCompatibleDC(hDC);
+	hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left,
+		rcClient.bottom - rcClient.top);
+	::SelectObject(hMemDC, hBitmap);
+
+	hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+	::SelectObject(hMemDC, hFont);
+	::SetBkMode(hMemDC, TRANSPARENT);
+
+
+	// 背景颜色
+	hBrushBK = CreateSolidBrush(GetBkColor());
+	::FillRect(hMemDC, &rcClient, hBrushBK);
+	DeleteObject(hBrushBK);
+
+
+
+	// 绘制子项
+	DrawItems(hMemDC);
+
+
+	// EndPaint
+	::BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
+		hMemDC, 0, 0, SRCCOPY);
+	::EndPaint(m_hWnd, &ps);
+	::DeleteObject(hBitmap);
+	::DeleteDC(hMemDC);
+}
+
+void CApredTreeCtrl::DrawItems(HDC hDC)
+{
+	HTREEITEM hCurrentItem;
+	int      itemState;
+	CRect rcClient, rcItem, rcText;
+	GetClientRect(&rcClient);
+	Gdiplus::Graphics graphics(hDC);
+	graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+
+
+	// 绘制可见的子项
+	hCurrentItem = GetFirstVisibleItem();//获取第一个课可见的项  
+	do {
+		if (GetItemRect(hCurrentItem, &rcItem, FALSE) && GetItemRect(hCurrentItem, &rcText, TRUE)) {
+			rcText.right = rcItem.right - 8;
+			rcText.left += 8;
+			CRect fillRect(0, rcItem.top, rcClient.right, rcItem.bottom);
+			if (rcItem.top > rcClient.bottom) {
+				break;
+			}
+
+
+			// 绘制子项背景
+			itemState = GetItemState(hCurrentItem, TVIF_STATE);
+			COLORREF crText = m_crText[0];
+			if (itemState & TVIS_SELECTED) {
+				crText = m_crText[1];
+				HRGN hRgn = CreateRoundRectRgn(rcItem.left, rcItem.top, rcItem.right, rcItem.bottom, 4, 4);
+				::FillRgn(hDC, hRgn, m_hBrushItem[1]);
+				::DeleteObject(hRgn);
+				::SelectObject(hDC, m_hBrushBtn[1]);
+				::SelectObject(hDC, m_hPenItem[1]);
+			}
+			else if (hCurrentItem == m_hHoverItem) {
+				crText = m_crText[2];
+				HRGN hRgn = CreateRoundRectRgn(rcItem.left, rcItem.top, rcItem.right, rcItem.bottom, 4, 4);
+				::FillRgn(hDC, hRgn, m_hBrushItem[2]);
+				::DeleteObject(hRgn);
+				::SelectObject(hDC, m_hBrushBtn[2]);
+				::SelectObject(hDC, m_hPenItem[2]);
+			}
+			else {
+				crText = m_crText[0];
+				::SelectObject(hDC, m_hBrushBtn[0]);
+				::SelectObject(hDC, m_hPenItem[0]);
+			}
+
+
+			//绘制展开图片  
+			if (ItemHasChildren(hCurrentItem)) {
+				CRect rcBtn = rcText;
+				rcBtn.right = rcText.left - 2;
+				rcBtn.left -= rcBtn.right - 30;
+				DrawItemButton(hCurrentItem, hDC, &rcBtn);
+			}
+
+			// 图标
+			if (m_icons.find(hCurrentItem) != m_icons.end()) {
+				HICON hIcon = m_icons[hCurrentItem];
+				DrawIconEx(hDC, 8, (rcItem.bottom - rcItem.top - 32) / 2,
+					hIcon, 32, 32, 0, 0, DI_NORMAL);
+				rcText.left += 32;
+				rcText.left += 8;
+			}
+
+
+			//绘制文字  
+			HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+			::SelectObject(hDC, hFont);
+			LOGFONT lf;
+			::GetObject(hFont, sizeof(LOGFONT), &lf);
+			lf.lfWeight = FW_BOLD;
+			HFONT hFontBold = CreateFontIndirect(&lf);
+
+			::SetTextColor(hDC, crText);
+			CString strText = GetItemText(hCurrentItem);
+			if (FindBoldItem(hCurrentItem)) {
+				::SelectObject(hDC, hFontBold);
+			}
+			else {
+				::SelectObject(hDC, hFont);
+			}
+			DrawText(hDC, strText, strText.GetLength(), &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+			::DeleteObject(hFontBold);
+
+
+			// 是否有小圆点
+			if (m_badges.find(hCurrentItem) != m_badges.end()) {
+				BADGE& badge = m_badges[hCurrentItem];
+				if (badge.type == BADGE_DOT) {
+					Gdiplus::SolidBrush brush(Gdiplus::Color(GetRValue(badge.badgeBackground), GetGValue(badge.badgeBackground), GetBValue(badge.badgeBackground)));
+					int x = rcItem.right - 18 - BADGE_DOT_WIDTH;
+					int y = rcItem.top + (rcItem.Height() - BADGE_DOT_WIDTH) / 2;
+					graphics.FillEllipse(&brush, x, y, BADGE_DOT_WIDTH, BADGE_DOT_WIDTH);
+				}
+				else if (badge.type == BADGE_NUMBER) {
+					Gdiplus::SolidBrush brush(Gdiplus::Color(GetRValue(badge.badgeBackground), GetGValue(badge.badgeBackground), GetBValue(badge.badgeBackground)));
+					int x = rcItem.right - 18 - BADGE_NUMBER_WIDTH;
+					int y = rcItem.top + (rcItem.Height() - BADGE_NUMBER_WIDTH) / 2;
+					graphics.FillEllipse(&brush, x, y, BADGE_NUMBER_WIDTH, BADGE_NUMBER_WIDTH);
+					RECT rcBadge;
+					rcBadge.left = x;
+					rcBadge.right = rcBadge.left + BADGE_NUMBER_WIDTH;
+					rcBadge.top = y;
+					rcBadge.bottom = rcBadge.top + BADGE_NUMBER_WIDTH;
+					::SetTextColor(hDC, badge.badgeForeground);
+					char szBuffer[32];
+					sprintf_s(szBuffer, 32, "%d%s", min(badge.number, 9), badge.number > 9 ? "+" : "");
+					DrawText(hDC, szBuffer, (int)strlen(szBuffer), &rcBadge, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+				}
+			}
+		}
+	} while ((hCurrentItem = GetNextVisibleItem(hCurrentItem)) != NULL);
+}
+
+void CApredTreeCtrl::OnMouseMove(UINT nFlags, CPoint point)
+{
+	// 检测并记录热点项
+	HTREEITEM hHoverItem = HitTest(point);
+	if (m_hHoverItem != hHoverItem) {
+		m_hHoverItem = hHoverItem;
+		InvalidateRect(NULL);
+	}
+
+	if (!m_bTracking) {
+		TRACKMOUSEEVENT tme;
+		tme.cbSize = sizeof(tme);
+		tme.dwFlags = TME_HOVER | TME_LEAVE;		// 发送WM_MOUSEHOVER和WM_MOUSELEAVE 
+		tme.hwndTrack = m_hWnd;						// 指定要追踪的窗口 
+		tme.dwHoverTime = 10;						// 鼠标在按钮上停留超过10ms,才认为状态为HOVER 
+		m_bTracking = _TrackMouseEvent(&tme);		// 开启Windows的WM_MOUSELEAVEWM_MOUSEHOVER事件支持 
+	}
+
+	CTreeCtrl::OnMouseMove(nFlags, point);
+}
+
+void CApredTreeCtrl::OnTimer(UINT_PTR nIDEvent)
+{
+	if (1 == nIDEvent) {
+		BOOL bNeedInvalidate = FALSE;
+		for (auto& item : m_badges) {
+			if (item.second.showTime > 0) {
+				item.second.showTime--;
+				if (item.second.showTime == 0) {
+					item.second.type = BADGE_HIDE;
+					bNeedInvalidate = TRUE;
+				}
+			}
+		}
+		if(bNeedInvalidate)
+			InvalidateRect(NULL, TRUE);
+	}
+
+
+	CTreeCtrl::OnTimer(nIDEvent);
+}
+
+void CApredTreeCtrl::OnMouseHover(UINT nFlags, CPoint point)
+{
+
+}
+
+void CApredTreeCtrl::OnMouseLeave()
+{
+	m_hHoverItem = nullptr;
+	m_bTracking = FALSE;	// 若已经离开,则停止追踪 
+	InvalidateRect(NULL);
+
+	CTreeCtrl::OnMouseLeave();
+}
+
+void CApredTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point)
+{
+	HTREEITEM hItem = HitTest(point);
+	if (hItem != nullptr) {
+		SelectItem(hItem);
+		GetParent()->SendMessage(ID_MSG_TREE_CLICK_ITEM, (WPARAM)hItem, 0);
+	}
+
+	CTreeCtrl::OnLButtonDown(nFlags, point);
+}
+
+void CApredTreeCtrl::SetItemBadge(HTREEITEM hItem, COLORREF badgeBackground, COLORREF badgeForeground)
+{
+	if (m_badges.find(hItem) == m_badges.end()) {
+		BADGE badge;
+		badge.badgeBackground = badgeBackground;
+		badge.badgeForeground = badgeForeground;
+		badge.type = BADGE_HIDE;
+		badge.showTime = 0;
+		m_badges[hItem] = badge;
+	}
+	else {
+		BADGE& badge = m_badges[hItem];
+		badge.badgeBackground = badgeBackground;
+		badge.badgeForeground = badgeForeground;
+		badge.type = BADGE_HIDE;
+	}
+}
+
+void CApredTreeCtrl::ShowItemBadgeNumber(HTREEITEM hItem, int number)
+{
+	if (m_badges.find(hItem) == m_badges.end()) {
+		return;
+	}
+
+	BADGE& badge = m_badges[hItem];
+	badge.type = BADGE_NUMBER;
+	badge.number = number;
+	InvalidateRect(NULL, TRUE);
+}
+
+void CApredTreeCtrl::ShowItemBadgeDotMode(HTREEITEM hItem, int nSecond/* = 0*/)
+{
+	if (m_badges.find(hItem) == m_badges.end()) {
+		return;
+	}
+
+	BADGE& badge = m_badges[hItem];
+	if (badge.type != BADGE_DOT) {
+		badge.type = BADGE_DOT;
+		badge.showTime = nSecond;
+		InvalidateRect(NULL, TRUE);
+	}
+}
+
+void CApredTreeCtrl::HideItemBadge(HTREEITEM hItem)
+{
+	BADGE& badge = m_badges[hItem];
+	if (badge.type != BADGE_HIDE) {
+		badge.type = BADGE_HIDE;
+		badge.showTime = 0;
+		InvalidateRect(NULL, TRUE);
+	}
+}
+
+void CApredTreeCtrl::SetItemBold(HTREEITEM item)
+{
+	if (!FindBoldItem(item)) {
+		m_itemBolds.push_back(item);
+	}
+}
+
+void CApredTreeCtrl::CancelItemBold(HTREEITEM item)
+{
+	for (auto iter = m_itemBolds.begin(); iter != m_itemBolds.end(); iter++) {
+		if (*iter == item) {
+			m_itemBolds.erase(iter);
+			break;
+		}
+	}
+
+	InvalidateRect(NULL, TRUE);
+}
+
+BOOL CApredTreeCtrl::FindBoldItem(HTREEITEM item)
+{
+	BOOL bFound = FALSE;
+	for (auto i : m_itemBolds) {
+		if (i == item) return TRUE;
+	}
+
+	return FALSE;
+}
+
+
+int CApredTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+	if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
+		return -1;
+
+	SetTimer(1, 1000, nullptr);
+
+	return 0;
+}
+
+
+void CApredTreeCtrl::PreSubclassWindow()
+{
+	SetTimer(1, 1000, nullptr);
+
+	CTreeCtrl::PreSubclassWindow();
+}
+
+void CApredTreeCtrl::SetItemIcon(HTREEITEM hItem, HICON hIcon)
+{
+	m_icons[hItem] = hIcon;
+}
diff --git a/SourceCode/Bond/BondEq/ApredTreeCtrl.h b/SourceCode/Bond/BondEq/ApredTreeCtrl.h
new file mode 100644
index 0000000..17e5f0a
--- /dev/null
+++ b/SourceCode/Bond/BondEq/ApredTreeCtrl.h
@@ -0,0 +1,66 @@
+#pragma once
+#include <afxcmn.h>
+#include <map>
+#include <vector>
+
+#define ID_MSG_TREE_CLICK_ITEM      WM_USER+2080
+
+class CApredTreeCtrl :
+    public CTreeCtrl
+{
+public:
+    typedef struct tagBADGE
+    {
+        HTREEITEM hTreeItem;
+        COLORREF badgeBackground;
+        COLORREF badgeForeground;
+        int type;                       /* 0: 无,不显示*/
+        int number;
+		int showTime;					/* 显示时长,0:永远*/
+    } BADGE;
+
+    DECLARE_DYNAMIC(CApredTreeCtrl)
+
+public:
+    CApredTreeCtrl();
+    virtual ~CApredTreeCtrl();
+
+
+public:
+    void SetItemBadge(HTREEITEM hItem, COLORREF badgeBackground, COLORREF badgeForeground);
+    void ShowItemBadgeNumber(HTREEITEM hItem, int number);
+    void ShowItemBadgeDotMode(HTREEITEM hItem, int nSecond = 0);
+    void HideItemBadge(HTREEITEM hItem);
+    void SetItemBold(HTREEITEM item);
+    void CancelItemBold(HTREEITEM item);
+    BOOL FindBoldItem(HTREEITEM item);
+	void SetItemIcon(HTREEITEM hItem, HICON hIcon);
+
+private:
+    void DrawItemButton(HTREEITEM hItem, HDC hDC, CRect* pRect);
+    void DrawItems(HDC hDC);
+
+private:
+    std::map<HTREEITEM, BADGE> m_badges;
+	std::map<HTREEITEM, HICON> m_icons;
+    std::vector< HTREEITEM> m_itemBolds;
+    HBRUSH m_hBrushItem[3];
+    COLORREF m_crItemBk[3];
+    COLORREF m_crText[3];
+    HBRUSH m_hBrushBtn[3];
+    HPEN m_hPenItem[3];
+    HTREEITEM m_hHoverItem;
+    BOOL m_bTracking;		// 跟踪 
+
+public:
+    DECLARE_MESSAGE_MAP()
+    afx_msg void OnPaint();
+    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+    afx_msg void OnMouseHover(UINT nFlags, CPoint point);
+    afx_msg void OnMouseLeave();
+    afx_msg void OnTimer(UINT_PTR nIDEvent);
+    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+	virtual void PreSubclassWindow();
+};
+
diff --git a/SourceCode/Bond/BondEq/BaseSetPage.cpp b/SourceCode/Bond/BondEq/BaseSetPage.cpp
new file mode 100644
index 0000000..8a7d1a7
--- /dev/null
+++ b/SourceCode/Bond/BondEq/BaseSetPage.cpp
@@ -0,0 +1,55 @@
+#include "stdafx.h"
+#include "BaseSetPage.h"
+#include "Common.h"
+
+
+CBaseSetPage::CBaseSetPage(UINT nIDTemplate, CWnd *pParent)
+	: CDialogEx(nIDTemplate, pParent)
+{
+	m_crBkgnd = SETPAGE_BACKGROUND_COLOR;
+	m_hbrBkgnd = nullptr;
+}
+
+CBaseSetPage::~CBaseSetPage()
+{
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+}
+
+BEGIN_MESSAGE_MAP(CBaseSetPage, CDialogEx)
+	ON_WM_CTLCOLOR()
+	ON_WM_NCLBUTTONDOWN()
+	ON_WM_NCRBUTTONDOWN()
+END_MESSAGE_MAP()
+
+
+HBRUSH CBaseSetPage::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+	else if (nCtlColor == CTLCOLOR_EDIT || nCtlColor == CTLCOLOR_LISTBOX) {
+		pDC->SetBkColor(m_crBkgnd);
+		return m_hbrBkgnd;
+	}
+
+
+	return m_hbrBkgnd;
+}
+
+void CBaseSetPage::OnApply()
+{
+
+}
+
+void CBaseSetPage::OnModify()
+{
+	GetParent()->SendMessageA(ID_MSG_PAGE_MODIFY);
+}
diff --git a/SourceCode/Bond/BondEq/BaseSetPage.h b/SourceCode/Bond/BondEq/BaseSetPage.h
new file mode 100644
index 0000000..2aa260e
--- /dev/null
+++ b/SourceCode/Bond/BondEq/BaseSetPage.h
@@ -0,0 +1,26 @@
+#pragma once
+#include "afxdialogex.h"
+
+
+#define ID_MSG_PAGE_MODIFY		WM_USER + 1278
+
+class CBaseSetPage :
+	public CDialogEx
+{
+public:
+	CBaseSetPage(UINT nIDTemplate, CWnd *pParent = NULL);
+	~CBaseSetPage();
+
+public:
+	virtual void OnApply();
+	virtual void OnModify();
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+
+public:
+	DECLARE_MESSAGE_MAP()
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+};
+
diff --git a/SourceCode/Bond/BondEq/BlButton.cpp b/SourceCode/Bond/BondEq/BlButton.cpp
new file mode 100644
index 0000000..289e020
--- /dev/null
+++ b/SourceCode/Bond/BondEq/BlButton.cpp
@@ -0,0 +1,448 @@
+#include "stdafx.h"
+#include "BlButton.h"
+
+
+#define BADGE_HIDE                  0
+#define BADGE_DOT                   1
+#define BADGE_NUMBER                2
+#define BADGE_DOT_WIDTH             12
+#define BADGE_NUMBER_WIDTH          20
+
+CBlButton::CBlButton()
+{
+	m_nState = BS_NORMAL;
+	m_crFrame[BS_NORMAL] = RGB(225, 225, 225);
+	m_crFrame[BS_HOVER] = RGB(0, 120, 215);
+	m_crFrame[BS_PRESS] = RGB(0, 84, 153);
+	m_crFrame[BS_FOCUS] = RGB(0, 120, 215);
+	m_crFrame[BS_DISABLE] = RGB(191, 191, 191);
+	m_crBkgnd[BS_NORMAL] = RGB(225, 225, 225);
+	m_crBkgnd[BS_HOVER] = RGB(229, 241, 251);
+	m_crBkgnd[BS_PRESS] = RGB(204, 228, 247);
+	m_crBkgnd[BS_FOCUS] = RGB(225, 225, 225);
+	m_crBkgnd[BS_DISABLE] = RGB(204, 204, 204);
+	m_crText[BS_NORMAL] = RGB(0, 0, 0);
+	m_crText[BS_HOVER] = RGB(0, 0, 0);
+	m_crText[BS_PRESS] = RGB(0, 0, 0);
+	m_crText[BS_FOCUS] = RGB(0, 0, 0);
+	m_crText[BS_DISABLE] = RGB(131, 131, 131);
+	m_bHover = FALSE;
+	m_bSelected = FALSE;
+	m_bTracking = FALSE;
+	memset(&m_badge, 0, sizeof(BADGE));
+	m_nRoundWidth = 0;
+	m_hMenu = nullptr;
+	m_hIcon[0] = nullptr;
+	m_hIcon[1] = nullptr;
+	m_nIconWidth = 0;
+}
+
+
+CBlButton::~CBlButton()
+{
+}
+
+void CBlButton::SetFrameColor(int index, COLORREF color)
+{
+	if (BS_NORMAL <= index && index <= BS_DISABLE) {
+		m_crFrame[index] = color;
+	}
+}
+
+void CBlButton::SetRoundWidth(int width)
+{
+	m_nRoundWidth = width;
+}
+
+void CBlButton::SetBkgndColor(int index, COLORREF color)
+{
+	if (BS_NORMAL <= index && index <= BS_DISABLE) {
+		m_crBkgnd[index] = color;
+	}
+}
+
+void CBlButton::SetTextColor(int index, COLORREF color)
+{
+	if (BS_NORMAL <= index && index <= BS_DISABLE) {
+		m_crText[index] = color;
+	}
+}
+
+void CBlButton::SetFaceColor(COLORREF color)
+{
+	m_crBkgnd[BS_NORMAL] = color;
+	m_crBkgnd[BS_HOVER] = color;
+	m_crBkgnd[BS_PRESS] = color;
+	m_crBkgnd[BS_FOCUS] = color;
+	Invalidate();
+}
+
+void CBlButton::SetTextColor(COLORREF color)
+{
+	m_crText[BS_NORMAL] = color;
+	m_crText[BS_HOVER] = color;
+	m_crText[BS_PRESS] = color;
+	m_crText[BS_FOCUS] = color;
+	Invalidate();
+}
+
+void CBlButton::SetBadgeNumber(int number)
+{
+	m_badge.badgeBackground = RGB(255, 0, 0);
+	m_badge.badgeForeground = RGB(255, 255, 255);
+	m_badge.type = number > 0 ? BADGE_NUMBER : BADGE_HIDE;
+	m_badge.number = number;
+	Invalidate();
+}
+
+void CBlButton::ShowDotBadge(BOOL bShow, COLORREF color)
+{
+	m_badge.badgeBackground = color;
+	m_badge.type = bShow ? BADGE_DOT : BADGE_HIDE;
+	Invalidate();
+}
+
+void CBlButton::SetBkgndBmp(const char* pszBmpFile)
+{
+	m_strBkgndBmp = pszBmpFile;
+}
+
+void CBlButton::SetMenu(HMENU hMenu)
+{
+	m_hMenu = hMenu;
+}
+
+void CBlButton::SetCurrentMenuItem(UINT nPosition)
+{
+	char szTxt[256];
+	GetMenuString(::GetSubMenu(m_hMenu, 0), nPosition, szTxt, 256, MF_BYPOSITION);
+	SetWindowText(szTxt);
+}
+
+HMENU CBlButton::GetMenu()
+{
+	return m_hMenu;
+}
+
+void CBlButton::SetIcon(HICON hIcon, HICON hIconGray, int width)
+{
+	m_hIcon[0] = hIcon;
+	m_hIcon[1] = hIconGray;
+	m_nIconWidth = width;
+}
+
+void CBlButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
+{
+	HDC hDC = lpDrawItemStruct->hDC;
+	RECT rcClient;
+	GetClientRect(&rcClient);
+
+
+	// 边框+背景
+	int state = GetDrawState();
+	HBRUSH hBrush = CreateSolidBrush(m_crBkgnd[state]);
+	HPEN hPen = CreatePen(PS_SOLID, state == BS_FOCUS ? 2 : 1, m_crFrame[state]);
+	HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
+	HPEN hOldBrush = (HPEN)::SelectObject(hDC, hBrush);
+	::RoundRect(hDC, state == BS_FOCUS ? rcClient.left + 1 : rcClient.left,
+		state == BS_FOCUS ? rcClient.top + 1 : rcClient.top, rcClient.right,
+		rcClient.bottom, m_nRoundWidth, m_nRoundWidth);
+	::SelectObject(hDC, hOldPen);
+	::SelectObject(hDC, hOldBrush);
+	::DeleteObject(hBrush);
+	::DeleteObject(hPen);
+
+
+
+	// 贴图
+	CustomBitBlt(hDC, &rcClient, m_strBkgndBmp, state, 5, 2, 2, 2, 2, RGB(255,0,255));
+
+	// 获得文本 
+	char szText[64];
+	int nTextLen = GetWindowText(szText, 64);
+
+
+	// 图标
+	RECT rcText = rcClient;
+	if (m_hIcon != nullptr) {
+		int xIcon = (rcClient.right - rcClient.top - m_nIconWidth) / 2;
+		if (m_hMenu != nullptr) xIcon -= 10;
+		int yIcon = (rcClient.bottom - rcClient.top - m_nIconWidth) / 2;
+		if (nTextLen != 0) {
+			yIcon -= 8;
+		}
+
+		DrawIconEx(hDC, xIcon, yIcon,
+			this->IsWindowEnabled() ? m_hIcon[0] : m_hIcon[01], m_nIconWidth, m_nIconWidth, 0, 0, DI_NORMAL);
+		rcText.top = yIcon + m_nIconWidth + 2;
+	}
+
+
+	// 文本
+	HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+
+	::SelectObject(hDC, hFont);
+	::SetBkMode(hDC, TRANSPARENT);
+	::SetTextColor(hDC, m_crText[state]);
+
+	if ((BS_MULTILINE & GetStyle()) == BS_MULTILINE) {
+		CRect rcBound;
+		int height = DrawTextA(hDC, szText, (int)strlen(szText), &rcBound,  DT_CENTER | DT_CALCRECT | DT_EDITCONTROL);
+		rcText.top = rcBound.top + (rcClient.bottom - rcClient.top - height) / 2;
+		rcText.bottom = rcText.top + height;
+		DrawTextA(hDC, szText, (int)strlen(szText), &rcText,  DT_CENTER | DT_EDITCONTROL);
+	}
+	else {
+		if (m_hMenu != nullptr) {
+			rcText.right -= (10);
+		}
+		DrawTextA(hDC, szText, (int)strlen(szText), &rcText, DT_VCENTER | DT_CENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
+	}
+
+
+	// 是否有小圆点
+	if (m_badge.type == BADGE_DOT) {
+		Gdiplus::Graphics graphics(hDC);
+		graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+		Gdiplus::SolidBrush brush(Gdiplus::Color(GetRValue(m_badge.badgeBackground), GetGValue(m_badge.badgeBackground), GetBValue(m_badge.badgeBackground)));
+		int x = rcClient.right - 8 - BADGE_DOT_WIDTH;
+		int y = rcClient.top + 8;
+		graphics.FillEllipse(&brush, x, y, BADGE_DOT_WIDTH, BADGE_DOT_WIDTH);
+	}
+	else if (m_badge.type == BADGE_NUMBER) {
+		Gdiplus::Graphics graphics(hDC);
+		graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+		Gdiplus::SolidBrush brush(Gdiplus::Color(GetRValue(m_badge.badgeBackground), GetGValue(m_badge.badgeBackground), GetBValue(m_badge.badgeBackground)));
+		int x = rcClient.right - 8 - BADGE_NUMBER_WIDTH;
+		int y = rcClient.top + 8;
+		graphics.FillEllipse(&brush, x, y, BADGE_NUMBER_WIDTH, BADGE_NUMBER_WIDTH);
+		RECT rcBadge;
+		rcBadge.left = x;
+		rcBadge.right = rcBadge.left + BADGE_NUMBER_WIDTH;
+		rcBadge.top = y;
+		rcBadge.bottom = rcBadge.top + BADGE_NUMBER_WIDTH;
+		::SetTextColor(hDC, m_badge.badgeForeground);
+		char szBuffer[32];
+		sprintf_s(szBuffer, 32, "%d%s", min(m_badge.number, 9), m_badge.number > 9 ? "+" : "");
+		DrawText(hDC, szBuffer, (int)strlen(szBuffer), &rcBadge, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+	}
+
+
+	// 菜单项小三角
+	if (m_hMenu != nullptr) {
+		HPEN hPenDrop = CreatePen(PS_SOLID, 1, m_crText[state]);
+		HBRUSH hbrDrop = CreateSolidBrush(m_crText[state]);
+		HBRUSH hOldBrush = (HBRUSH)::SelectObject(hDC, hbrDrop);
+		HPEN hOldPen = (HPEN)::SelectObject(hDC, hPenDrop);
+		POINT pt[3];
+		pt[0].x = rcClient.right - 20;
+		pt[0].y = rcClient.top + (rcClient.bottom - rcClient.top - 5) / 2;
+		pt[1].x = pt[0].x + 10;
+		pt[1].y = pt[0].y;
+		pt[2].x = pt[0].x + (pt[1].x - pt[0].x) / 2;
+		pt[2].y = pt[0].y + 5;
+		::Polygon(hDC, pt, 3);
+		::SelectObject(hDC, hOldBrush);
+		::SelectObject(hDC, hOldPen);
+		::DeleteObject(hBrush);
+		::DeleteObject(hPen);
+	}
+}
+
+int CBlButton::GetDrawState()
+{
+	if (!IsWindowEnabled()) {
+		return BS_DISABLE;
+	}
+
+	//if (GetFocus() == this) {
+	//	return BS_FOCUS;
+	//}
+
+	return m_nState;
+}
+
+void CBlButton::PreSubclassWindow()
+{
+	m_bHover = false;
+	m_bSelected = false;
+	m_bTracking = FALSE;
+	ModifyStyle(0, BS_OWNERDRAW);
+
+	CButton::PreSubclassWindow();
+}
+
+BEGIN_MESSAGE_MAP(CBlButton, CButton)
+	ON_WM_MOUSEMOVE()
+	ON_WM_MOUSEHOVER()
+	ON_WM_MOUSELEAVE()
+	ON_WM_LBUTTONDOWN()
+	ON_CONTROL_REFLECT_EX(BN_CLICKED, &CBlButton::OnBnClicked)
+	ON_WM_LBUTTONUP()
+END_MESSAGE_MAP()
+
+
+void CBlButton::OnMouseMove(UINT nFlags, CPoint point)
+{
+	if (!m_bTracking)
+	{
+		TRACKMOUSEEVENT tme;
+		tme.cbSize = sizeof(tme);
+		tme.dwFlags = TME_HOVER | TME_LEAVE;		// 发送WM_MOUSEHOVER和WM_MOUSELEAVE 
+		tme.hwndTrack = m_hWnd;						// 指定要追踪的窗口 
+		tme.dwHoverTime = 10;						// 鼠标在按钮上停留超过10ms,才认为状态为HOVER 
+		m_bTracking = _TrackMouseEvent(&tme);		// 开启Windows的WM_MOUSELEAVEWM_MOUSEHOVER事件支持 
+	}
+
+	CButton::OnMouseMove(nFlags, point);
+}
+
+
+void CBlButton::OnMouseHover(UINT nFlags, CPoint point)
+{
+	m_bHover = true;
+	m_nState = BS_HOVER;
+	InvalidateRect(NULL);
+
+	return;
+
+	// CButton::OnMouseHover(nFlags, point);
+}
+
+
+void CBlButton::OnMouseLeave()
+{
+	m_bHover = false;
+	m_bTracking = FALSE;	// 若已经离开,则停止追踪 
+	m_nState = BS_NORMAL;
+	InvalidateRect(NULL);
+
+	CButton::OnMouseLeave();
+}
+
+BOOL CBlButton::CustomBitBlt(HDC hDC, LPRECT lprc, CString& strBkgndBmp, int nFrame, int nAllFrame,
+	int nB0, int nB1, int nB2, int nB3, COLORREF crTransparent)
+{
+	// 载入BMP
+	HBITMAP hBmpTemp = (HBITMAP)LoadImage(AfxGetInstanceHandle(),
+		strBkgndBmp, IMAGE_BITMAP, 0, 0,
+		LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE);
+	if (hBmpTemp == NULL)
+		return FALSE;
+
+	HDC hDCTemp = ::CreateCompatibleDC(hDC);
+	::SelectObject(hDCTemp, hBmpTemp);
+	BITMAP bitmap;
+	::GetObject(hBmpTemp, sizeof(BITMAP), &bitmap);
+
+	int nFrameWidth = bitmap.bmWidth / nAllFrame;		// 每帧的宽
+	int nFrameX = nFrameWidth*nFrame;				// 指定帧相素起点
+
+
+													// 如果角或边厚为0
+	if (nB0 == 0 && nB1 == 0 &&
+		nB2 == 0 && nB3 == 0) {
+		::TransparentBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
+			hDCTemp, nFrameX, 0, nFrameWidth, bitmap.bmHeight, crTransparent);
+
+		::DeleteObject(hBmpTemp);
+		::DeleteDC(hDCTemp);
+		return TRUE;
+	}
+
+
+	// 其它
+	int x = lprc->left + nB3;
+	int y = lprc->top + nB0;
+	::TransparentBlt(hDC, x, y, lprc->right - lprc->left - (nB1 + nB3), lprc->bottom - lprc->top - (nB0 + nB2),
+		hDCTemp, nFrameX + nB3, nB0, nFrameWidth - (nB1 + nB3), bitmap.bmHeight - (nB0 + nB2), crTransparent);
+
+	x = lprc->left;
+	y = lprc->top;
+	::TransparentBlt(hDC, x, y, nB3, nB0,
+		hDCTemp, nFrameX + 0, 0, nB3, nB0, crTransparent);
+
+	x += nB3;
+	y = lprc->top;
+	::TransparentBlt(hDC, x, y, lprc->right - lprc->left - (nB1 + nB3), nB0,
+		hDCTemp, nFrameX + nB3, 0, nFrameWidth - (nB1 + nB3), nB0, crTransparent);
+
+	x = lprc->right - nB1;
+	y = lprc->top;
+	::TransparentBlt(hDC, x, y, nB1, nB0,
+		hDCTemp, nFrameX + nFrameWidth - nB1, 0, nB1, nB0, crTransparent);
+
+	x = lprc->right - nB1;
+	y = lprc->top + nB0;
+	::TransparentBlt(hDC, x, y, nB1, lprc->bottom - lprc->top - (nB0 + nB2),
+		hDCTemp, nFrameX + nFrameWidth - nB1, nB0, nB1, bitmap.bmHeight - (nB0 + nB2), crTransparent);
+
+	x = lprc->right - nB1;
+	y = lprc->bottom - nB2;
+	::TransparentBlt(hDC, x, y, nB1, nB2,
+		hDCTemp, nFrameX + nFrameWidth - nB1, bitmap.bmHeight - nB2, nB1, nB2, crTransparent);
+
+	x = lprc->left + nB3;
+	y = lprc->bottom - nB2;
+	::TransparentBlt(hDC, x, y, lprc->right - lprc->left - (nB1 + nB3), nB2,
+		hDCTemp, nFrameX + nB3, bitmap.bmHeight - nB2, nFrameWidth - (nB1 + nB3), nB2, crTransparent);
+
+	x = lprc->left;
+	y = lprc->bottom - nB2;
+	::TransparentBlt(hDC, x, y, nB3, nB2,
+		hDCTemp, nFrameX + 0, bitmap.bmHeight - nB2, nB3, nB2, crTransparent);
+
+	x = lprc->left;
+	y = lprc->top + nB0;
+	::TransparentBlt(hDC, x, y, nB3, lprc->bottom - lprc->top - (nB0 + nB2),
+		hDCTemp, nFrameX + 0, nB0, nB3, bitmap.bmHeight - (nB0 + nB2), crTransparent);
+
+
+	::DeleteObject(hBmpTemp);
+	::DeleteDC(hDCTemp);
+	return TRUE;
+}
+
+void CBlButton::OnLButtonDown(UINT nFlags, CPoint point)
+{
+	m_nState = BS_PRESS;
+	CButton::OnLButtonDown(nFlags, point);
+}
+
+void CBlButton::OnLButtonUp(UINT nFlags, CPoint point)
+{
+	m_nState = BS_HOVER;
+	CButton::OnLButtonUp(nFlags, point);
+}
+
+BOOL CBlButton::OnBnClicked()
+{
+	if (m_hMenu != NULL) {
+		RECT rect;
+		GetWindowRect(&rect);
+		int cmd = ::TrackPopupMenu(::GetSubMenu(m_hMenu, 0),
+			TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, rect.left, rect.bottom, 0, m_hWnd, NULL);
+		if (cmd > 0) {
+			int position = cmd - GetMenuItemID(::GetSubMenu(m_hMenu, 0), 0);
+			Notify((int)BLBUTTON_MENU_ITEM_CLICKED, position);
+		}
+	}
+
+	return FALSE;
+}
+
+void CBlButton::Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1/* = 0*/, DWORD_PTR dwData2/* = 0*/)
+{
+	CWnd* pParent;
+	pParent = GetParent();
+	if (pParent != nullptr) {
+		BLBUTTON_NMHDR blbNmhdr;
+		blbNmhdr.nmhdr.code = nCode;
+		blbNmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
+		blbNmhdr.nmhdr.hwndFrom = m_hWnd;
+		blbNmhdr.dwData = dwData;
+		blbNmhdr.dwData1 = dwData1;
+		blbNmhdr.dwData2 = dwData2;
+		pParent->SendMessage(WM_NOTIFY, (WPARAM)blbNmhdr.nmhdr.idFrom, (LPARAM)&blbNmhdr);
+	}
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/BlButton.h b/SourceCode/Bond/BondEq/BlButton.h
new file mode 100644
index 0000000..4415a8b
--- /dev/null
+++ b/SourceCode/Bond/BondEq/BlButton.h
@@ -0,0 +1,88 @@
+#pragma once
+#include "afxwin.h"
+
+#define BS_NORMAL		0
+#define BS_HOVER		1
+#define BS_PRESS		2
+#define BS_FOCUS		3
+#define BS_DISABLE		4
+
+#define BLBUTTON_MENU_ITEM_CLICKED		0x1345
+
+typedef struct tagBLBUTTON_NMHDR
+{
+	NMHDR		nmhdr;
+	DWORD_PTR	dwData;
+	DWORD_PTR	dwData1;
+	DWORD_PTR	dwData2;
+} BLBUTTON_NMHDR;
+
+class CBlButton :
+	public CButton
+{
+private:
+	typedef struct tagBADGE
+	{
+		COLORREF badgeBackground;
+		COLORREF badgeForeground;
+		int type;                       /* 0: 无,不显示*/
+		int number;
+	} BADGE;
+
+public:
+	CBlButton();
+	~CBlButton();
+
+
+public:
+	void SetRoundWidth(int width);
+	int GetDrawState();
+	void SetFrameColor(int index, COLORREF color);
+	void SetBkgndColor(int index, COLORREF color);
+	void SetTextColor(int index, COLORREF color);
+	void SetBkgndBmp(const char* pszBmpFile);
+	void SetFaceColor(COLORREF color);
+	void SetTextColor(COLORREF color);
+	void SetBadgeNumber(int number);
+	void ShowDotBadge(BOOL bShow, COLORREF color);
+	void SetMenu(HMENU hMenu);
+	void SetCurrentMenuItem(UINT nPosition);
+	HMENU GetMenu();
+	void SetIcon(HICON hIcon, HICON hIconGray, int width);
+
+private:
+	BOOL CustomBitBlt(HDC hDC, LPRECT lprc, CString& strBkgndBmp, int nFrame, int nAllFrame,
+		int nB0, int nB1, int nB2, int nB3, COLORREF crTransparent);
+	void CBlButton::Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1 = 0, DWORD_PTR dwData2 = 0);
+
+private:
+	bool m_bHover;			// 悬停 
+	bool m_bSelected;		// 按下 
+	BOOL m_bTracking;		// 跟踪 
+	int m_nState;
+	int m_nRoundWidth;
+
+private:
+	COLORREF m_crFrame[5];	// 边框颜色
+	COLORREF m_crBkgnd[5];	// 背景颜色
+	COLORREF m_crText[5];	// 文本颜色
+	CString m_strBkgndBmp;
+
+private:
+	BADGE m_badge;
+	HMENU m_hMenu;
+	HICON m_hIcon[2];
+	int m_nIconWidth;
+
+public:
+	virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
+	virtual void PreSubclassWindow();
+	DECLARE_MESSAGE_MAP()
+	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+	afx_msg void OnMouseHover(UINT nFlags, CPoint point);
+	afx_msg void OnMouseLeave();
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg BOOL OnBnClicked();
+	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+};
+
diff --git a/SourceCode/Bond/BondEq/BondEq.vcxproj b/SourceCode/Bond/BondEq/BondEq.vcxproj
new file mode 100644
index 0000000..f0c25f0
--- /dev/null
+++ b/SourceCode/Bond/BondEq/BondEq.vcxproj
@@ -0,0 +1,290 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{7864134E-C538-4C0F-AF24-215FFCCBBAB4}</ProjectGuid>
+    <RootNamespace>BondServo</RootNamespace>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+    <Keyword>MFCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <AdditionalIncludeDirectories>.;.\View;.\DBManager;..\DatabaseSDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="AccordionWnd.h" />
+    <ClInclude Include="ApredTreeCtrl.h" />
+    <ClInclude Include="BaseSetPage.h" />
+    <ClInclude Include="BlButton.h" />
+    <ClInclude Include="BondServo.h" />
+    <ClInclude Include="BondServoDlg.h" />
+    <ClInclude Include="CBaseView.h" />
+    <ClInclude Include="CRemoteEqUnitView.h" />
+    <ClInclude Include="CRemoteEqView.h" />
+    <ClInclude Include="CHomeDialog.h" />
+    <ClInclude Include="CMainContainer.h" />
+    <ClInclude Include="CPageLogcat.h" />
+    <ClInclude Include="CProjectPageRemoteEqs.h" />
+    <ClInclude Include="Common.h" />
+    <ClInclude Include="Configuration.h" />
+    <ClInclude Include="CPanelProject.h" />
+    <ClInclude Include="DBManager\UserManager.h" />
+    <ClInclude Include="HmTab.h" />
+    <ClInclude Include="HmVerticalTab.h" />
+    <ClInclude Include="HorizontalLine.h" />
+    <ClInclude Include="Log.h" />
+    <ClInclude Include="LogEdit.h" />
+    <ClInclude Include="Model.h" />
+    <ClInclude Include="CPageAlarm.h" />
+    <ClInclude Include="Resource.h" />
+    <ClInclude Include="Servo.h" />
+    <ClInclude Include="SetPage1.h" />
+    <ClInclude Include="SetPage2.h" />
+    <ClInclude Include="SettingsDlg.h" />
+    <ClInclude Include="stdafx.h" />
+    <ClInclude Include="targetver.h" />
+    <ClInclude Include="ToolUnits.h" />
+    <ClInclude Include="TopToolbar.h" />
+    <ClInclude Include="VerticalLine.h" />
+    <ClInclude Include="View\ChangePasswordDlg.h" />
+    <ClInclude Include="View\LoginDlg.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="AccordionWnd.cpp" />
+    <ClCompile Include="ApredTreeCtrl.cpp" />
+    <ClCompile Include="BaseSetPage.cpp" />
+    <ClCompile Include="BlButton.cpp" />
+    <ClCompile Include="BondServo.cpp" />
+    <ClCompile Include="BondServoDlg.cpp" />
+    <ClCompile Include="CBaseView.cpp" />
+    <ClCompile Include="CRemoteEqUnitView.cpp" />
+    <ClCompile Include="CRemoteEqView.cpp" />
+    <ClCompile Include="CHomeDialog.cpp" />
+    <ClCompile Include="CMainContainer.cpp" />
+    <ClCompile Include="CPageLogcat.cpp" />
+    <ClCompile Include="CProjectPageRemoteEqs.cpp" />
+    <ClCompile Include="Configuration.cpp" />
+    <ClCompile Include="CPanelProject.cpp" />
+    <ClCompile Include="DBManager\UserManager.cpp" />
+    <ClCompile Include="HmTab.cpp" />
+    <ClCompile Include="HmVerticalTab.cpp" />
+    <ClCompile Include="HorizontalLine.cpp" />
+    <ClCompile Include="Log.cpp" />
+    <ClCompile Include="LogEdit.cpp" />
+    <ClCompile Include="Model.cpp" />
+    <ClCompile Include="CPageAlarm.cpp" />
+    <ClCompile Include="Servo.cpp" />
+    <ClCompile Include="SetPage1.cpp" />
+    <ClCompile Include="SetPage2.cpp" />
+    <ClCompile Include="SettingsDlg.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="ToolUnits.cpp" />
+    <ClCompile Include="TopToolbar.cpp" />
+    <ClCompile Include="VerticalLine.cpp" />
+    <ClCompile Include="View\ChangePasswordDlg.cpp" />
+    <ClCompile Include="View\LoginDlg.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="BondServo.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\BondServo.rc2" />
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\BondServo.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <Manifest Include="res\application.exe.manifest" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+  <ProjectExtensions>
+    <VisualStudio>
+      <UserProperties RESOURCE_FILE="BondServo.rc" />
+    </VisualStudio>
+  </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/BondSEq.vcxproj.filters b/SourceCode/Bond/BondEq/BondSEq.vcxproj.filters
new file mode 100644
index 0000000..77b314d
--- /dev/null
+++ b/SourceCode/Bond/BondEq/BondSEq.vcxproj.filters
@@ -0,0 +1,255 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="婧愭枃浠�">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="澶存枃浠�">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="璧勬簮鏂囦欢">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+    <Filter Include="DBManager">
+      <UniqueIdentifier>{223a97a4-3935-4383-b097-ccae2f176660}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="View">
+      <UniqueIdentifier>{ac8ea0ef-ae05-4436-9d51-4cc145e4c1b0}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="BondServo.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="BondServoDlg.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="stdafx.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Resource.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Model.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Log.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="ToolUnits.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Common.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Configuration.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Servo.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="AccordionWnd.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="HorizontalLine.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="VerticalLine.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="CPanelProject.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="ApredTreeCtrl.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="CProjectPageRemoteEqs.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="CMainContainer.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="CHomeDialog.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="HmTab.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="CPageLogcat.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="CBaseView.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="BlButton.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="LogEdit.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="HmVerticalTab.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="SettingsDlg.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="SetPage1.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="SetPage2.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="BaseSetPage.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="CRemoteEqView.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="CPageAlarm.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="TopToolbar.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="CRemoteEqUnitView.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="DBManager\UserManager.h">
+      <Filter>DBManager</Filter>
+    </ClInclude>
+    <ClInclude Include="View\LoginDlg.h">
+      <Filter>View</Filter>
+    </ClInclude>
+    <ClInclude Include="View\ChangePasswordDlg.h">
+      <Filter>View</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="BondServo.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="BondServoDlg.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="Model.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="Log.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="ToolUnits.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="Configuration.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="Servo.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="AccordionWnd.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="HorizontalLine.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="VerticalLine.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="CPanelProject.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="ApredTreeCtrl.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="CProjectPageRemoteEqs.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="CMainContainer.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="CHomeDialog.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="HmTab.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="CPageLogcat.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="CBaseView.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="BlButton.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="LogEdit.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="HmVerticalTab.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="SettingsDlg.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="SetPage1.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="SetPage2.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="BaseSetPage.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="CRemoteEqView.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="CPageAlarm.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="TopToolbar.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="CRemoteEqUnitView.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="DBManager\UserManager.cpp">
+      <Filter>DBManager</Filter>
+    </ClCompile>
+    <ClCompile Include="View\LoginDlg.cpp">
+      <Filter>View</Filter>
+    </ClCompile>
+    <ClCompile Include="View\ChangePasswordDlg.cpp">
+      <Filter>View</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="BondServo.rc">
+      <Filter>璧勬簮鏂囦欢</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\BondServo.rc2">
+      <Filter>璧勬簮鏂囦欢</Filter>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\BondServo.ico">
+      <Filter>璧勬簮鏂囦欢</Filter>
+    </Image>
+  </ItemGroup>
+  <ItemGroup>
+    <Manifest Include="res\application.exe.manifest" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/BondServo.cpp b/SourceCode/Bond/BondEq/BondServo.cpp
new file mode 100644
index 0000000..8de4719
--- /dev/null
+++ b/SourceCode/Bond/BondEq/BondServo.cpp
@@ -0,0 +1,148 @@
+
+// BondServo.cpp : 定义应用程序的类行为。
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "BondServoDlg.h"
+#include "AccordionWnd.h"
+#include "VerticalLine.h"
+#include "HorizontalLine.h"
+#include "HmTab.h"
+#include "HmVerticalTab.h"
+
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CBondServoApp
+
+BEGIN_MESSAGE_MAP(CBondServoApp, CWinApp)
+	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CBondServoApp 构造
+
+CBondServoApp::CBondServoApp()
+{
+	// 支持重新启动管理器
+	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
+
+	// TODO: 在此处添加构造代码,
+	// 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的一个 CBondServoApp 对象
+
+CBondServoApp theApp;
+
+
+// CBondServoApp 初始化
+
+BOOL CBondServoApp::InitInstance()
+{
+	// 如果一个运行在 Windows XP 上的应用程序清单指定要
+	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
+	//则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
+	INITCOMMONCONTROLSEX InitCtrls;
+	InitCtrls.dwSize = sizeof(InitCtrls);
+	// 将它设置为包括所有要在应用程序中使用的
+	// 公共控件类。
+	InitCtrls.dwICC = ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&InitCtrls);
+
+	CWinApp::InitInstance();
+
+
+	AfxEnableControlContainer();
+
+	// 创建 shell 管理器,以防对话框包含
+	// 任何 shell 树视图控件或 shell 列表视图控件。
+	CShellManager *pShellManager = new CShellManager;
+
+	// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
+	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
+
+	// 标准初始化
+	// 如果未使用这些功能并希望减小
+	// 最终可执行文件的大小,则应移除下列
+	// 不需要的特定初始化例程
+	// 更改用于存储设置的注册表项
+	// TODO: 应适当修改该字符串,
+	// 例如修改为公司或组织名
+	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
+
+
+	// 本程序文件目录
+	TCHAR sDrive[_MAX_DRIVE];
+	TCHAR sDir[_MAX_DIR];
+	TCHAR sFilename[_MAX_FNAME], sAppFilename[_MAX_FNAME];
+	TCHAR sExt[_MAX_EXT];
+	GetModuleFileName(AfxGetInstanceHandle(), sAppFilename, _MAX_FNAME);
+	_tsplitpath_s(sAppFilename, sDrive, sDir, sFilename, sExt);
+	m_strAppDir = CString(sDrive) + CString(sDir);
+	m_strAppFile = CString(sFilename);
+	m_model.setWorkDir((LPTSTR)(LPCTSTR)m_strAppDir);
+
+
+	m_hAppMutex = CreateMutexA(NULL, FALSE, _T("BondServoApp"));
+	if (GetLastError() == ERROR_ALREADY_EXISTS) {
+		AfxMessageBox(_T("已经运行了一个实例,启动失败!"));
+		return FALSE;
+	}
+
+
+	// 初始化BEQ库
+	BEQ_Initialize();
+	RX_Init();
+
+
+	// 自定义组件
+	CAccordionWnd::RegisterWndClass();
+	CVerticalLine::RegisterWndClass();
+	CHorizontalLine::RegisterWndClass();
+	CHmTab::RegisterWndClass();
+	CHmVerticalTab::RegisterWndClass();
+
+
+	CBondServoDlg dlg;
+	m_pMainWnd = &dlg;
+	INT_PTR nResponse = dlg.DoModal();
+	if (nResponse == IDOK)
+	{
+		// TODO: 在此放置处理何时用
+		//  “确定”来关闭对话框的代码
+	}
+	else if (nResponse == IDCANCEL)
+	{
+		// TODO: 在此放置处理何时用
+		//  “取消”来关闭对话框的代码
+	}
+	else if (nResponse == -1)
+	{
+		TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
+		TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
+	}
+
+	// 删除上面创建的 shell 管理器。
+	if (pShellManager != NULL)
+	{
+		delete pShellManager;
+	}
+
+	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
+	//  而不是启动应用程序的消息泵。
+	return FALSE;
+}
+
+int CBondServoApp::ExitInstance()
+{
+	BEQ_Term();
+	RX_Term();
+
+	return CWinApp::ExitInstance();
+}
diff --git a/SourceCode/Bond/BondEq/BondServo.h b/SourceCode/Bond/BondEq/BondServo.h
new file mode 100644
index 0000000..f7fe86c
--- /dev/null
+++ b/SourceCode/Bond/BondEq/BondServo.h
@@ -0,0 +1,44 @@
+
+// BondServo.h : PROJECT_NAME 应用程序的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
+#endif
+
+#include "resource.h"		// 主符号
+#include "Model.h"
+
+
+// CBondServoApp: 
+// 有关此类的实现,请参阅 BondServo.cpp
+//
+
+class CBondServoApp : public CWinApp
+{
+public:
+	CBondServoApp();
+
+// 重写
+public:
+	virtual BOOL InitInstance();
+
+
+public:
+	CModel m_model;
+	HANDLE m_hAppMutex;
+	CString m_strAppDir;
+	CString m_strAppFile;
+	int m_nVersionNumber;
+	CString m_strVersionName;
+
+
+// 实现
+
+	DECLARE_MESSAGE_MAP()
+	virtual int ExitInstance();
+};
+
+extern CBondServoApp theApp;
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/BondServo.rc b/SourceCode/Bond/BondEq/BondServo.rc
new file mode 100644
index 0000000..66da5d2
--- /dev/null
+++ b/SourceCode/Bond/BondEq/BondServo.rc
Binary files differ
diff --git a/SourceCode/Bond/BondEq/BondServoDlg.cpp b/SourceCode/Bond/BondEq/BondServoDlg.cpp
new file mode 100644
index 0000000..240b7e3
--- /dev/null
+++ b/SourceCode/Bond/BondEq/BondServoDlg.cpp
@@ -0,0 +1,627 @@
+
+// BondServoDlg.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "BondServoDlg.h"
+#include "afxdialogex.h"
+#include "Common.h"
+#include "Servo.h"
+#include "SettingsDlg.h"
+#include "UserManager.h"
+#include "LoginDlg.h"
+
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
+
+class CAboutDlg : public CDialogEx
+{
+public:
+	CAboutDlg();
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_ABOUTBOX };
+#endif
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+// 实现
+protected:
+	DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+
+// CBondServoDlg 对话框
+
+
+
+CBondServoDlg::CBondServoDlg(CWnd* pParent /*=NULL*/)
+	: CDialogEx(IDD_BONDSERVO_DIALOG, pParent)
+{
+	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+	m_pObserver = nullptr;
+	m_pPanelProject = nullptr;
+	m_crBkgnd = APPDLG_BACKGROUND_COLOR;
+	m_hbrBkgnd = nullptr;
+	m_pTopToolbar = nullptr;
+	m_pMainContainer = nullptr;
+	m_pHomeDialog = nullptr;
+	m_pActiveView = nullptr;
+}
+
+void CBondServoDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CBondServoDlg, CDialogEx)
+	ON_WM_SYSCOMMAND()
+	ON_WM_PAINT()
+	ON_WM_QUERYDRAGICON()
+	ON_WM_CLOSE()
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_WM_SIZE()
+	ON_COMMAND(ID_MENU_FILE_EXIT, &CBondServoDlg::OnMenuFileExit)
+	ON_UPDATE_COMMAND_UI(ID_MENU_FILE_EXIT, &CBondServoDlg::OnUpdateMenuFileExit)
+	ON_COMMAND(ID_MENU_FILE_SETTINGS, &CBondServoDlg::OnMenuFileSettings)
+	ON_UPDATE_COMMAND_UI(ID_MENU_FILE_SETTINGS, &CBondServoDlg::OnUpdateMenuFileSettings)
+	ON_COMMAND(ID_MENU_HELP_ABOUT, &CBondServoDlg::OnMenuHelpAbout)
+	ON_WM_INITMENUPOPUP()
+	ON_MESSAGE(ID_MSG_VIEW_ACTIVE, &CBondServoDlg::OnViewActive)
+	ON_MESSAGE(ID_MSG_BTN_CLICKED, &CBondServoDlg::OnViewBtnClicked)
+	ON_MESSAGE(ID_MSG_BTN_MENU_ITEM, &CBondServoDlg::OnViewBtnMenuItem)
+	ON_MESSAGE(ID_MSG_TOOLBAR_BTN_CLICKED, &CBondServoDlg::OnToolbarBtnClicked)
+	ON_WM_TIMER()
+END_MESSAGE_MAP()
+
+
+// CBondServoDlg 消息处理程序
+
+void CBondServoDlg::InitRxWindows()
+{
+	/* code */
+	// 订阅数据
+	IRxWindows* pRxWindows = RX_GetRxWindows();
+	pRxWindows->enableLog(5);
+	if (m_pObserver == NULL) {
+		m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void {
+			// onNext
+			pAny->addRef();
+			int code = pAny->getCode();
+			if (RX_CODE_SELECT_EQ == code) {
+				BEQ::IRemoteEquipment* pEquipment;
+				if (pAny->getPtrValue("ptr", (void*&)pEquipment)) {
+					if (m_pMainContainer != nullptr) {
+						if (m_pActiveView != nullptr) {
+							if (m_pActiveView->GetContext() != (void*)pEquipment) {
+								m_pActiveView->DestroyWindow();
+								delete m_pActiveView;
+								m_pActiveView = nullptr;
+							}
+						}
+
+						if (m_pActiveView == nullptr) {
+							m_pActiveView = CreateRemoteEqView(pEquipment);
+						}
+					}
+				}
+			}
+
+			pAny->release();
+		}, [&]() -> void {
+			// onComplete
+		}, [&](IThrowable* pThrowable) -> void {
+			// onErrorm
+			pThrowable->printf();
+		});
+
+		theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
+			->subscribe(m_pObserver);
+	}
+}
+
+BOOL CBondServoDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// 将“关于...”菜单项添加到系统菜单中。
+
+	// IDM_ABOUTBOX 必须在系统命令范围内。
+	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+	ASSERT(IDM_ABOUTBOX < 0xF000);
+
+	CMenu* pSysMenu = GetSystemMenu(FALSE);
+	if (pSysMenu != NULL)
+	{
+		BOOL bNameValid;
+		CString strAboutMenu;
+		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
+		ASSERT(bNameValid);
+		if (!strAboutMenu.IsEmpty())
+		{
+			pSysMenu->AppendMenu(MF_SEPARATOR);
+			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+		}
+	}
+
+	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
+	//  执行此操作
+	SetIcon(m_hIcon, TRUE);			// 设置大图标
+	SetIcon(m_hIcon, FALSE);		// 设置小图标
+
+
+	// 初始化用户管理
+	UserManager& userManager = UserManager::getInstance();
+#if !defined(_DEBUG)
+	userManager.initializeIdleDetection(AfxGetMainWnd()->m_hWnd);
+	SetTimer(1, 60000, nullptr);
+#endif
+	userManager.loadSession();
+
+
+	// 菜单
+	CMenu menu;
+	menu.LoadMenu(IDR_MENU_APP);
+	SetMenu(&menu);
+
+
+	// model init
+	theApp.m_model.init();
+
+
+	// toolbar
+	m_pTopToolbar = new CTopToolbar();
+	m_pTopToolbar->Create(IDD_TOP_TOOLBAR, this);
+	m_pTopToolbar->ShowWindow(SW_SHOW);
+	m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE);
+
+
+	// 设备面板
+	m_pPanelProject = new CPanelProject();
+	m_pPanelProject->Create(IDD_PANEL_PROJECT, this);
+	m_pPanelProject->ShowWindow(SW_SHOW);
+
+
+	// 主窗口页
+	m_pMainContainer = new CMainContainer();
+	m_pMainContainer->Create(IDD_MAIN_CONTAINER, this);
+	m_pMainContainer->ShowWindow(SW_SHOW);
+
+
+	// Home页
+	m_pHomeDialog = CreateHomeDlg();
+	ShowWindow(SW_SHOWMAXIMIZED);
+	SetTimer(2, 1000, nullptr);
+
+
+	InitRxWindows();
+
+
+	// 登录管理
+	if (userManager.isLoggedIn()) {
+		m_pTopToolbar->SetOperatorBtnText(userManager.getCurrentUser().c_str());
+	}
+
+
+	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
+}
+
+void CBondServoDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+	{
+		CAboutDlg dlgAbout;
+		dlgAbout.DoModal();
+	}
+	else
+	{
+		CDialogEx::OnSysCommand(nID, lParam);
+	}
+}
+
+// 如果向对话框添加最小化按钮,则需要下面的代码
+//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
+//  这将由框架自动完成。
+
+void CBondServoDlg::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 CBondServoDlg::OnQueryDragIcon()
+{
+	return static_cast<HCURSOR>(m_hIcon);
+}
+
+void CBondServoDlg::OnClose()
+{
+	// TODO: 在此添加消息处理程序代码和/或调用默认值
+	CServo& servo = theApp.m_model.getServo();
+	if (servo.isRunning()) {
+		AfxMessageBox("程序和机器正在运行中,请先停止工作再退出程序!");
+		return;
+	}
+	
+
+	CDialogEx::OnClose();
+}
+
+HBRUSH CBondServoDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	// TODO:  在此更改 DC 的任何特性
+
+	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
+	return hbr;
+}
+
+void CBondServoDlg::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+	if (m_pTopToolbar != nullptr) {
+		m_pTopToolbar->DestroyWindow();
+		delete m_pTopToolbar;
+		m_pTopToolbar = nullptr;
+	}
+
+	if (m_pPanelProject != nullptr) {
+		m_pPanelProject->DestroyWindow();
+		delete m_pPanelProject;
+		m_pPanelProject = nullptr;
+	}
+
+	if (m_pMainContainer != nullptr) {
+		m_pMainContainer->DestroyWindow();
+		delete m_pMainContainer;
+		m_pMainContainer = nullptr;
+	}
+
+	if (m_pHomeDialog != nullptr) {
+		m_pHomeDialog->DestroyWindow();
+		delete m_pHomeDialog;
+		m_pHomeDialog = nullptr;
+	}
+
+	if (m_pActiveView != nullptr) {
+		m_pActiveView->DestroyWindow();
+		delete m_pActiveView;
+		m_pActiveView = nullptr;
+	}
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+
+	ASSERT(m_pObserver != NULL);
+	m_pObserver->unsubscribe();
+	m_pObserver = NULL;
+
+#if !defined(_DEBUG)
+	// 清除 UserManager 的无操作检测
+	UserManager::getInstance().terminateIdleDetection();
+	KillTimer(1);
+#endif
+}
+
+void CBondServoDlg::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+	if (m_pPanelProject == nullptr) return;
+
+	Resize();
+}
+
+#define TOOLBAR_HEIGHT		78
+void CBondServoDlg::Resize()
+{
+	CRect rcClient, rcItem;
+	GetClientRect(&rcClient);
+
+	int y = 0;
+	m_pTopToolbar->MoveWindow(0, 0, rcClient.Width(), TOOLBAR_HEIGHT);
+	y += TOOLBAR_HEIGHT;
+
+	ASSERT(m_pPanelProject);
+	int nPanelEquipmentWidth = m_pPanelProject->GetPanelWidth();
+	m_pPanelProject->MoveWindow(0, y, nPanelEquipmentWidth, rcClient.bottom - y);
+
+	int x = nPanelEquipmentWidth;
+	m_pMainContainer->MoveWindow(x + 1, y, rcClient.Width() - x - 0, rcClient.bottom - y - 2);
+}
+
+void CBondServoDlg::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
+{
+	ASSERT(pPopupMenu != NULL);
+
+	CCmdUI state;
+	state.m_pMenu = pPopupMenu;
+	ASSERT(state.m_pOther == NULL);
+	ASSERT(state.m_pParentMenu == NULL);
+
+	HMENU hParentMenu;
+	if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu)
+		state.m_pParentMenu = pPopupMenu;
+	else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL)
+	{
+		CWnd* pParent = this;
+		if (pParent != NULL &&
+			(hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
+		{
+			int nIndexMax = ::GetMenuItemCount(hParentMenu);
+			for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
+			{
+				if (::GetSubMenu(hParentMenu, nIndex) == pPopupMenu->m_hMenu)
+				{
+					state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
+					break;
+				}
+			}
+		}
+	}
+
+	state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
+	for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
+	state.m_nIndex++)
+	{
+		state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
+		if (state.m_nID == 0)
+			continue;
+
+		ASSERT(state.m_pOther == NULL);
+		ASSERT(state.m_pMenu != NULL);
+		if (state.m_nID == (UINT)-1)
+		{
+			state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);
+			if (state.m_pSubMenu == NULL ||
+				(state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
+				state.m_nID == (UINT)-1)
+			{
+				continue;
+			}
+			state.DoUpdate(this, TRUE);
+		}
+		else
+		{
+			state.m_pSubMenu = NULL;
+			state.DoUpdate(this, FALSE);
+		}
+
+		UINT nCount = pPopupMenu->GetMenuItemCount();
+		if (nCount < state.m_nIndexMax)
+		{
+			state.m_nIndex -= (state.m_nIndexMax - nCount);
+			while (state.m_nIndex < nCount &&
+				pPopupMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
+			{
+				state.m_nIndex++;
+			}
+		}
+		state.m_nIndexMax = nCount;
+	}
+}
+
+void CBondServoDlg::OnMenuFileSettings()
+{
+	CSettingsDlg dlg;
+	dlg.DoModal();
+}
+
+void CBondServoDlg::OnUpdateMenuFileSettings(CCmdUI* pCmdUI)
+{
+	pCmdUI->Enable(!theApp.m_model.getServo().isRunning());
+}
+
+void CBondServoDlg::OnMenuFileExit()
+{
+	PostMessage(WM_CLOSE);
+}
+
+void CBondServoDlg::OnUpdateMenuFileExit(CCmdUI* pCmdUI)
+{
+	pCmdUI->Enable(!theApp.m_model.getServo().isRunning());
+}
+
+void CBondServoDlg::OnMenuHelpAbout()
+{
+	CAboutDlg dlgAbout;
+	dlgAbout.DoModal();
+}
+
+BOOL CBondServoDlg::PreTranslateMessage(MSG* pMsg)
+{
+	if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE) {
+		return TRUE;
+	}
+
+	return CDialogEx::PreTranslateMessage(pMsg);
+}
+
+LRESULT CBondServoDlg::OnViewActive(WPARAM wParam, LPARAM lParam)
+{
+	CBaseView* pView = (CBaseView*)wParam;
+	int code = (int)lParam;
+	if (code == MA_ACTIVATE || code == MA_ACTIVATEANDEAT) {
+
+	}
+
+
+	return 0;
+}
+
+LRESULT CBondServoDlg::OnViewBtnClicked(WPARAM wParam, LPARAM lParam)
+{
+	int id = (int)lParam;
+	if (id == VIEW_TOOL_BTN_CLOSE) {
+		CloseView((CBaseView*)wParam);
+	}
+
+	return 0;
+}
+
+LRESULT CBondServoDlg::OnToolbarBtnClicked(WPARAM wParam, LPARAM lParam)
+{
+	int id = (int)lParam;
+	if (id == IDC_BUTTON_RUN) {
+		m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
+		m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(TRUE);
+	}
+	else if (id == IDC_BUTTON_STOP) {
+		m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE);
+		m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE);
+	}
+	else if (id == IDC_BUTTON_SETTINGS) {
+		CSettingsDlg dlg;
+		dlg.DoModal();
+	}
+	else if (id == IDC_BUTTON_OPERATOR) {
+		int menuId = (int)wParam;
+		UserManager& userManager = UserManager::getInstance();
+		if (menuId == 0) {
+			ShowLoginDlg();
+		}
+		else if (1 == menuId) {
+			if (userManager.isLoggedIn()) {
+				userManager.logout();
+			}
+
+			ShowLoginDlg();
+		}
+		else if (2 == menuId) {
+			if (userManager.isLoggedIn()) {
+				userManager.logout();
+				m_pTopToolbar->SetOperatorBtnText(_T("未登录"));
+			}
+		}
+	}
+
+	return 0;
+}
+
+LRESULT CBondServoDlg::OnViewBtnMenuItem(WPARAM wParam, LPARAM lParam)
+{
+	UINT id = (UINT)lParam;
+
+	return 0;
+}
+
+void CBondServoDlg::CloseView(CBaseView* pView)
+{
+	pView->DestroyWindow();
+	delete (CBaseView*)pView;
+	m_pActiveView = nullptr;
+	m_pMainContainer->Resize();
+}
+
+CHomeDialog* CBondServoDlg::CreateHomeDlg()
+{
+	CHomeDialog* pDlg = new CHomeDialog(m_pMainContainer);
+	pDlg->Create(IDD_DIALOG_HOME, m_pMainContainer);
+	::SetProp(pDlg->GetSafeHwnd(), _T("Home"), (HANDLE)(void*)1);
+	m_pMainContainer->Resize();
+
+	return pDlg;
+}
+
+void CBondServoDlg::OnTimer(UINT_PTR nIDEvent)
+{
+	if (1 == nIDEvent) {
+		UserManager& userManager = UserManager::getInstance();
+		if (userManager.isLoggedIn()) {
+			if (userManager.isInactiveTimeout()) {
+				AfxMessageBox(_T("You have been logged out automatically due to a long period of no action."));
+				userManager.logout();
+			}
+		}
+	}
+	else if (2 == nIDEvent) {
+		KillTimer(2);
+		theApp.m_model.createRemoteEqs();
+	}
+
+	CDialogEx::OnTimer(nIDEvent);
+}
+
+CBaseView* CBondServoDlg::CreateRemoteEqView(BEQ::IRemoteEquipment* pEquipment)
+{
+	CBaseView* pDlg = new CRemoteEqView(m_pMainContainer);
+	pDlg->Create(IDD_COMPONENT_REMOTE_EQ, m_pMainContainer);
+	pDlg->SetContext(pEquipment);
+
+	CString strIcon0, strIcon1, strIcon2, strIcon3;
+	strIcon0.Format(_T("%s\\Res\\small_close0.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir);
+	strIcon1.Format(_T("%s\\Res\\small_close1.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir);
+	strIcon2.Format(_T("%s\\Res\\small_close2.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir);
+	strIcon3.Format(_T("%s\\Res\\small_close3.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir);
+	pDlg->AddToolBtn(VIEW_TOOL_BTN_CLOSE,
+		(LPTSTR)(LPCTSTR)strIcon0,
+		(LPTSTR)(LPCTSTR)strIcon1,
+		(LPTSTR)(LPCTSTR)strIcon2,
+		(LPTSTR)(LPCTSTR)strIcon3, "关闭");
+	pDlg->ShowWindow(SW_SHOW);
+	char szName[256];
+	pEquipment->getName(szName, 256);
+	pDlg->SetWindowText(szName);
+	m_pMainContainer->Resize();
+
+	return pDlg;
+}
+
+void CBondServoDlg::ShowLoginDlg()
+{
+	CLoginDlg loginDlg;
+	loginDlg.DoModal();
+
+	UserManager& userManager = UserManager::getInstance();
+	if (userManager.isLoggedIn())
+	{
+		m_pTopToolbar->SetOperatorBtnText(userManager.getCurrentUser().c_str());
+	}
+	else {
+		m_pTopToolbar->SetOperatorBtnText(_T("未登录"));
+	}
+}
diff --git a/SourceCode/Bond/BondEq/BondServoDlg.h b/SourceCode/Bond/BondEq/BondServoDlg.h
new file mode 100644
index 0000000..bb472a7
--- /dev/null
+++ b/SourceCode/Bond/BondEq/BondServoDlg.h
@@ -0,0 +1,76 @@
+
+// BondServoDlg.h : 头文件
+//
+
+#pragma once
+#include "CPanelProject.h"
+#include "CMainContainer.h"
+#include "CHomeDialog.h"
+#include "CBaseView.h"
+#include "CRemoteEqView.h"
+#include "TopToolbar.h"
+
+
+// CBondServoDlg 对话框
+class CBondServoDlg : public CDialogEx
+{
+// 构造
+public:
+	CBondServoDlg(CWnd* pParent = NULL);	// 标准构造函数
+
+private:
+	void InitRxWindows();
+	void Resize();
+	void CloseView(CBaseView* pView);
+	CHomeDialog* CreateHomeDlg();
+	CBaseView* CreateRemoteEqView(BEQ::IRemoteEquipment* pEquipment);
+	void ShowLoginDlg();
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+	IObserver* m_pObserver;
+	CTopToolbar* m_pTopToolbar;
+	CMainContainer* m_pMainContainer;
+	CPanelProject* m_pPanelProject;
+	CHomeDialog* m_pHomeDialog;
+	CBaseView* m_pActiveView;
+
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_BONDSERVO_DIALOG };
+#endif
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
+
+
+// 实现
+protected:
+	HICON m_hIcon;
+
+	// 生成的消息映射函数
+	virtual BOOL OnInitDialog();
+	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+	afx_msg void OnPaint();
+	afx_msg HCURSOR OnQueryDragIcon();
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnClose();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
+	afx_msg void OnMenuFileSettings();
+	afx_msg void OnUpdateMenuFileSettings(CCmdUI* pCmdUI);
+	afx_msg void OnMenuFileExit();
+	afx_msg void OnUpdateMenuFileExit(CCmdUI* pCmdUI);
+	afx_msg void OnMenuHelpAbout();
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	LRESULT OnViewActive(WPARAM wParam, LPARAM lParam);
+	LRESULT OnViewBtnClicked(WPARAM wParam, LPARAM lParam);
+	LRESULT OnViewBtnMenuItem(WPARAM wParam, LPARAM lParam);
+	LRESULT OnToolbarBtnClicked(WPARAM wParam, LPARAM lParam);
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+};
diff --git a/SourceCode/Bond/BondEq/CBaseView.cpp b/SourceCode/Bond/BondEq/CBaseView.cpp
new file mode 100644
index 0000000..0484c89
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CBaseView.cpp
@@ -0,0 +1,415 @@
+#include "stdafx.h"
+#include "CBaseView.h"
+#include "Common.h"
+
+
+#define CAPTION_HEIGHT		36
+#define CAPBTN				99
+
+
+IMPLEMENT_DYNAMIC(CBaseView, CDialogEx)
+
+CBaseView::CBaseView(UINT id, CWnd* pPage) : CDialogEx(id, pPage)
+{
+	m_crBkgnd = BASE_VIEW_BACKGROUND;
+	m_hbrBkgnd = nullptr;
+	m_pContext = nullptr;
+	m_nState = 0;
+	m_pHotBtn = nullptr;
+	m_pPressBtn = nullptr;
+}
+
+CBaseView::~CBaseView()
+{
+}
+
+BEGIN_MESSAGE_MAP(CBaseView, CDialogEx)
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_WM_ACTIVATE()
+	ON_WM_NCPAINT()
+	ON_WM_MOUSEACTIVATE()
+	ON_WM_SIZE()
+	ON_WM_NCCALCSIZE()
+	ON_WM_LBUTTONDOWN()
+	ON_WM_NCHITTEST()
+	ON_WM_NCMOUSEMOVE()
+	ON_WM_NCLBUTTONDOWN()
+	ON_WM_NCLBUTTONUP()
+END_MESSAGE_MAP()
+
+HBRUSH CBaseView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+
+void CBaseView::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+}
+
+void CBaseView::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
+{
+	CDialogEx::OnActivate(nState, pWndOther, bMinimized);
+
+	if (WA_INACTIVE == nState) {
+		OnApply();
+	}
+}
+
+void CBaseView::OnNcPaint()
+{
+	// TODO: 在此处添加消息处理程序代码
+	// 不为绘图消息调用 CDialogEx::OnNcPaint()
+
+
+	RECT rect, rcClient;
+	::GetClientRect(m_hWnd, &rcClient);
+	::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.left);
+	::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.right);
+	::GetWindowRect(m_hWnd, &rect);
+	::OffsetRect(&rcClient, -rect.left, -rect.top);
+
+	rect.right -= rect.left;
+	rect.bottom -= rect.top;
+	rect.left = 0;
+	rect.top = 0;
+
+	HRGN hRgnWnd = CreateRectRgnIndirect(&rect);
+	HRGN hRgnClient = CreateRectRgnIndirect(&rcClient);
+
+	HBRUSH hBrushBK, hBrushFrame;
+	HDC hDC = ::GetWindowDC(m_hWnd);
+	::SelectClipRgn(hDC, hRgnWnd);
+	::ExtSelectClipRgn(hDC, hRgnClient, RGN_DIFF);
+
+
+	// 背景
+	hBrushBK = CreateSolidBrush(m_crBkgnd);
+	::FillRect(hDC, &rect, hBrushBK);
+	DeleteObject(hBrushBK);
+
+
+	// 标题栏,文字,横线
+	HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+	::SelectObject(hDC, hFont);
+
+	RECT rcCaption, rcText;
+	rcCaption = rect;
+	rcCaption.bottom = rcCaption.top + CAPTION_HEIGHT;
+	rcText = rcCaption;
+	rcText.left += 12;
+	char szCaption[64];
+	int nCaptionLen = GetWindowText(szCaption, 64);
+	::DrawText(hDC, szCaption, nCaptionLen, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
+
+
+	HPEN hPen = CreatePen(PS_SOLID, 1, RGB(222, 222, 222));
+	HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);
+	::MoveToEx(hDC, 0, rcCaption.bottom, NULL);
+	::LineTo(hDC, rect.right, rcCaption.bottom);
+	::SelectObject(hDC, hOldPen);
+	::DeleteObject(hPen);
+
+
+	// 绘制按钮
+	int y = (rcCaption.bottom - rcCaption.top - 24) / 2;
+	int x = rcCaption.right - 12;
+	for (auto& item : m_toolbtns) {
+		if (item.hIcon != nullptr) {
+			if (!item.bEnable) {
+				DrawIconEx(hDC, x - 24, y,
+					item.hIcon[3], 24, 24, 0, 0, DI_NORMAL);
+			}
+			else if (m_pPressBtn == &item) {
+				DrawIconEx(hDC, x - 24, y,
+					item.hIcon[2], 24, 24, 0, 0, DI_NORMAL);
+			}
+			else if (m_pHotBtn == &item) {
+				DrawIconEx(hDC, x - 24, y,
+					item.hIcon[1], 24, 24, 0, 0, DI_NORMAL);
+			}
+			else {
+				DrawIconEx(hDC, x - 24, y,
+					item.hIcon[0], 24, 24, 0, 0, DI_NORMAL);
+			}
+			x -= 24;
+			x -= 3;
+		}
+	}
+
+
+
+	hBrushFrame = CreateSolidBrush(RGB(255, 0, 0));
+	// ::FrameRect(hDC, &rect, hBrushFrame);
+
+	::DeleteObject(hRgnWnd);
+	::DeleteObject(hRgnClient);
+	DeleteObject(hBrushFrame);
+	::ReleaseDC(m_hWnd, hDC);
+}
+
+int CBaseView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
+{
+	// TODO: 在此添加消息处理程序代码和/或调用默认值
+	int nRet = CDialogEx::OnMouseActivate(pDesktopWnd, nHitTest, message);
+	GetParent()->GetParent()->SendMessage(ID_MSG_VIEW_ACTIVE, (WPARAM)this, nRet);
+	return nRet;
+}
+
+void CBaseView::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
+{
+	lpncsp->rgrc[0].top += (CAPTION_HEIGHT);
+	CDialogEx::OnNcCalcSize(bCalcValidRects, lpncsp);
+}
+
+void CBaseView::SetContext(void* pContext)
+{
+	m_pContext = pContext;
+}
+
+void* CBaseView::GetContext()
+{
+	return m_pContext;
+}
+
+void CBaseView::OnApply()
+{
+
+}
+
+void CBaseView::Show(CWnd* pParent, LPRECT lprcBtn)
+{
+	RECT rcClient, rcBox;
+	pParent->GetClientRect(&rcClient);
+	pParent->ClientToScreen(&rcClient);
+	GetWindowRect(&rcBox);
+
+	int x = lprcBtn->left;
+	if (x + (rcBox.right - rcBox.left) > rcClient.right) {
+		x = rcClient.right - (rcBox.right - rcBox.left);
+	}
+	SetWindowPos(NULL, x, lprcBtn->bottom + 2, 0, 0, SWP_NOSIZE);
+	ShowWindow(SW_SHOW);
+}
+
+void CBaseView::OnViewActive()
+{
+	m_nState = 1;
+	SendMessage(WM_NCPAINT, 0, 0);
+}
+
+void CBaseView::OnViewInactive()
+{
+	m_nState = 0;
+	SendMessage(WM_NCPAINT, 0, 0);
+}
+
+void CBaseView::AddToolBtn(int id, const char* pszIcon0Path, const char* pszIcon1Path, const char* pszIcon2Path, const char* pszIcon3Path, const char* pszTooltip)
+{
+	TOOLBTN tb;
+	memset(&tb, 0, sizeof(TOOLBTN));
+	tb.id = id;
+	tb.hIcon[0] = (HICON)::LoadImage(GetModuleHandle(NULL), pszIcon0Path, IMAGE_ICON, 24, 24,
+		LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+	tb.hIcon[1] = (HICON)::LoadImage(GetModuleHandle(NULL), pszIcon1Path, IMAGE_ICON, 24, 24,
+		LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+	tb.hIcon[2] = (HICON)::LoadImage(GetModuleHandle(NULL), pszIcon2Path, IMAGE_ICON, 24, 24,
+		LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+	tb.hIcon[3] = (HICON)::LoadImage(GetModuleHandle(NULL), pszIcon3Path, IMAGE_ICON, 24, 24,
+		LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+	strcpy_s(tb.szTooltip, 256, pszTooltip);
+	tb.bEnable = TRUE;
+	m_toolbtns.push_back(tb);
+
+	EnableToolTips(TRUE);
+}
+
+void CBaseView::SetToolBtnEnable(int id, BOOL bEnable)
+{
+	CBaseView::TOOLBTN* pBtn = GetToolBtn(id);
+	if (pBtn != nullptr) {
+		pBtn->bEnable = bEnable;
+		SendMessage(WM_NCPAINT);
+	}
+}
+
+void CBaseView::SetToolBtnMenu(int id, HMENU hMenu)
+{
+	CBaseView::TOOLBTN* pBtn = GetToolBtn(id);
+	if (pBtn != nullptr) {
+		pBtn->hMenu = hMenu;
+	}
+}
+
+void CBaseView::OnLButtonDown(UINT nFlags, CPoint point)
+{
+	// TODO: 在此添加消息处理程序代码和/或调用默认值
+
+	CDialogEx::OnLButtonDown(nFlags, point);
+}
+
+
+LRESULT CBaseView::OnNcHitTest(CPoint point)
+{
+	TOOLBTN* pBtn;
+	LRESULT hit = MyHitTest(point, pBtn);
+	if (hit == HTCAPTION || hit == CAPBTN) {
+		return hit;
+	}
+
+	return CDialogEx::OnNcHitTest(point);
+}
+
+void CBaseView::OnNcMouseMove(UINT nHitTest, CPoint point)
+{
+	TOOLBTN* pLastHot = m_pHotBtn;
+	int code = MyHitTest(point, m_pHotBtn);
+	if (pLastHot != m_pHotBtn) {
+		SendMessage(WM_NCPAINT, 0, 0);
+	}
+
+
+	CDialogEx::OnNcMouseMove(nHitTest, point);
+}
+
+void CBaseView::OnNcLButtonDown(UINT nHitTest, CPoint point)
+{
+	int code = MyHitTest(point, m_pPressBtn);
+	SendMessage(WM_NCPAINT, 0, 0);
+	GetParent()->GetParent()->SendMessage(ID_MSG_VIEW_ACTIVE, (WPARAM)this, MA_ACTIVATE);
+
+	CDialogEx::OnNcLButtonDown(nHitTest, point);
+}
+
+void CBaseView::OnNcLButtonUp(UINT nHitTest, CPoint point)
+{
+	MyHitTest(point, m_pHotBtn);
+	if (m_pPressBtn == m_pHotBtn && m_pPressBtn != nullptr && m_pPressBtn->bEnable) {
+		if (m_pPressBtn->hMenu != nullptr) {
+			int cmd = ::TrackPopupMenu(::GetSubMenu(m_pPressBtn->hMenu, 0),
+				TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
+				point.x, point.y + 2, 0, m_hWnd, NULL);
+			GetParent()->GetParent()->PostMessage(ID_MSG_BTN_MENU_ITEM, (WPARAM)this, cmd);
+		}
+		else {
+			GetParent()->GetParent()->PostMessage(ID_MSG_BTN_CLICKED, (WPARAM)this, m_pPressBtn->id);
+		}
+	}
+	m_pPressBtn = nullptr;
+
+	SendMessage(WM_NCPAINT, 0, 0);
+
+
+	CDialogEx::OnNcLButtonUp(nHitTest, point);
+}
+
+int CBaseView::MyHitTest(POINT& point, TOOLBTN*& pBtn)
+{
+	RECT rcWnd, rcCaption;
+	GetWindowRect(&rcWnd);
+	LRESULT hit = HTNOWHERE;
+	pBtn = nullptr;
+
+	rcCaption.left = rcWnd.left + 2;
+	rcCaption.right = rcWnd.right - 2;
+	rcCaption.top = rcWnd.top += 2;
+	rcCaption.bottom = rcCaption.top + 2 + CAPTION_HEIGHT;
+	if (::PtInRect(&rcCaption, point)) {
+		hit = HTCAPTION;
+
+		RECT rcIcon;
+		rcIcon.top = rcCaption.top + (rcCaption.bottom - rcCaption.top - 24) / 2;
+		rcIcon.bottom = rcIcon.top + 24;
+		rcIcon.right = rcCaption.right - 12;
+		for (auto& item : m_toolbtns) {
+			rcIcon.left = rcIcon.right - 24;
+			if (::PtInRect(&rcIcon, point)) {
+				pBtn = &item;
+				hit = CAPBTN;
+				break;
+			}
+			rcIcon.right = rcIcon.left - 3;
+		}
+	}
+
+	return (int)hit;
+}
+
+CBaseView::TOOLBTN* CBaseView::GetToolBtn(int id)
+{
+	for (auto& item : m_toolbtns) {
+		if (item.id == id) return &item;
+	}
+
+	return nullptr;
+}
+
+BOOL CBaseView::GetBtnRect(int id, LPRECT lprcBtn)
+{
+	RECT rcWnd, rcCaption;
+	GetWindowRect(&rcWnd);
+	::OffsetRect(&rcWnd, -rcWnd.left, -rcWnd.top);
+	rcCaption.left = rcWnd.left + 2;
+	rcCaption.right = rcWnd.right - 2;
+	rcCaption.top = rcWnd.top += 2;
+	rcCaption.bottom = rcCaption.top + 2 + CAPTION_HEIGHT;
+
+	lprcBtn->top = rcCaption.top + (rcCaption.bottom - rcCaption.top - 24) / 2;
+	lprcBtn->bottom = lprcBtn->top + 24;
+	lprcBtn->right = rcCaption.right - 12;
+	for (auto& item : m_toolbtns) {
+		lprcBtn->left = lprcBtn->right - 24;
+		if (item.id == id) {
+			return TRUE;
+		}
+		lprcBtn->right = lprcBtn->left - 3;
+	}
+
+	return FALSE;
+}
+
+INT_PTR CBaseView::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
+{
+	RECT rcClient, rcCaption, rcBtn;
+	::GetClientRect(m_hWnd, &rcClient);
+	rcCaption.bottom = 0;
+	rcCaption.top = rcCaption.bottom - CAPTION_HEIGHT;
+	rcCaption.left = rcClient.left;
+	rcCaption.right = rcClient.right;
+	rcBtn.top = rcCaption.top + (rcCaption.bottom - rcCaption.top - 24) / 2;
+	rcBtn.bottom = rcBtn.top + 24;
+	rcBtn.right = rcCaption.right - 12;
+	::OffsetRect(&rcBtn, +5, -5);		// 5为边框粗的修正
+
+	if ((point.y <= 0)) {
+		for (auto& item : m_toolbtns) {
+			rcBtn.left = rcBtn.right - 24;
+			if (::PtInRect(&rcBtn, point)) {
+				pTI->rect = rcBtn;
+				pTI->hwnd = m_hWnd;
+				pTI->uId = (UINT)1020; // Tooltip should show `1020
+				pTI->lpszText = _tcsdup(item.szTooltip);
+				return pTI->uId;
+			}
+
+			rcBtn.right = rcBtn.left - 3;
+		}
+	}
+
+
+	return CDialogEx::OnToolHitTest(point, pTI);
+}
+
+
diff --git a/SourceCode/Bond/BondEq/CBaseView.h b/SourceCode/Bond/BondEq/CBaseView.h
new file mode 100644
index 0000000..8ad4c90
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CBaseView.h
@@ -0,0 +1,73 @@
+#pragma once
+
+#define ID_MSG_VIEW_ACTIVE		WM_USER+2356
+#define ID_MSG_BTN_CLICKED		WM_USER+2357
+#define ID_MSG_BTN_MENU_ITEM	WM_USER+2358
+
+
+class CBaseView : public CDialogEx
+{
+private:
+	typedef struct _TOOLBTN
+	{
+		int id;
+		HICON hIcon[4];
+		char szTooltip[256];
+		BOOL bEnable;
+		HMENU hMenu;
+	} TOOLBTN;
+
+
+	DECLARE_DYNAMIC(CBaseView)
+
+public:
+	CBaseView(UINT id, CWnd* pPage);   // 标准构造函数
+	virtual ~CBaseView();
+
+
+public:
+	void OnViewActive();
+	void OnViewInactive();
+	void AddToolBtn(int id, const char* pszIcon0Path, const char* pszIcon1Path, const char* pszIcon2Path, const char* pszIcon3Path, const char* pszTooltip);
+	void SetToolBtnEnable(int id, BOOL bEnable);
+	void SetToolBtnMenu(int id, HMENU hMenu);
+	void Show(CWnd* pParent, LPRECT lprcBtn);
+	void SetContext(void* pContext);
+	void* GetContext();
+	virtual void OnApply();
+
+private:
+	int MyHitTest(POINT& point, TOOLBTN*& pBtn);
+	CBaseView::TOOLBTN* GetToolBtn(int id);
+	BOOL GetBtnRect(int id, LPRECT lprcBtn);
+
+
+private:
+	std::vector<TOOLBTN> m_toolbtns;
+	TOOLBTN* m_pHotBtn;
+	TOOLBTN* m_pPressBtn;
+	int m_nState;
+
+
+protected:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+	void* m_pContext;
+
+
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
+	afx_msg void OnNcPaint();
+	afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
+	afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp);
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg LRESULT OnNcHitTest(CPoint point);
+	afx_msg void OnNcMouseMove(UINT nHitTest, CPoint point);
+	afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);
+	afx_msg void OnNcLButtonUp(UINT nHitTest, CPoint point);
+	virtual INT_PTR OnToolHitTest(CPoint point, TOOLINFO* pTI) const;
+};
+
diff --git a/SourceCode/Bond/BondEq/CHomeDialog.cpp b/SourceCode/Bond/BondEq/CHomeDialog.cpp
new file mode 100644
index 0000000..a8d3e24
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CHomeDialog.cpp
@@ -0,0 +1,155 @@
+锘�// CHomeDialog.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "Common.h"
+#include "CHomeDialog.h"
+#include "afxdialogex.h"
+
+
+// CHomeDialog 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CHomeDialog, CDialogEx)
+
+CHomeDialog::CHomeDialog(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_DIALOG_HOME, pParent)
+{
+	m_pTab = nullptr;
+	m_pPageLogcat = nullptr;
+	m_pPageAlarm = nullptr;
+	m_crBkgnd = HOMEPAGE_BACKGROUND;
+	m_hbrBkgnd = nullptr;
+}
+
+CHomeDialog::~CHomeDialog()
+{
+}
+
+void CHomeDialog::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CHomeDialog, CDialogEx)
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_WM_SIZE()
+	ON_NOTIFY(BYHMTAB_SEL_CHANGED, IDC_HMTAB1, &CHomeDialog::OnTabSelChanged)
+END_MESSAGE_MAP()
+
+
+// CHomeDialog 娑堟伅澶勭悊绋嬪簭
+
+
+BOOL CHomeDialog::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+
+	// 瀛愰〉闈�
+	m_pPageAlarm = new CPageAlarm();
+	m_pPageAlarm->Create(IDD_PAGE_ALARM, this);
+	m_pPageLogcat = new CPageLogcat();
+	m_pPageLogcat->Create(IDD_PAGE_LOGCAT, this);
+
+
+	// Tab
+	m_pTab = CHmTab::Hook(GetDlgItem(IDC_HMTAB1)->m_hWnd);
+	m_pTab->SetPaddingLeft(20);
+	m_pTab->SetItemMarginLeft(18);
+	m_pTab->SetBkgndColor(RGB(255, 255, 255));
+	m_pTab->AddItem("璀﹀憡", FALSE);
+	m_pTab->AddItem("鏃ュ織", TRUE);
+	m_pTab->SetCurSel(0);
+
+
+	ShowChildPage(0);
+	ShowWindow(SW_MAXIMIZE);
+	
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+
+HBRUSH CHomeDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+
+void CHomeDialog::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+
+	if (m_pPageAlarm != nullptr) {
+		m_pPageAlarm->DestroyWindow();
+		delete m_pPageAlarm;
+		m_pPageAlarm = nullptr;
+	}
+
+	if (m_pPageLogcat != nullptr) {
+		m_pPageLogcat->DestroyWindow();
+		delete m_pPageLogcat;
+		m_pPageLogcat = nullptr;
+	}
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+}
+
+
+void CHomeDialog::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+	if (GetDlgItem(IDC_HMTAB1) == nullptr) return;
+	Resize();
+}
+
+
+void CHomeDialog::ShowChildPage(int index)
+{
+	ASSERT(0 <= index && index < 2);
+	static CWnd* pPages[] = { m_pPageAlarm, m_pPageLogcat };
+	for (int i = 0; i < 2; i++) {
+		pPages[i]->ShowWindow(i == index ? SW_SHOW : SW_HIDE);
+	}
+}
+
+void CHomeDialog::OnTabSelChanged(NMHDR* nmhdr, LRESULT* result)
+{
+	BYHMTAB_NMHDR* pNmhdrex = (BYHMTAB_NMHDR*)nmhdr;
+	ShowChildPage((int)pNmhdrex->dwData);
+
+	*result = 0;
+}
+
+void CHomeDialog::Resize()
+{
+	CRect rcClient, rcItem;
+	GetClientRect(&rcClient);
+
+	int x = 8;
+	int y = 12;
+	GetDlgItem(IDC_HMTAB1)->GetWindowRect(&rcItem);
+	GetDlgItem(IDC_HMTAB1)->MoveWindow(x, y, rcClient.Width() - x * 2, rcItem.Height());
+	y += rcItem.Height();
+	y += 1;
+
+	m_pPageAlarm->MoveWindow(x, y, rcClient.Width() - x * 2, rcClient.Height() - y);
+	m_pPageLogcat->MoveWindow(x, y, rcClient.Width() - x * 2, rcClient.Height() - y);
+}
diff --git a/SourceCode/Bond/BondEq/CHomeDialog.h b/SourceCode/Bond/BondEq/CHomeDialog.h
new file mode 100644
index 0000000..e00d6ad
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CHomeDialog.h
@@ -0,0 +1,45 @@
+锘�#pragma once
+#include "HmTab.h"
+#include "CPageLogcat.h"
+#include "CPageAlarm.h"
+
+
+// CHomeDialog 瀵硅瘽妗�
+
+class CHomeDialog : public CDialogEx
+{
+	DECLARE_DYNAMIC(CHomeDialog)
+
+public:
+	CHomeDialog(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CHomeDialog();
+
+public:
+	void ShowChildPage(int index);
+	void Resize();
+
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+	CHmTab* m_pTab;
+	CPageLogcat* m_pPageLogcat;
+	CPageAlarm* m_pPageAlarm;
+
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_DIALOG_HOME };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnTabSelChanged(NMHDR* nmhdr, LRESULT* result);
+};
diff --git a/SourceCode/Bond/BondEq/CMainContainer.cpp b/SourceCode/Bond/BondEq/CMainContainer.cpp
new file mode 100644
index 0000000..fb92fb4
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CMainContainer.cpp
@@ -0,0 +1,110 @@
+锘�// CMainContainer.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "Common.h"
+#include "CMainContainer.h"
+#include "afxdialogex.h"
+
+
+// CMainContainer 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CMainContainer, CDialogEx)
+
+CMainContainer::CMainContainer(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_MAIN_CONTAINER, pParent)
+{
+	m_crBkgnd = MAIN_CONTAINER_BACKGROUND;
+	m_hbrBkgnd = nullptr;
+}
+
+CMainContainer::~CMainContainer()
+{
+}
+
+void CMainContainer::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CMainContainer, CDialogEx)
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_WM_SIZE()
+END_MESSAGE_MAP()
+
+
+// CMainContainer 娑堟伅澶勭悊绋嬪簭
+
+
+BOOL CMainContainer::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// TODO:  鍦ㄦ娣诲姞棰濆鐨勫垵濮嬪寲
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+
+HBRUSH CMainContainer::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+
+void CMainContainer::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+}
+
+
+void CMainContainer::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+	Resize();
+}
+
+void CMainContainer::Resize()
+{
+	CRect rcClient;
+	GetClientRect(&rcClient);
+
+	// 鍏堝彇寰楀瓙绐楀彛鏁伴噺
+	int count = 0;
+	CWnd* pClild = FindWindowEx(m_hWnd, NULL, NULL, NULL);
+	while (pClild != nullptr) {
+		count++;
+		pClild = FindWindowEx(m_hWnd, pClild->m_hWnd, NULL, NULL);
+	}
+
+	pClild = FindWindowEx(m_hWnd, NULL, NULL, NULL);
+	while (pClild != nullptr) {
+		pClild->MoveWindow(&rcClient);
+		if (::GetProp(pClild->GetSafeHwnd(), "Home") == (HANDLE)1) {
+			pClild->ShowWindow(count == 1 ? SW_SHOW : SW_HIDE);
+		}
+		else {
+			pClild->ShowWindow(SW_SHOW);
+		}
+
+		pClild = FindWindowEx(m_hWnd, pClild->m_hWnd, NULL, NULL);
+	}
+}
diff --git a/SourceCode/Bond/BondEq/CMainContainer.h b/SourceCode/Bond/BondEq/CMainContainer.h
new file mode 100644
index 0000000..ff3d271
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CMainContainer.h
@@ -0,0 +1,38 @@
+锘�#pragma once
+
+
+// CMainContainer 瀵硅瘽妗�
+
+class CMainContainer : public CDialogEx
+{
+	DECLARE_DYNAMIC(CMainContainer)
+
+public:
+	CMainContainer(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CMainContainer();
+
+
+public:
+	void Resize();
+
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_MAIN_CONTAINER };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+};
diff --git a/SourceCode/Bond/BondEq/CPageAlarm.cpp b/SourceCode/Bond/BondEq/CPageAlarm.cpp
new file mode 100644
index 0000000..6c5fa98
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CPageAlarm.cpp
@@ -0,0 +1,116 @@
+// PageAlarm.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "CPageAlarm.h"
+#include "afxdialogex.h"
+#include "Common.h"
+
+
+// CPageAlarm 对话框
+
+IMPLEMENT_DYNAMIC(CPageAlarm, CDialogEx)
+
+CPageAlarm::CPageAlarm(CWnd* pParent /*=NULL*/)
+	: CDialogEx(IDD_PAGE_ALARM, pParent)
+{
+	m_crBkgnd = PAGE_BACKGROUND_COLOR;
+	m_hbrBkgnd = nullptr;
+	m_pObserver = nullptr;
+}
+
+CPageAlarm::~CPageAlarm()
+{
+}
+
+void CPageAlarm::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CPageAlarm, CDialogEx)
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_WM_SIZE()
+END_MESSAGE_MAP()
+
+
+// CPageAlarm 消息处理程序
+
+void CPageAlarm::InitRxWindow()
+{
+	/* code */
+	// 订阅数据
+	IRxWindows* pRxWindows = RX_GetRxWindows();
+	pRxWindows->enableLog(5);
+	if (m_pObserver == NULL) {
+		m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void {
+			// onNext
+			pAny->addRef();
+			int code = pAny->getCode();
+			if (RX_CODE_LOG == code && ::IsWindow(m_hWnd)) {
+
+			}
+
+			pAny->release();
+		}, [&]() -> void {
+			// onComplete
+		}, [&](IThrowable* pThrowable) -> void {
+			// onErrorm
+			pThrowable->printf();
+		});
+
+		theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
+			->subscribe(m_pObserver);
+	}
+}
+
+BOOL CPageAlarm::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+	InitRxWindow();
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 异常: OCX 属性页应返回 FALSE
+}
+
+
+HBRUSH CPageAlarm::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+
+void CPageAlarm::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+
+	if (m_pObserver != NULL) {
+		m_pObserver->unsubscribe();
+		m_pObserver = NULL;
+	}
+}
+
+
+void CPageAlarm::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+
+	// TODO: 在此处添加消息处理程序代码
+}
diff --git a/SourceCode/Bond/BondEq/CPageAlarm.h b/SourceCode/Bond/BondEq/CPageAlarm.h
new file mode 100644
index 0000000..2fdbcb7
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CPageAlarm.h
@@ -0,0 +1,37 @@
+#pragma once
+
+
+// CPageAlarm 对话框
+
+class CPageAlarm : public CDialogEx
+{
+	DECLARE_DYNAMIC(CPageAlarm)
+
+public:
+	CPageAlarm(CWnd* pParent = NULL);   // 标准构造函数
+	virtual ~CPageAlarm();
+
+private:
+	void InitRxWindow();
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+	IObserver* m_pObserver;
+
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_PAGE_ALARM };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+};
diff --git a/SourceCode/Bond/BondEq/CPageLogcat.cpp b/SourceCode/Bond/BondEq/CPageLogcat.cpp
new file mode 100644
index 0000000..f6c32a0
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CPageLogcat.cpp
@@ -0,0 +1,300 @@
+锘�// CPageLogcat.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "Common.h"
+#include "CPageLogcat.h"
+#include "afxdialogex.h"
+#include <regex>
+
+
+// CPageLogcat 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CPageLogcat, CDialogEx)
+
+CPageLogcat::CPageLogcat(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_PAGE_LOGCAT, pParent)
+{
+	m_crBkgnd = PAGE_BACKGROUND_COLOR;
+	m_hbrBkgnd = nullptr;
+	m_pObserver = nullptr;
+	m_nLevel = 0;
+	m_strIncludeText = _T("");
+	m_bIncludeRegex = FALSE;
+}
+
+CPageLogcat::~CPageLogcat()
+{
+}
+
+void CPageLogcat::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_BUTTON_LEVEL, m_btnLevel);
+	DDX_Control(pDX, IDC_BUTTON_INCLUDE, m_btnInclude);
+	DDX_Control(pDX, IDC_EDIT_LOG, m_logEdit);
+	
+}
+
+
+BEGIN_MESSAGE_MAP(CPageLogcat, CDialogEx)
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_WM_SIZE()
+	ON_NOTIFY(BLBUTTON_MENU_ITEM_CLICKED, IDC_BUTTON_LEVEL, &CPageLogcat::OnButtonLevelMenuClicked)
+	ON_NOTIFY(BLBUTTON_MENU_ITEM_CLICKED, IDC_BUTTON_INCLUDE, &CPageLogcat::OnButtonIncludeMenuClicked)
+	ON_EN_CHANGE(IDC_EDIT_INCLUDE, &CPageLogcat::OnEnChangeEditInclude)
+	ON_BN_CLICKED(IDC_CHECK_REGEX, &CPageLogcat::OnBnClickedCheckRegex)
+END_MESSAGE_MAP()
+
+
+// CPageLogcat 娑堟伅澶勭悊绋嬪簭
+
+void CPageLogcat::InitRxWindow()
+{
+	/* code */
+	// 璁㈤槄鏁版嵁
+	IRxWindows* pRxWindows = RX_GetRxWindows();
+	pRxWindows->enableLog(5);
+	if (m_pObserver == NULL) {
+		m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void {
+			// onNext
+			pAny->addRef();
+			int code = pAny->getCode();
+			if (RX_CODE_LOG == code && ::IsWindow(m_hWnd)) {
+				const char* pszLogMsg;
+				int level;
+				if (pAny->getStringValue("text", pszLogMsg)
+					&& pAny->getIntValue("exCode", level)) {
+					if (level >= m_nLevel) {
+						CString strText = pszLogMsg;
+						BOOL bInclude = TRUE;
+						if (!m_strIncludeText.IsEmpty()) {
+							if (!m_bIncludeRegex) {
+								bInclude = (strText.Find(m_strIncludeText) >= 0);
+							}
+							else {
+								bInclude = std::regex_search((LPTSTR)(LPCTSTR)strText,
+									std::regex((LPTSTR)(LPCTSTR)m_strIncludeText));
+							}
+						}
+							
+							
+						if (bInclude) {
+							strText.Replace("\n", "\r\n");
+							AppendLog(level, (LPTSTR)(LPCTSTR)strText);
+						}
+					}
+				}
+			}
+
+			pAny->release();
+			}, [&]() -> void {
+				// onComplete
+			}, [&](IThrowable* pThrowable) -> void {
+				// onErrorm
+				pThrowable->printf();
+			});
+
+		theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
+			->subscribe(m_pObserver);
+	}
+}
+
+BOOL CPageLogcat::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+
+	// 缂撳瓨
+	m_nLevel = theApp.m_model.m_configuration.getLogcatLevel();
+	theApp.m_model.m_configuration.getLogcatIncludeText(m_strIncludeText);
+	m_bIncludeRegex = theApp.m_model.m_configuration.isLogcatIncludeRegex();
+	theApp.m_model.m_configuration.getCustomLogcatIncludeTexts(m_customIncludeTexts);
+
+
+	// Level
+	HMENU hMenu = LoadMenu(AfxGetInstanceHandle(), MAKEINTRESOURCEA(IDR_MENU_LOGCAT_LEVEL));
+	m_btnLevel.SetMenu(hMenu);
+	m_btnLevel.SetCurrentMenuItem(m_nLevel);
+	m_btnLevel.SetBkgndColor(BS_NORMAL, RGB(241, 242, 244));
+	m_btnLevel.SetBkgndColor(BS_HOVER, RGB(220, 223, 228));
+	m_btnLevel.SetBkgndColor(BS_PRESS, RGB(179, 185, 196));
+	m_btnLevel.SetFrameColor(BS_NORMAL, RGB(133, 144, 162));
+	m_btnLevel.SetFrameColor(BS_HOVER, RGB(56, 139, 255));
+	m_btnLevel.SetFrameColor(BS_PRESS, RGB(56, 139, 255));
+	m_btnLevel.SetFrameColor(BS_FOCUS, RGB(56, 139, 255));
+
+
+	// 鍖呭惈瀛楃涓�
+	CString strIcon1;
+	strIcon1.Format(_T("%s\\Res\\logcat_include.ico"), theApp.m_strAppDir);
+	HICON hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(),
+		strIcon1, IMAGE_ICON, 24, 24,
+		LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+	m_btnInclude.SetIcon(hIcon, hIcon, 24);
+
+	{
+		HMENU hMenu = LoadMenu(AfxGetInstanceHandle(), MAKEINTRESOURCEA(IDR_MENU_INCLUDE));
+		HMENU hSubMenu = GetSubMenu(hMenu, 0);
+		DeleteMenu(hSubMenu, 0, MF_BYPOSITION);
+		int i = 0;
+		for (auto& item : m_customIncludeTexts) {
+			i++;
+			InsertMenu(hSubMenu, 0, MF_BYPOSITION, 0x1998+i, item.c_str());
+			m_btnInclude.SetMenu(hMenu);
+		}
+	}
+
+
+	SetDlgItemText(IDC_EDIT_INCLUDE, m_strIncludeText);
+	CButton* pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_REGEX);
+	pCheckBox->SetCheck(m_bIncludeRegex ? BST_CHECKED : BST_UNCHECKED);
+
+
+	// 鍐呭
+	m_logEdit.SetMaxLineCount(20);
+	m_logEdit.SetLimitText(-1);
+
+
+	InitRxWindow();
+
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+
+HBRUSH CPageLogcat::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+
+void CPageLogcat::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+	{
+		HMENU hMenu = m_btnLevel.GetMenu();
+		if (hMenu != NULL) {
+			::DestroyMenu(hMenu);
+		}
+	}
+
+	{
+		HMENU hMenu = m_btnInclude.GetMenu();
+		if (hMenu != NULL) {
+			::DestroyMenu(hMenu);
+		}
+	}
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+
+	ASSERT(m_pObserver != NULL);
+	m_pObserver->unsubscribe();
+	m_pObserver = NULL;
+}
+
+
+void CPageLogcat::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+	if (GetDlgItem(IDC_EDIT_LOG) == nullptr) return;
+
+	int x, y, temp;
+	CRect rcClient, rcItem;
+	CWnd* pItem;
+	GetClientRect(&rcClient);
+
+	x = 12;
+	pItem = GetDlgItem(IDC_BUTTON_LEVEL);
+	pItem->GetWindowRect(&rcItem);
+	ScreenToClient(&rcItem);
+	pItem->MoveWindow(x, 12, rcItem.Width(), rcItem.Height());
+	x += rcItem.Width();
+	x += 18;
+	y = rcItem.bottom;
+	y += 12;
+
+	pItem = GetDlgItem(IDC_BUTTON_INCLUDE);
+	pItem->GetWindowRect(&rcItem);
+	pItem->MoveWindow(x, 12, rcItem.Width(), rcItem.Height());
+	x += rcItem.Width();
+	x += 2;
+
+	pItem = GetDlgItem(IDC_EDIT_INCLUDE);
+	pItem->GetWindowRect(&rcItem);
+	pItem->MoveWindow(x, 12, rcItem.Width(), rcItem.Height());
+	x += rcItem.Width();
+	x += 12;
+	temp = rcItem.Height();
+
+	pItem = GetDlgItem(IDC_CHECK_REGEX);
+	pItem->GetWindowRect(&rcItem);
+	pItem->MoveWindow(x, 12 + (temp - rcItem.Height()) / 2, rcItem.Width(), rcItem.Height());
+
+	pItem = GetDlgItem(IDC_EDIT_LOG);
+	pItem->MoveWindow(12, y, rcClient.Width() - 24, rcClient.Height() - 12 - y);
+
+}
+
+void CPageLogcat::AppendLog(int level, const char* pszText)
+{
+	if (!::IsWindow(m_logEdit.m_hWnd)) {
+		return;
+	}
+	m_logEdit.AppendText(pszText);
+}
+
+void CPageLogcat::OnButtonLevelMenuClicked(NMHDR* pNMHDR, LRESULT* pResult)
+{
+	BLBUTTON_NMHDR* pblbNmhdr = reinterpret_cast<BLBUTTON_NMHDR*>(pNMHDR);
+	m_nLevel = (int)pblbNmhdr->dwData;
+	theApp.m_model.m_configuration.setLogcatLevel(m_nLevel);
+	m_btnLevel.SetCurrentMenuItem(m_nLevel);
+
+	*pResult = 0;
+}
+
+void CPageLogcat::OnButtonIncludeMenuClicked(NMHDR* pNMHDR, LRESULT* pResult)
+{
+	BLBUTTON_NMHDR* pblbNmhdr = reinterpret_cast<BLBUTTON_NMHDR*>(pNMHDR);
+	int position = (int)pblbNmhdr->dwData;
+	std::string& strInclude = m_customIncludeTexts.at(position);
+	SetDlgItemText(IDC_EDIT_INCLUDE, strInclude.c_str());
+	CButton* pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_REGEX);
+	m_bIncludeRegex = FALSE;
+	pCheckBox->SetCheck(BST_UNCHECKED);
+
+	theApp.m_model.m_configuration.setLogcatIncludeRegex(m_bIncludeRegex);
+	theApp.m_model.m_configuration.setLogcatIncludeText(m_strIncludeText);
+
+	*pResult = 0;
+}
+
+void CPageLogcat::OnEnChangeEditInclude()
+{
+	GetDlgItemText(IDC_EDIT_INCLUDE, m_strIncludeText);
+	theApp.m_model.m_configuration.setLogcatIncludeText(m_strIncludeText);
+}
+
+void CPageLogcat::OnBnClickedCheckRegex()
+{
+	CButton* pCheckBox = (CButton*)GetDlgItem(IDC_CHECK_REGEX);
+	m_bIncludeRegex = pCheckBox->GetCheck();
+	theApp.m_model.m_configuration.setLogcatIncludeRegex(m_bIncludeRegex);
+}
diff --git a/SourceCode/Bond/BondEq/CPageLogcat.h b/SourceCode/Bond/BondEq/CPageLogcat.h
new file mode 100644
index 0000000..78eae19
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CPageLogcat.h
@@ -0,0 +1,56 @@
+锘�#pragma once
+#include "BlButton.h"
+#include "LogEdit.h"
+#include <vector>
+#include <string>
+
+
+// CPageLogcat 瀵硅瘽妗�
+
+class CPageLogcat : public CDialogEx
+{
+	DECLARE_DYNAMIC(CPageLogcat)
+
+public:
+	CPageLogcat(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CPageLogcat();
+
+
+private:
+	void InitRxWindow();
+	void AppendLog(int level, const char* pszText);
+
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+	IObserver* m_pObserver;
+	int m_nLevel;
+	CString m_strIncludeText;
+	BOOL m_bIncludeRegex;
+	std::vector<std::string> m_customIncludeTexts;
+
+private:
+	CBlButton m_btnLevel;
+	CBlButton m_btnInclude;
+	CLogEdit m_logEdit;
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_PAGE_LOGCAT };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnButtonLevelMenuClicked(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg void OnButtonIncludeMenuClicked(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg void OnEnChangeEditInclude();
+	afx_msg void OnBnClickedCheckRegex();
+};
diff --git a/SourceCode/Bond/BondEq/CPanelProject.cpp b/SourceCode/Bond/BondEq/CPanelProject.cpp
new file mode 100644
index 0000000..2501e28
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CPanelProject.cpp
@@ -0,0 +1,154 @@
+锘�// CPanelProject.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "CPanelProject.h"
+#include "afxdialogex.h"
+
+
+// CPanelEquipment 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CPanelProject, CDialogEx)
+
+CPanelProject::CPanelProject(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_PANEL_PROJECT, pParent)
+{
+	m_crBkgnd = RGB(252, 252, 255);
+	m_hbrBkgnd = nullptr;
+	m_nPanelWidth = int((double)GetSystemMetrics(SM_CXSCREEN) * 0.25);
+	m_pAccordionWnd = nullptr;
+	m_pPageRemoteEqs = nullptr;
+}
+
+CPanelProject::~CPanelProject()
+{
+}
+
+void CPanelProject::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CPanelProject, CDialogEx)
+	ON_WM_SIZE()
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_NOTIFY(BYVERTICALLINE_MOVEX, IDC_LINE1, &CPanelProject::OnVLineMoveX)
+END_MESSAGE_MAP()
+
+
+// CPanelEquipment 娑堟伅澶勭悊绋嬪簭
+
+
+BOOL CPanelProject::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+
+	// 璇诲彇闈㈡澘瀹�
+	CString strIniFile;
+	strIniFile.Format(_T("%s\\configuration.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir);
+	m_nPanelWidth = GetPrivateProfileInt(_T("App"), _T("PanelEquipmentWidth"),
+		int((double)GetSystemMetrics(SM_CXSCREEN) * 0.25), (LPTSTR)(LPCTSTR)strIniFile);
+
+	CVerticalLine* pLine = CVerticalLine::Hook(GetDlgItem(IDC_LINE1)->GetSafeHwnd());
+	pLine->EnableResize();
+
+
+	// 鍒嗙粍灞曞紑鏀惰捣鎺т欢
+	CString strExpandIcon, strCloseIcon;
+	strExpandIcon.Format(_T("%s\\res\\arrow_down.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir);
+	strCloseIcon.Format(_T("%s\\res\\arrow_right.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir);
+
+	m_pAccordionWnd = CAccordionWnd::FromHandle(GetDlgItem(IDC_ACCORDION_WND1)->m_hWnd);
+	m_pAccordionWnd->SetFrameColor(RGB(220, 220, 220), TRUE);
+	m_pAccordionWnd->Setpadding(PADDING_LEFT, 2);
+	m_pAccordionWnd->Setpadding(PADDING_TOP, 2);
+	m_pAccordionWnd->Setpadding(PADDING_RIGHT, 2);
+	m_pAccordionWnd->Setpadding(PADDING_BOTTOM, 2);
+	m_pAccordionWnd->LoadExpandIcon(strExpandIcon, strCloseIcon);
+	
+	m_pPageRemoteEqs = new CProjectPageRemoteEqs();
+	m_pPageRemoteEqs->Create(IDD_PROJECT_PAGE_REMOTEEQS, GetDlgItem(IDC_ACCORDION_WND1));
+	m_pPageRemoteEqs->ShowWindow(SW_SHOW);
+	m_pAccordionWnd->AddItem("杩滅▼璁惧", m_pPageRemoteEqs, 0, TRUE, TRUE);
+	
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+void CPanelProject::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+	if(GetDlgItem(IDC_LINE1) == nullptr) return;
+	Resize();
+}
+
+HBRUSH CPanelProject::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+void CPanelProject::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+
+	if (m_pPageRemoteEqs != nullptr) {
+		m_pPageRemoteEqs->DestroyWindow();
+		delete m_pPageRemoteEqs;
+		m_pPageRemoteEqs = nullptr;
+	}
+}
+
+void CPanelProject::Resize()
+{
+	CRect rcClient, rcItem;
+	GetClientRect(&rcClient);
+
+	CWnd* pLine = GetDlgItem(IDC_LINE1);
+	pLine->MoveWindow(rcClient.right - 2, 0, 2, rcClient.Height());
+
+	GetDlgItem(IDC_ACCORDION_WND1)->MoveWindow(0, 0, rcClient.Width() - 2, rcClient.Height());
+}
+
+#define LEFT_PANEL_MIN_WIDTH		80
+#define LEFT_PANEL_MAX_WIDTH		880
+void CPanelProject::OnVLineMoveX(NMHDR* nmhdr, LRESULT* result)
+{
+	BYVERTICALLINE_NMHDR* pNmhdrex = (BYVERTICALLINE_NMHDR*)nmhdr;
+	int x = pNmhdrex->dwData;
+	m_nPanelWidth += x;
+	m_nPanelWidth = max(m_nPanelWidth, LEFT_PANEL_MIN_WIDTH);
+	m_nPanelWidth = min(m_nPanelWidth, LEFT_PANEL_MAX_WIDTH);
+	GetParent()->SendMessage(WM_SIZE, 0, 0);
+
+	CString strIniFile, strValue;
+	strIniFile.Format(_T("%s\\configuration.ini"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir);
+	strValue.Format(_T("%d"), m_nPanelWidth);
+	WritePrivateProfileString(_T("App"), _T("PanelEquipmentWidth"),
+		(LPTSTR)(LPCTSTR)strValue, (LPTSTR)(LPCTSTR)strIniFile);
+
+	*result = 0;
+}
+
+int CPanelProject::GetPanelWidth()
+{
+	return m_nPanelWidth;
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/CPanelProject.h b/SourceCode/Bond/BondEq/CPanelProject.h
new file mode 100644
index 0000000..d62a58b
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CPanelProject.h
@@ -0,0 +1,49 @@
+锘�#pragma once
+#include "VerticalLine.h"
+#include "CProjectPageRemoteEqs.h"
+#include "AccordionWnd.h"
+
+
+// CPanelProject 瀵硅瘽妗�
+
+class CPanelProject : public CDialogEx
+{
+	DECLARE_DYNAMIC(CPanelProject)
+
+public:
+	CPanelProject(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CPanelProject();
+
+
+public:
+	int GetPanelWidth();
+
+
+private:
+	void Resize();
+
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+	int m_nPanelWidth;
+	CAccordionWnd* m_pAccordionWnd;
+	CProjectPageRemoteEqs* m_pPageRemoteEqs;
+
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_PANEL_PROJECT };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnVLineMoveX(NMHDR* nmhdr, LRESULT* result);
+};
diff --git a/SourceCode/Bond/BondEq/CProjectPageRemoteEqs.cpp b/SourceCode/Bond/BondEq/CProjectPageRemoteEqs.cpp
new file mode 100644
index 0000000..a9e516f
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CProjectPageRemoteEqs.cpp
@@ -0,0 +1,211 @@
+锘�// CProjectPageRemoteEqs.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "Common.h"
+#include "BondServo.h"
+#include "CProjectPageRemoteEqs.h"
+#include "afxdialogex.h"
+
+
+// CProjectPageRemoteEqs 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CProjectPageRemoteEqs, CDialogEx)
+
+CProjectPageRemoteEqs::CProjectPageRemoteEqs(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_PROJECT_PAGE_REMOTEEQS, pParent)
+{
+	m_crBkgnd = PROPAGE_BACKGROUND_COLOR;
+	m_hbrBkgnd = nullptr;
+	m_pObserver = nullptr;
+}
+
+CProjectPageRemoteEqs::~CProjectPageRemoteEqs()
+{
+}
+
+void CProjectPageRemoteEqs::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_TREE1, m_treeRemoteEqs);
+}
+
+
+BEGIN_MESSAGE_MAP(CProjectPageRemoteEqs, CDialogEx)
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_WM_SIZE()
+	ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, &CProjectPageRemoteEqs::OnTvnSelchangedTree1)
+	ON_MESSAGE(ID_MSG_TREE_CLICK_ITEM, OnTreeClickItem)
+	ON_WM_TIMER()
+END_MESSAGE_MAP()
+
+
+// CProjectPageRemoteEqs 娑堟伅澶勭悊绋嬪簭
+
+
+void CProjectPageRemoteEqs::InitRxWindows()
+{
+	/* code */
+	// 璁㈤槄鏁版嵁
+	IRxWindows* pRxWindows = RX_GetRxWindows();
+	pRxWindows->enableLog(5);
+	if (m_pObserver == NULL) {
+		m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void {
+			// onNext
+			pAny->addRef();
+			int code = pAny->getCode();
+			if (RX_CODE_REMOTEEQ_STATE_CHANGED == code) {
+				BEQ::IRemoteEquipment* pRemoteEq;
+				if (pAny->getPtrValue("ptr", (void*&)pRemoteEq)) {
+					HTREEITEM hItem = getTreeItem(pRemoteEq);
+					if (hItem != nullptr) {
+						char szBuffer[256];
+						pRemoteEq->getName(szBuffer, 256);
+						m_treeRemoteEqs.SetItemText(hItem, szBuffer);
+						m_treeRemoteEqs.SetItemIcon(hItem, 
+							pRemoteEq->isConnected() ? m_hIconRemoteEqLight : m_hIconRemoteEqDark);
+					}
+				}
+			}
+			pAny->release();
+		}, [&]() -> void {
+			// onComplete
+		}, [&](IThrowable* pThrowable) -> void {
+			// onErrorm
+			pThrowable->printf();
+		});
+
+		theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
+			->subscribe(m_pObserver);
+	}
+}
+
+BOOL CProjectPageRemoteEqs::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	CString strFilepath;
+	strFilepath.Format(_T("%s\\Res\\remote_eq_light_32.ico"), theApp.m_strAppDir);
+	m_hIconRemoteEqLight = (HICON)::LoadImage(AfxGetInstanceHandle(),
+		strFilepath, IMAGE_ICON, 32, 32,
+		LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+	strFilepath.Format(_T("%s\\Res\\remote_eq_dark_32.ico"), theApp.m_strAppDir);
+	m_hIconRemoteEqDark = (HICON)::LoadImage(AfxGetInstanceHandle(),
+		strFilepath, IMAGE_ICON, 32, 32,
+		LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+
+	m_treeRemoteEqs.SetBkColor(PROPAGE_BACKGROUND_COLOR);
+	m_treeRemoteEqs.SetItemHeight(50);
+	SetTimer(1, 2000, nullptr);
+
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+HBRUSH CProjectPageRemoteEqs::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+
+void CProjectPageRemoteEqs::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+
+	ASSERT(m_pObserver != NULL);
+	m_pObserver->unsubscribe();
+	m_pObserver = NULL;
+}
+
+
+void CProjectPageRemoteEqs::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+	if (GetDlgItem(IDC_TREE1) == nullptr) return;
+
+	CRect rcClient;
+	CWnd* pItem;
+	GetClientRect(&rcClient);
+
+	pItem = GetDlgItem(IDC_TREE1);
+	pItem->MoveWindow(12, 12, rcClient.Width() - 24, rcClient.Height() - 24);
+}
+
+
+void CProjectPageRemoteEqs::OnTvnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult)
+{
+	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
+
+
+	HTREEITEM hItem = pNMTreeView->itemNew.hItem;
+	ASSERT(hItem);
+	BEQ::IRemoteEquipment* pEquipment = (BEQ::IRemoteEquipment*)m_treeRemoteEqs.GetItemData(hItem);
+	ASSERT(pEquipment);
+	theApp.m_model.notifyPtr(RX_CODE_SELECT_EQ, pEquipment);
+
+
+	*pResult = 0;
+}
+
+LRESULT CProjectPageRemoteEqs::OnTreeClickItem(WPARAM wParam, LPARAM lParam)
+{
+	HTREEITEM hItem = (HTREEITEM)wParam;
+	ASSERT(hItem);
+	BEQ::IRemoteEquipment* pEquipment = (BEQ::IRemoteEquipment*)m_treeRemoteEqs.GetItemData(hItem);
+	ASSERT(pEquipment);
+	theApp.m_model.notifyPtr(RX_CODE_SELECT_EQ, pEquipment);
+
+
+	return 0;
+}
+
+HTREEITEM CProjectPageRemoteEqs::getTreeItem(BEQ::IRemoteEquipment* pEquipment)
+{
+	HTREEITEM hItem = m_treeRemoteEqs.GetChildItem(nullptr);
+	while (hItem != nullptr) {
+		BEQ::IRemoteEquipment* p = (BEQ::IRemoteEquipment*)m_treeRemoteEqs.GetItemData(hItem);
+		if (p == pEquipment) {
+			return hItem;
+		}
+
+		hItem = m_treeRemoteEqs.GetNextSiblingItem(hItem);
+	}
+
+	return nullptr;
+}
+
+void CProjectPageRemoteEqs::OnTimer(UINT_PTR nIDEvent)
+{
+	if (1 == nIDEvent) {
+		KillTimer(1);
+		InitRxWindows();
+
+		// 杩滅▼璁惧鍒楄〃
+		char szEqName[256];
+		BEQ::IRemoteEquipment* pRemoteEq = theApp.m_model.getBond1();
+		ASSERT(pRemoteEq);
+		pRemoteEq->getName(szEqName, 256);
+		
+		HTREEITEM hItemEq = m_treeRemoteEqs.InsertItem(szEqName);
+		m_treeRemoteEqs.SetItemIcon(hItemEq, pRemoteEq->isConnected() ? m_hIconRemoteEqLight : m_hIconRemoteEqDark);
+		m_treeRemoteEqs.SetItemData(hItemEq, (DWORD_PTR)pRemoteEq);
+	}
+
+	CDialogEx::OnTimer(nIDEvent);
+}
diff --git a/SourceCode/Bond/BondEq/CProjectPageRemoteEqs.h b/SourceCode/Bond/BondEq/CProjectPageRemoteEqs.h
new file mode 100644
index 0000000..ec0437e
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CProjectPageRemoteEqs.h
@@ -0,0 +1,46 @@
+锘�#pragma once
+#include "ApredTreeCtrl.h"
+
+
+// CProjectPageRemoteEqs 瀵硅瘽妗�
+
+class CProjectPageRemoteEqs : public CDialogEx
+{
+	DECLARE_DYNAMIC(CProjectPageRemoteEqs)
+
+public:
+	CProjectPageRemoteEqs(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CProjectPageRemoteEqs();
+
+
+private:
+	void InitRxWindows();
+	HTREEITEM getTreeItem(BEQ::IRemoteEquipment* pEquipment);
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+	CApredTreeCtrl m_treeRemoteEqs;
+	IObserver* m_pObserver;
+	HICON m_hIconRemoteEqLight;
+	HICON m_hIconRemoteEqDark;
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_PROJECT_PAGE_REMOTEEQS
+	};
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnTvnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult);
+	afx_msg LRESULT OnTreeClickItem(WPARAM wParam, LPARAM lParam);
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+};
diff --git a/SourceCode/Bond/BondEq/CRemoteEqUnitView.cpp b/SourceCode/Bond/BondEq/CRemoteEqUnitView.cpp
new file mode 100644
index 0000000..c1eca1c
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CRemoteEqUnitView.cpp
@@ -0,0 +1,68 @@
+锘�// CRemoteEqUnitView.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "afxdialogex.h"
+#include "CRemoteEqUnitView.h"
+#include "Log.h"
+#include "ToolUnits.h"
+#include "Common.h"
+
+
+// CRemoteEqUnitView 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CRemoteEqUnitView, CBaseView)
+
+CRemoteEqUnitView::CRemoteEqUnitView(CWnd* pParent /*=nullptr*/)
+	: CBaseView(IDD_COMPONENT_REMOTE_EQ_UNIT, pParent)
+{
+	m_pObserver = nullptr;
+	m_crBkgnd = REMOTE_EQ_VIEW_BACKGROUND;
+	m_hbrBkgnd = nullptr;
+}
+
+CRemoteEqUnitView::~CRemoteEqUnitView()
+{
+}
+
+void CRemoteEqUnitView::DoDataExchange(CDataExchange* pDX)
+{
+	CBaseView::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CRemoteEqUnitView, CBaseView)
+END_MESSAGE_MAP()
+
+
+// CRemoteEqUnitView 娑堟伅澶勭悊绋嬪簭
+
+
+HBRUSH CRemoteEqUnitView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+void CRemoteEqUnitView::OnDestroy()
+{
+	CBaseView::OnDestroy();
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+
+	ASSERT(m_pObserver != NULL);
+	m_pObserver->unsubscribe();
+	m_pObserver = NULL;
+}
diff --git a/SourceCode/Bond/BondEq/CRemoteEqUnitView.h b/SourceCode/Bond/BondEq/CRemoteEqUnitView.h
new file mode 100644
index 0000000..777b785
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CRemoteEqUnitView.h
@@ -0,0 +1,32 @@
+锘�#pragma once
+#include "CBaseView.h"
+
+
+// CRemoteEqUnitView 瀵硅瘽妗�
+
+class CRemoteEqUnitView : public CBaseView
+{
+	DECLARE_DYNAMIC(CRemoteEqUnitView)
+
+public:
+	CRemoteEqUnitView(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CRemoteEqUnitView();
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+	IObserver* m_pObserver;
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_COMPONENT_REMOTE_EQ_UNIT };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+};
diff --git a/SourceCode/Bond/BondEq/CRemoteEqView.cpp b/SourceCode/Bond/BondEq/CRemoteEqView.cpp
new file mode 100644
index 0000000..e640f9e
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CRemoteEqView.cpp
@@ -0,0 +1,206 @@
+锘�// CComponentData1Dlg.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "CRemoteEqView.h"
+#include "afxdialogex.h"
+#include "Log.h"
+#include "ToolUnits.h"
+#include "Common.h"
+
+
+// CComponentData1Dlg 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CRemoteEqView, CBaseView)
+
+CRemoteEqView::CRemoteEqView(CWnd* pParent /*=nullptr*/)
+	: CBaseView(IDD_COMPONENT_REMOTE_EQ, pParent)
+{
+	m_pObserver = nullptr;
+	m_crBkgnd = REMOTE_EQ_VIEW_BACKGROUND;
+	m_hbrBkgnd = nullptr;
+}
+
+CRemoteEqView::~CRemoteEqView()
+{
+	for (CRemoteEqUnitView* pView : m_tabViews) {
+		if (pView) {
+			pView->DestroyWindow();
+			delete pView;
+		}
+	}
+	m_tabViews.clear();
+}
+
+void CRemoteEqView::DoDataExchange(CDataExchange* pDX)
+{
+	CBaseView::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CRemoteEqView, CBaseView)
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_WM_SIZE()
+	ON_WM_TIMER()
+	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_UNITS, &CRemoteEqView::OnSelchangeUnitTab)
+END_MESSAGE_MAP()
+
+
+// CComponentData1Dlg 娑堟伅澶勭悊绋嬪簭
+
+void CRemoteEqView::InitRxWindows()
+{
+	/* code */
+	// 璁㈤槄鏁版嵁
+	IRxWindows* pRxWindows = RX_GetRxWindows();
+	if (m_pObserver == NULL) {
+		m_pObserver = pRxWindows->allocObserver([&](IAny* pAny) -> void {
+			// onNext
+			pAny->addRef();
+			int code = pAny->getCode();
+
+			pAny->release();
+			}, [&]() -> void {
+				// onComplete
+			}, [&](IThrowable* pThrowable) -> void {
+				// onErrorm
+				pThrowable->printf();
+			});
+
+		theApp.m_model.getObservable()->observeOn(pRxWindows->mainThread())
+			->subscribe(m_pObserver);
+	}
+}
+
+BOOL CRemoteEqView::OnInitDialog()
+{
+	CBaseView::OnInitDialog();
+	SetTimer(1, 200, NULL);
+
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+
+HBRUSH CRemoteEqView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+void CRemoteEqView::OnDestroy()
+{
+	CBaseView::OnDestroy();
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+
+	ASSERT(m_pObserver != NULL);
+	m_pObserver->unsubscribe();
+	m_pObserver = NULL;
+}
+
+void CRemoteEqView::OnSize(UINT nType, int cx, int cy)
+{
+	CBaseView::OnSize(nType, cx, cy);
+}
+
+void CRemoteEqView::OnTimer(UINT_PTR nIDEvent)
+{
+	// TODO: 鍦ㄦ娣诲姞娑堟伅澶勭悊绋嬪簭浠g爜鍜�/鎴栬皟鐢ㄩ粯璁ゅ��
+	if (1 == nIDEvent) {
+		KillTimer(1);
+		InitRxWindows();
+		LoadData();
+	}
+
+	CBaseView::OnTimer(nIDEvent);
+}
+
+void CRemoteEqView::LoadData()
+{
+	BEQ::IRemoteEquipment* pEquipment = (BEQ::IRemoteEquipment*)GetContext();
+	if (pEquipment == nullptr) {
+		return;
+	}
+
+	CTabCtrl* pTabCtrl = (CTabCtrl*)GetDlgItem(IDC_TAB_UNITS);
+	const char** names = pEquipment->getAllUnitNames();
+	AddUnitTabs(*pTabCtrl, names);
+
+	if (m_tabViews.size() > 0 && !m_tabViews.empty()) {
+		m_tabViews[0]->ShowWindow(SW_SHOW);
+	}
+}
+
+void CRemoteEqView::Resize()
+{
+	int y = 12;
+	int x = 0;
+	CRect rcClient, rcItem;
+	CWnd* pItem;
+	GetClientRect(&rcClient);
+}
+
+void CRemoteEqView::AddUnitTabs(CTabCtrl& tabCtrl, const char** names)
+{
+	BEQ::IRemoteEquipment* pEquipment = (BEQ::IRemoteEquipment*)GetContext();
+	if (pEquipment == nullptr) {
+		return;
+	}
+
+	int tabIndex = 0;
+	while (names[tabIndex] != nullptr) {
+		BEQ::IUnit* pUnit = pEquipment->getUnit(names[tabIndex]);
+		if (pUnit == nullptr) {
+			++tabIndex;
+			continue;
+		}
+
+		CString tabText(names[tabIndex]);
+		tabCtrl.InsertItem(tabIndex, tabText);
+
+		CRemoteEqUnitView* pView = new CRemoteEqUnitView();
+		if (pView->Create(IDD_COMPONENT_REMOTE_EQ_UNIT, &tabCtrl)) {
+			CRect rect;
+			tabCtrl.GetClientRect(&rect);
+			tabCtrl.AdjustRect(FALSE, &rect);
+			rect.DeflateRect(10, 10);
+			pView->MoveWindow(rect);
+			pView->ShowWindow(SW_HIDE);
+
+			pView->SetContext(pUnit);
+			m_tabViews.push_back(pView);
+		}
+		++tabIndex;
+	}
+}
+
+void CRemoteEqView::OnSelchangeUnitTab(NMHDR* pNMHDR, LRESULT* pResult)
+{
+	CTabCtrl* pTabCtrl = (CTabCtrl*)GetDlgItem(IDC_TAB_UNITS);
+	int selectedIndex = pTabCtrl->GetCurSel();
+
+	for (CRemoteEqUnitView* pView : m_tabViews) {
+		pView->ShowWindow(SW_HIDE);
+	}
+
+	if (selectedIndex >= 0 && selectedIndex < m_tabViews.size()) {
+		m_tabViews[selectedIndex]->ShowWindow(SW_SHOW);
+	}
+
+	*pResult = 0;
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/CRemoteEqView.h b/SourceCode/Bond/BondEq/CRemoteEqView.h
new file mode 100644
index 0000000..f2c5146
--- /dev/null
+++ b/SourceCode/Bond/BondEq/CRemoteEqView.h
@@ -0,0 +1,46 @@
+锘�#pragma once
+#include "CBaseView.h"
+#include "CRemoteEqUnitView.h"
+
+
+// CComponentData1Dlg 瀵硅瘽妗�
+
+class CRemoteEqView : public CBaseView
+{
+	DECLARE_DYNAMIC(CRemoteEqView)
+
+public:
+	CRemoteEqView(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CRemoteEqView();
+
+
+private:
+	void InitRxWindows();
+	void LoadData();
+	void Resize();
+	void AddUnitTabs(CTabCtrl& tabCtrl, const char** names);
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+	IObserver* m_pObserver;
+	std::vector<CRemoteEqUnitView*> m_tabViews;
+
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_COMPONENT_DATA1 };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+	afx_msg void OnSelchangeUnitTab(NMHDR* pNMHDR, LRESULT* pResult);
+};
diff --git a/SourceCode/Bond/BondEq/Common.h b/SourceCode/Bond/BondEq/Common.h
new file mode 100644
index 0000000..0ef4e64
--- /dev/null
+++ b/SourceCode/Bond/BondEq/Common.h
@@ -0,0 +1,89 @@
+#pragma once
+
+
+#define MC_TIME_SEPAR				1000
+
+
+/* Context Ret code */
+#define CRC_ACK_REJECT							-3
+#define CRC_TIMEOUT								-2
+#define CRC_NG									-1
+#define CRC_UNKNOWN								0
+#define CRC_SUCCEED								1
+
+/* Rx Code */
+#define RX_CODE_TEST					0
+#define RX_CODE_LOG						1000
+#define RX_CODE_BONDER_STATE_CHANGED	1001
+#define RX_CODE_PASSIVE_STATUS_CHANGED	1002
+#define RX_CODE_PLC1_CONNECTTD			1003
+#define RX_CODE_PLC1_DISCONNECTTD		1004
+#define RX_CODE_SELECT_EQ				1005
+#define RX_CODE_DATA1_MATERIAL_RECEIVED	1006
+#define RX_CODE_DATA1_BEGIN_SAMPLING	1007
+#define RX_CODE_DATA1_UPDATE			1008
+#define RX_CODE_DATA1_END_SAMPLING		1009
+#define RX_CODE_DATA1_MATERIAL_REMOVEED	1010
+#define RX_CODE_PANEL_COMPLATE			1011
+#define RX_CODE_ALARM_EVENT				1012
+#define RX_CODE_EQSTATE_EVENT			1013
+#define RX_CODE_EFEM_STATUS_CHANGED		1014
+#define RX_CODE_REMOTEEQ_STATE_CHANGED	1015
+
+/* 广播代码 */
+#define BC_CODE_DATA1_MATERIAL_RECEIVED	5000
+#define BC_CODE_DATA1_BEGIN_SAMPLING	5001
+#define BC_CODE_DATA1_UPDATE			5002
+#define BC_CODE_DATA1_END_SAMPLING		5003
+#define BC_CODE_DATA1_MATERIAL_REMOVED	5004
+#define BC_CODE_ALARM_EVENT				5005
+#define BC_CODE_EQSTATE_EVENT			5006
+#define BC_CODE_RUN_RECIPE_RESULT		5007
+
+/* Channel Name */
+#define MC_CHANNEL1_NAME		"McChannel1"
+
+
+/* 颜色 */
+#define APPDLG_BACKGROUND_COLOR			RGB(252, 252, 255)
+#define PAGE_BACKGROUND_COLOR			RGB(252, 252, 255)
+#define SETPAGE_BACKGROUND_COLOR		RGB(250, 250, 255)
+#define PROPAGE_BACKGROUND_COLOR		RGB(252, 252, 255)
+#define REMOTE_EQ_VIEW_BACKGROUND		RGB(252, 252, 255)	
+#define TOP_TOOLBAR_BACKGROUND			RGB(240, 240, 240)	
+#define INACTIVE_BACKGROUND				RGB(188, 188, 188)
+#define INACTIVE_FOREGROUND				RGB(68, 68, 68)
+#define ACTIVE_BACKGROUND				RGB(34, 177, 76)
+#define ACTIVE_FOREGROUND				RGB(68, 68, 68)
+#define NOT_SELECTED_BACKGROUND			RGB(181, 230, 29)
+#define NOT_SELECTED_FOREGROUND			RGB(68, 68, 68)
+#define SELECTED_BACKGROUND				RGB(34, 177, 76)
+#define SELECTED_FOREGROUND				RGB(68, 68, 68)
+#define DISCONNECTED_BACKGROUND			RGB(255, 127, 39)
+#define DISCONNECTED_FOREGROUND			RGB(68, 68, 68)
+#define CONNECTED_BACKGROUND			RGB(34, 177, 76)
+#define CONNECTED_FOREGROUND			RGB(68, 68, 68)
+#define BASE_VIEW_BACKGROUND			RGB(252, 252, 255)
+#define MAIN_CONTAINER_BACKGROUND		RGB(252, 252, 255)
+#define TREE_BADGE_BACKGROUND			RGB(34, 177, 76)
+#define TREE_BADGE_FOREGROUND			RGB(222, 222, 222)
+#define TREE_BADGE2_BACKGROUND			RGB(255, 127, 39)
+#define TREE_BADGE2_FOREGROUND			RGB(222, 222, 222)
+#define HOMEPAGE_BACKGROUND				RGB(252, 252, 255)
+
+
+/* 按钮颜色定义 风格1*/
+#define BTN1_BKGND_NORMAL				RGB(245, 245, 245)
+#define BTN1_BKGND_HOVER				RGB(229, 241, 251)
+#define BTN1_BKGND_PRESS				RGB(185, 209, 234)
+#define BTN1_BKGND_FOCUS				RGB(245, 245, 245)
+#define BTN1_BKGND_DISABLE				RGB(245, 245, 245)
+#define BTN1_TEXT_NORMAL				RGB(51, 51, 51)
+#define BTN1_TEXT_HOVER					RGB(51, 51, 51)
+#define BTN1_TEXT_PRESS					RGB(51, 51, 51)
+#define BTN1_TEXT_FOCUS					RGB(51, 51, 51)
+#define BTN1_TEXT_DISABLE				RGB(191, 191, 191)
+
+/* 按钮id */
+#define VIEW_TOOL_BTN_CLOSE				0x1016
+
diff --git a/SourceCode/Bond/BondEq/Configuration.cpp b/SourceCode/Bond/BondEq/Configuration.cpp
new file mode 100644
index 0000000..b8529b6
--- /dev/null
+++ b/SourceCode/Bond/BondEq/Configuration.cpp
@@ -0,0 +1,105 @@
+#include "stdafx.h"
+#include "Configuration.h"
+
+
+CConfiguration::CConfiguration()
+{
+}
+
+CConfiguration::CConfiguration(const char* pszFilepath)
+{
+	m_strFilepath = pszFilepath;
+}
+
+CConfiguration::~CConfiguration()
+{
+}
+
+void CConfiguration::setFilepath(const char* pszFilepath)
+{
+	m_strFilepath = pszFilepath;
+}
+
+void CConfiguration::getUnitId(CString& strUnitId)
+{
+	char szTemp[256];
+	GetPrivateProfileString("App", _T("UnitId"), _T(""), szTemp, 256, m_strFilepath);
+	strUnitId = szTemp;
+}
+
+void CConfiguration::getBond1(CString& strIp, UINT& port, UINT& doorCount)
+{
+	char szTemp[256];
+
+	// 读IP和端口
+	GetPrivateProfileString("Bond1", _T("IP"), _T(""), szTemp, 256, m_strFilepath);
+	strIp = szTemp;
+	port = GetPrivateProfileInt("Bond1", _T("Port"), 0, m_strFilepath);
+	doorCount = GetPrivateProfileInt("Bond1", _T("DoorCount"), 0, m_strFilepath);
+}
+
+int CConfiguration::getLogcatLevel()
+{
+	return GetPrivateProfileInt(_T("Logcat"), _T("Level"), 0, m_strFilepath);
+}
+
+void CConfiguration::setLogcatLevel(int level)
+{
+	WritePrivateProfileString(_T("Logcat"), _T("Level"),
+		std::to_string(level).c_str(), m_strFilepath);
+}
+
+int CConfiguration::setLogcatIncludeText(CString& strInclude)
+{
+	WritePrivateProfileString(_T("Logcat"), _T("IncludeText"),
+		strInclude, m_strFilepath);
+	return 0;
+}
+
+int CConfiguration::getLogcatIncludeText(CString& strInclude)
+{
+	char szTemp[256];
+	GetPrivateProfileString("Logcat", _T("IncludeText"), _T(""), szTemp, 256, m_strFilepath);
+	strInclude = szTemp;
+	return 0;
+}
+
+void CConfiguration::setLogcatIncludeRegex(BOOL bRegex)
+{
+	WritePrivateProfileString(_T("Logcat"), _T("IncludeRegex"),
+		bRegex ? "1" : "0", m_strFilepath);
+}
+
+BOOL CConfiguration::isLogcatIncludeRegex()
+{
+	return GetPrivateProfileInt(_T("Logcat"), _T("IncludeRegex"), 0, m_strFilepath);
+}
+
+int CConfiguration::getCustomLogcatIncludeTexts(std::vector<std::string>& texts)
+{
+	char szSection[256], szTemp[256];
+
+	for (int i = 0; i < 10; i++) {
+		sprintf_s(szSection, 256, "CustomInclude%d", i + 1);
+		GetPrivateProfileString("Logcat", szSection, _T(""),
+			szTemp, 256, m_strFilepath);
+		std::string strInclude(szTemp);
+		if (!strInclude.empty()) {
+			texts.push_back(strInclude);
+		}
+	}
+
+	return (int)texts.size();	
+}
+
+int CConfiguration::getP2RemoteEqReconnectInterval()
+{
+	return GetPrivateProfileInt(_T("P2"), _T("RemoteEqReconnectInterval"), 20, m_strFilepath);
+}
+
+void CConfiguration::setP2RemoteEqReconnectInterval(int second)
+{
+	WritePrivateProfileString(_T("P2"), _T("RemoteEqReconnectInterval"),
+		std::to_string(second).c_str(), m_strFilepath);
+}
+
diff --git a/SourceCode/Bond/BondEq/Configuration.h b/SourceCode/Bond/BondEq/Configuration.h
new file mode 100644
index 0000000..95d00e2
--- /dev/null
+++ b/SourceCode/Bond/BondEq/Configuration.h
@@ -0,0 +1,31 @@
+#pragma once
+#include <vector>
+#include <string>
+
+class CConfiguration
+{
+public:
+	CConfiguration();
+	CConfiguration(const char* pszFilepath);
+	~CConfiguration();
+
+public:
+	void setFilepath(const char* pszFilepath);
+	void getUnitId(CString& strUnitId);
+	void getBond1(CString& strIp, UINT& port, UINT& doorCount);
+	int getLogcatLevel();
+	void setLogcatLevel(int level);
+	int setLogcatIncludeText(CString& strInclude);
+	int getLogcatIncludeText(CString& strInclude);
+	void setLogcatIncludeRegex(BOOL bRegex);
+	BOOL isLogcatIncludeRegex();
+	int getCustomLogcatIncludeTexts(std::vector<std::string>& texts);
+
+public:
+	void setP2RemoteEqReconnectInterval(int second);
+	int getP2RemoteEqReconnectInterval();
+
+private:
+	CString m_strFilepath;
+};
+
diff --git a/SourceCode/Bond/BondEq/DBManager/UserManager.cpp b/SourceCode/Bond/BondEq/DBManager/UserManager.cpp
new file mode 100644
index 0000000..0b879db
--- /dev/null
+++ b/SourceCode/Bond/BondEq/DBManager/UserManager.cpp
@@ -0,0 +1,484 @@
+#include "stdafx.h"
+#include "UserManager.h"
+#include <chrono>
+#include <iostream>
+#include <fstream>
+#include <ctime>
+#include <sstream>
+
+const std::string SESSION_FILE = R"(session.dat)";
+const std::string DATABASE_FILE = R"(BondServo.db)";
+
+const std::string INITIAL_ADMIN_USERNAME = "admin";
+const std::string INITIAL_ADMIN_PASSWORD = "admin";
+
+// 获取单例实例
+UserManager& UserManager::getInstance() {
+    static UserManager instance;
+    return instance;
+}
+
+UserManager::UserManager()
+    : m_isLoggedIn(false), m_isRememberMe(false), m_tmSessionTimeout(std::chrono::minutes(30)),
+    m_tmSessionExpiration(std::chrono::hours(72)), m_hMouseHook(nullptr), m_hKeyboardHook(nullptr),
+    m_pDB(std::make_unique<BL::SQLiteDatabase>()) {
+    initializeDatabase();
+}
+
+UserManager::~UserManager() {
+    terminateIdleDetection();
+}
+
+// 初始化数据库,创建用户表并插入初始管理员用户
+bool UserManager::initializeDatabase() {
+    std::string dbFilePath = getDatabaseFilePath();
+    if (!m_pDB->connect(dbFilePath, true)) {
+        throw std::runtime_error("Failed to connect to database.");
+    }
+
+    std::string createTableQuery = R"(
+        CREATE TABLE IF NOT EXISTS users (
+            username VARCHAR(50) PRIMARY KEY,
+            password_hash VARCHAR(255) NOT NULL,
+            role INT NOT NULL,
+            session_timeout INT DEFAULT 30,
+            session_expiration INT DEFAULT 72,
+            last_login TIMESTAMP
+        )
+    )";
+    m_pDB->executeQuery(createTableQuery);
+
+    std::string checkAdminQuery = "SELECT COUNT(*) FROM users WHERE role = 0";
+    auto result = m_pDB->fetchResults(checkAdminQuery);
+
+    if (result.empty() || result[0][0] == "0") {
+        std::string insertAdminQuery = "INSERT INTO users (username, password_hash, role, session_timeout, session_expiration) VALUES ('" +
+            INITIAL_ADMIN_USERNAME + "', '" + hashPassword(INITIAL_ADMIN_PASSWORD) + "', 0, 30, 72)";
+        m_pDB->executeQuery(insertAdminQuery);
+    }
+
+    return true;
+}
+
+// 对密码进行哈希处理
+std::string UserManager::hashPassword(const std::string& password) {
+    return std::to_string(std::hash<std::string>{}(password));
+}
+
+// 简单的加密和解密函数
+std::string UserManager::simpleEncryptDecrypt(const std::string& data, const std::string& key) {
+    std::string result = data;
+    for (size_t i = 0; i < data.size(); ++i) {
+        result[i] ^= key[i % key.size()];  // 简单异或加密
+    }
+    return result;
+}
+
+// 从会话文件加载会话信息
+bool UserManager::loadSession() {
+    std::ifstream sessionFile(getSessionFilePath(), std::ios::binary);
+    if (!sessionFile.is_open()) {
+        return false;
+    }
+
+    // 从文件读取加密数据
+    std::string encryptedData((std::istreambuf_iterator<char>(sessionFile)), std::istreambuf_iterator<char>());
+    sessionFile.close();
+
+    // 解密数据
+    std::string decryptedData = simpleEncryptDecrypt(encryptedData, "my_secret_key");
+
+    // 解析解密的数据
+    std::istringstream sessionData(decryptedData);
+    std::string username;
+	std::string password;
+    std::time_t lastLoginTime;
+    int timeoutMinutes;
+    int expirationHours;
+
+    sessionData >> username >> password >> lastLoginTime >> timeoutMinutes >> expirationHours;
+
+    // 验证时间戳有效性
+    auto now = std::chrono::system_clock::now();
+    auto lastLogin = std::chrono::system_clock::from_time_t(lastLoginTime);
+    auto sessionDuration = std::chrono::duration_cast<std::chrono::hours>(now - lastLogin);
+
+    if (sessionDuration > std::chrono::hours(expirationHours)) {
+        clearSession();
+        return false;
+    }
+
+    // 恢复会话数据
+    m_strCurrentUser = username;
+	m_strCurrentPass = password;
+    m_tpLastLogin = lastLogin;
+    m_tmSessionTimeout = std::chrono::minutes(timeoutMinutes);
+    m_tmSessionExpiration = std::chrono::hours(expirationHours);
+    m_isLoggedIn = true;
+    m_isRememberMe = true;
+    updateActivityTime();
+
+    return true;
+}
+
+// 保存会话信息到文件
+void UserManager::saveSession() {
+    if (!m_isRememberMe) {
+        clearSession();
+        return;
+    }
+
+    // 原始会话数据
+    std::stringstream sessionData;
+    std::time_t lastLoginTime = std::chrono::system_clock::to_time_t(m_tpLastLogin);
+    sessionData << m_strCurrentUser << " " << m_strCurrentPass << " " << lastLoginTime << " "
+        << m_tmSessionTimeout.count() << " " << m_tmSessionExpiration.count();
+
+    // 加密数据
+    std::string encryptedData = simpleEncryptDecrypt(sessionData.str(), "my_secret_key");
+
+    // 写入加密数据到文件
+    std::ofstream sessionFile(getSessionFilePath(), std::ios::binary);
+    if (sessionFile.is_open()) {
+        sessionFile << encryptedData;
+        sessionFile.close();
+    }
+}
+
+// 清除会话文件
+void UserManager::clearSession() {
+    std::remove(getSessionFilePath().c_str());
+}
+
+// 获取程序路径下的config文件夹路径
+std::string UserManager::getConfigFolderPath() {
+    char path[MAX_PATH];
+    GetModuleFileName(NULL, path, MAX_PATH);
+    std::string exePath = std::string(path).substr(0, std::string(path).find_last_of("\\/"));
+    std::string configPath = exePath + "\\Config\\";
+
+    // 检查并创建config文件夹
+    DWORD fileAttr = GetFileAttributes(configPath.c_str());
+    if (fileAttr == INVALID_FILE_ATTRIBUTES) {
+        CreateDirectory(configPath.c_str(), NULL);
+    }
+
+    return configPath;
+}
+
+// 获取session.dat文件路径
+std::string UserManager::getSessionFilePath() {
+    return getConfigFolderPath() + SESSION_FILE;
+}
+
+// 获取数据库文件路径
+std::string UserManager::getDatabaseFilePath() {
+    return getConfigFolderPath() + DATABASE_FILE;
+}
+
+// 登录方法
+bool UserManager::login(const std::string& username, const std::string& password, bool rememberMeFlag) {
+    std::string query = "SELECT username, password_hash, role, session_timeout, session_expiration FROM users WHERE username = '" + username + "'";
+    auto result = m_pDB->fetchResults(query);
+
+    if (result.empty() || result[0][1] != hashPassword(password)) {
+        std::cerr << "Login failed: Invalid username or password." << std::endl;
+        return false;
+    }
+
+    m_strCurrentUser = username;
+	m_strCurrentPass = password;
+    m_enCurrentUserRole = static_cast<UserRole>(std::stoi(result[0][2]));
+    m_tmSessionTimeout = std::chrono::minutes(std::stoi(result[0][3]));
+    m_tmSessionExpiration = std::chrono::hours(std::stoi(result[0][4]));
+    m_isLoggedIn = true;
+    m_isRememberMe = rememberMeFlag;
+    updateActivityTime();
+    m_tpLastLogin = std::chrono::system_clock::now();
+
+    std::string updateLoginTime = "UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE username = '" + username + "'";
+    m_pDB->executeQuery(updateLoginTime);
+
+    saveSession();
+    return true;
+}
+
+// 登出方法
+void UserManager::logout() {
+    if (m_isLoggedIn) {
+        std::cout << "User logged out: " << m_strCurrentUser << std::endl;
+        m_strCurrentUser.clear();
+		m_strCurrentPass.clear();
+        m_isLoggedIn = false;
+        m_isRememberMe = false;
+        clearSession();
+    }
+}
+
+// 返回当前用户的登录状态
+bool UserManager::isLoggedIn() const {
+    return m_isLoggedIn;
+}
+
+// 返回当前用户的记住登录状态
+bool UserManager::isRememberMe() const {
+	return m_isRememberMe;
+}
+
+// 创建新用户,仅超级管理员有权限
+bool UserManager::createUser(const std::string& username, const std::string& password, UserRole role,
+    std::chrono::minutes timeout, std::chrono::hours expiration) {
+    if (m_enCurrentUserRole != UserRole::SuperAdmin) {
+        std::cerr << "Only SuperAdmin can create new users." << std::endl;
+        return false;
+    }
+
+    std::string query = "INSERT INTO users (username, password_hash, role, session_timeout, session_expiration) VALUES ('" +
+        username + "', '" + hashPassword(password) + "', " + std::to_string(static_cast<int>(role)) + ", " +
+        std::to_string(timeout.count()) + ", " + std::to_string(expiration.count()) + ")";
+    return m_pDB->executeQuery(query);
+}
+
+// 删除用户,仅超级管理员有权限,且不能删除自己
+bool UserManager::deleteUser(const std::string& username) {
+    if (m_enCurrentUserRole != UserRole::SuperAdmin) {
+        std::cerr << "Only SuperAdmin can delete users." << std::endl;
+        return false;
+    }
+    if (username == m_strCurrentUser) {
+        std::cerr << "SuperAdmin cannot delete their own account." << std::endl;
+        return false;
+    }
+
+    std::string query = "DELETE FROM users WHERE username = '" + username + "'";
+    return m_pDB->executeQuery(query);
+}
+
+// 获取所有用户信息,仅超级管理员有权限
+std::vector<std::vector<std::string>> UserManager::getUsers() {
+    if (m_enCurrentUserRole != UserRole::SuperAdmin) {
+        std::cerr << "Only SuperAdmin can retrieve user data." << std::endl;
+        return {};
+    }
+
+    // 查询整个用户表
+    std::string query = "SELECT username, password_hash, role, session_timeout, session_expiration, last_login FROM users";
+    return m_pDB->fetchResults(query);
+}
+
+// 设置整个用户表的数据,仅超级管理员有权限
+bool UserManager::setUsers(const std::vector<std::vector<std::string>>& usersData) {
+    if (m_enCurrentUserRole != UserRole::SuperAdmin) {
+        std::cerr << "Only SuperAdmin can set user data." << std::endl;
+        return false;
+    }
+
+    // 清空用户表
+    std::string deleteQuery = "DELETE FROM users";
+    if (!m_pDB->executeQuery(deleteQuery)) {
+        std::cerr << "Failed to clear the users table." << std::endl;
+        return false;
+    }
+
+    // 插入新的用户数据
+    for (const auto& user : usersData) {
+        if (user.size() != 6) {
+            std::cerr << "Invalid data format for user. Each user must have 6 fields." << std::endl;
+            return false;
+        }
+
+        std::string insertQuery = "INSERT INTO users (username, password_hash, role, session_timeout, session_expiration, last_login) VALUES ('" +
+            user[0] + "', '" + user[1] + "', " + user[2] + ", " + user[3] + ", " + user[4] + ", '" + user[5] + "')";
+
+        if (!m_pDB->executeQuery(insertQuery)) {
+            std::cerr << "Failed to insert user: " << user[0] << std::endl;
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// 修改用户名,仅超级管理员有权限
+bool UserManager::changeUsername(const std::string& username, const std::string& newUsername) {
+    if (m_enCurrentUserRole != UserRole::SuperAdmin) {
+        std::cerr << "Only SuperAdmin can change usernames." << std::endl;
+        return false;
+    }
+
+    std::string query = "UPDATE users SET username = '" + newUsername + "' WHERE username = '" + username + "'";
+    bool success = m_pDB->executeQuery(query);
+
+    // 如果是当前登录用户修改自己的用户名,更新成员变量并保存会话文件
+    if (success && m_strCurrentUser == username) {
+        m_strCurrentUser = newUsername;
+
+        // 如果“记住密码”已启用,更新会话文件
+        if (m_isRememberMe) {
+            saveSession();
+        }
+    }
+    return success;
+}
+
+// 修改用户密码(仅允许当前用户或超级管理员)
+bool UserManager::changePassword(const std::string& username, const std::string& newPassword) {
+    if (username != m_strCurrentUser && m_enCurrentUserRole != UserRole::SuperAdmin) {
+        std::cerr << "Permission denied: Only the user or SuperAdmin can change passwords." << std::endl;
+        return false;
+    }
+
+    std::string query = "UPDATE users SET password_hash = '" + hashPassword(newPassword) +
+        "' WHERE username = '" + username + "'";
+    bool success = m_pDB->executeQuery(query);
+
+    // 如果是当前用户修改自己的密码,退出登录并清除会话文件
+    if (success && m_strCurrentUser == username) {
+        logout();
+        std::cout << "Password changed successfully. Please log in again." << std::endl;
+    }
+
+    return success;
+}
+
+// 更改用户角色,仅超级管理员有权限
+bool UserManager::changeUserRole(const std::string& username, UserRole newRole) {
+    if (m_enCurrentUserRole != UserRole::SuperAdmin) {
+        std::cerr << "Only SuperAdmin can change user roles." << std::endl;
+        return false;
+    }
+
+    // 防止管理员更改自己的角色
+    if (m_strCurrentUser == username) {
+        std::cerr << "SuperAdmin cannot change their own role." << std::endl;
+        return false;
+    }
+
+    std::string query = "UPDATE users SET role = " + std::to_string(static_cast<int>(newRole)) +
+        " WHERE username = '" + username + "'";
+    return m_pDB->executeQuery(query);
+}
+
+// 修改用户的 session_timeout,仅超级管理员有权限
+bool UserManager::changeUserSessionTimeout(const std::string& username, int newTimeoutMinutes) {
+    if (m_enCurrentUserRole != UserRole::SuperAdmin) {
+        std::cerr << "Only SuperAdmin can change session timeout." << std::endl;
+        return false;
+    }
+
+    std::string query = "UPDATE users SET session_timeout = " + std::to_string(newTimeoutMinutes) +
+        " WHERE username = '" + username + "'";
+    bool success = m_pDB->executeQuery(query);
+    // 如果是当前登录用户修改自己的超时设置,更新成员变量
+    if (success && m_strCurrentUser == username) {
+        m_tmSessionTimeout = std::chrono::minutes(newTimeoutMinutes);
+
+        if (m_isRememberMe) {
+            saveSession();
+        }
+    }
+    return success;
+}
+
+// 修改用户的 session_expiration,仅超级管理员有权限
+bool UserManager::changeUserSessionExpiration(const std::string& username, int newExpirationHours) {
+    if (m_enCurrentUserRole != UserRole::SuperAdmin) {
+        std::cerr << "Only SuperAdmin can change session expiration." << std::endl;
+        return false;
+    }
+
+    std::string query = "UPDATE users SET session_expiration = " + std::to_string(newExpirationHours) +
+        " WHERE username = '" + username + "'";
+    bool success = m_pDB->executeQuery(query);
+    // 如果是当前登录用户修改自己的过期设置,更新成员变量
+    if (success && m_strCurrentUser == username) {
+        m_tmSessionExpiration = std::chrono::hours(newExpirationHours);
+
+        if (m_isRememberMe) {
+            saveSession();
+        }
+    }
+    return success;
+}
+
+// 更新最后活动时间,用于无操作超时检测
+void UserManager::updateActivityTime() {
+    m_tpLastActivity = std::chrono::system_clock::now();
+    std::cout << "Activity updated at: " << std::chrono::system_clock::to_time_t(m_tpLastActivity) << std::endl;
+}
+
+// 设置无操作超时时间
+void UserManager::setSessionTimeout(std::chrono::minutes timeout) {
+    m_tmSessionTimeout = timeout;
+}
+
+// 检查是否超过无操作超时时间
+bool UserManager::isInactiveTimeout() const {
+    auto now = std::chrono::system_clock::now();
+    auto elapsedSeconds = std::chrono::duration_cast<std::chrono::seconds>(now - m_tpLastActivity).count();
+    return elapsedSeconds > m_tmSessionTimeout.count() * 60;
+}
+
+// 初始化无操作检测,包括设置全局鼠标和键盘钩子
+void UserManager::initializeIdleDetection(HWND hwnd) {
+    updateActivityTime();
+    m_hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, (HINSTANCE) nullptr, 0);
+    m_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, (HINSTANCE) nullptr, 0);
+    ::SetTimer(hwnd, 1, 60000, nullptr);
+}
+
+// 终止无操作检测,清除鼠标和键盘钩子
+void UserManager::terminateIdleDetection() {
+    if (m_hMouseHook) {
+        UnhookWindowsHookEx(m_hMouseHook);
+        m_hMouseHook = nullptr;
+    }
+    if (m_hKeyboardHook) {
+        UnhookWindowsHookEx(m_hKeyboardHook);
+        m_hKeyboardHook = nullptr;
+    }
+    ::KillTimer(nullptr, 1);
+}
+
+// 获取当前登录用户名
+std::string UserManager::getCurrentUser() const {
+	return m_strCurrentUser;
+}
+
+// 获取当前登录用户密码
+std::string UserManager::getCurrentPass() const {
+	return m_strCurrentPass;
+}
+
+// 获取当前登录用户角色
+UserRole UserManager::getCurrentUserRole() const {
+	return m_enCurrentUserRole;
+}
+
+// 获取当前登录用户的无操作超时时间
+std::chrono::minutes UserManager::getSessionTimeout() const {
+	return m_tmSessionTimeout;
+}
+
+// 获取当前登录用户的会话过期时间
+std::chrono::hours UserManager::getSessionExpiration() const {
+	return m_tmSessionExpiration;
+}
+
+// 全局鼠标钩子回调,记录活动时间
+LRESULT CALLBACK UserManager::LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
+    if (nCode == HC_ACTION) {
+        UserManager::getInstance().updateActivityTime();
+        std::cout << "Mouse event detected. Activity time updated." << std::endl;
+    }
+    return CallNextHookEx(nullptr, nCode, wParam, lParam);
+}
+
+// 全局键盘钩子回调,记录活动时间
+LRESULT CALLBACK UserManager::LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
+    if (nCode == HC_ACTION) {
+        UserManager::getInstance().updateActivityTime();
+        std::cout << "Keyboard event detected. Activity time updated." << std::endl;
+    }
+    return CallNextHookEx(nullptr, nCode, wParam, lParam);
+}
diff --git a/SourceCode/Bond/BondEq/DBManager/UserManager.h b/SourceCode/Bond/BondEq/DBManager/UserManager.h
new file mode 100644
index 0000000..37fd44b
--- /dev/null
+++ b/SourceCode/Bond/BondEq/DBManager/UserManager.h
@@ -0,0 +1,116 @@
+#ifndef USER_MANAGER_H
+#define USER_MANAGER_H
+
+#include <string>
+#include <memory>
+#include <chrono>
+#include <windows.h>
+#include "Database.h"
+
+// 用户角色定义
+enum class UserRole {
+    SuperAdmin = 0,     // 超级管理员
+    Engineer,           // 工程师
+    Operator            // 操作员
+};
+
+// 用户管理类,采用单例模式
+class UserManager {
+public:
+    static UserManager& getInstance();
+
+    UserManager(const UserManager&) = delete;
+    UserManager& operator=(const UserManager&) = delete;
+
+    // 用户操作
+    bool login(const std::string& username, const std::string& password, bool rememberMe = false);
+    void logout();
+    bool isLoggedIn() const;
+	bool isRememberMe() const;
+    bool createUser(const std::string& username, const std::string& password, UserRole role,
+        std::chrono::minutes timeout = std::chrono::minutes(30),
+        std::chrono::hours expiration = std::chrono::hours(72));
+    bool deleteUser(const std::string& username);
+    std::vector<std::vector<std::string>> getUsers();
+    bool setUsers(const std::vector<std::vector<std::string>>& usersData);
+    bool changeUsername(const std::string& username, const std::string& newUsername);
+    bool changePassword(const std::string& username, const std::string& newPassword);
+    bool changeUserRole(const std::string& username, UserRole newRole);
+    bool changeUserSessionTimeout(const std::string& username, int newTimeoutMinutes);
+    bool changeUserSessionExpiration(const std::string& username, int newExpirationHours);
+
+    // 会话文件操作
+    bool loadSession();     // 从会话文件加载会话信息
+    void saveSession();     // 保存会话信息到文件
+    void clearSession();    // 清除会话文件
+
+    // 配置文件夹路径管理
+    static std::string getConfigFolderPath();
+    static std::string getSessionFilePath();
+    static std::string getDatabaseFilePath();
+
+    // 更新最后活动时间(用于无操作超时检测)
+    void updateActivityTime();
+
+    // 设置用户的无操作超时时间
+    void setSessionTimeout(std::chrono::minutes timeout);
+
+    // 检查是否无操作超时
+    bool isInactiveTimeout() const;
+
+    // 初始化无操作检测(设置全局钩子和定时器)
+    void initializeIdleDetection(HWND hwnd);
+
+    // 终止无操作检测(清除钩子和定时器)
+    void terminateIdleDetection();
+
+	// 获取当前登录用户名
+	std::string getCurrentUser() const;
+
+	// 获取当前登录用户密码
+	std::string getCurrentPass() const;
+
+	// 获取当前登录用户角色
+	UserRole getCurrentUserRole() const;
+
+	// 获取当前登录用户的无操作超时时间
+	std::chrono::minutes getSessionTimeout() const;
+
+	// 获取当前登录用户的会话过期时间
+	std::chrono::hours getSessionExpiration() const;
+
+private:
+    UserManager();
+    ~UserManager();
+
+    // 初始化数据库连接和用户表
+    bool initializeDatabase();
+
+    // 哈希密码,用于加密用户密码
+    std::string hashPassword(const std::string& password);
+
+    // 加密和解密函数
+    std::string simpleEncryptDecrypt(const std::string& data, const std::string& key);
+
+    // 键盘和鼠标钩子函数
+    static LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam);
+    static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
+
+    // 属性定义
+    std::string m_strCurrentUser;                     // 当前登录用户名
+    std::string m_strCurrentPass;                     // 当前登录密码
+    UserRole m_enCurrentUserRole;                     // 当前登录用户角色
+    bool m_isLoggedIn;                                // 是否已登录
+    bool m_isRememberMe;                              // 是否记住登录状态
+
+    std::chrono::time_point<std::chrono::system_clock> m_tpLastLogin;     // 上次登录时间
+    std::chrono::time_point<std::chrono::system_clock> m_tpLastActivity;  // 最后活动时间
+    std::chrono::minutes m_tmSessionTimeout;          // 无操作超时时间
+    std::chrono::hours m_tmSessionExpiration;         // 会话过期时间
+    HHOOK m_hMouseHook;                               // 鼠标钩子句柄
+    HHOOK m_hKeyboardHook;                            // 键盘钩子句柄
+
+    std::unique_ptr<BL::Database> m_pDB;              // 数据库接口
+};
+
+#endif // USER_MANAGER_H
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/HmTab.cpp b/SourceCode/Bond/BondEq/HmTab.cpp
new file mode 100644
index 0000000..29e13c9
--- /dev/null
+++ b/SourceCode/Bond/BondEq/HmTab.cpp
@@ -0,0 +1,529 @@
+// HmTab.cpp: implementation of the CHmTab class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "HmTab.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CHmTab::CHmTab()
+{
+	m_hWnd = NULL;
+	m_crBkgnd = RGB(250, 250, 255);
+	m_nPaddingLeft = 28;
+	m_nPaddingBottom = 12;
+	m_nItemMarginLeft = 8;
+	m_crText[0] = RGB(88, 88, 88);
+	m_crText[1] = RGB(18, 18, 18);
+	m_pPressItem = nullptr;
+	m_pHighItem = nullptr;
+
+	LOGBRUSH lb;
+	lb.lbColor = RGB(225, 127, 39);
+	lb.lbHatch = 0;
+	lb.lbStyle = BS_SOLID;
+	DWORD iStyle = PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_SQUARE | PS_JOIN_MITER;
+	m_hPenUnder[0] = ExtCreatePen(iStyle, 3, &lb, 0, NULL);
+	lb.lbColor = RGB(225, 127, 39);
+	m_hPenUnder[1] = ExtCreatePen(iStyle, 2, &lb, 0, NULL);
+	lb.lbColor = RGB(223, 226, 230);
+	m_hPenUnderWnd = ExtCreatePen(iStyle, 1, &lb, 0, NULL);
+	m_nCurSel = 0;
+}
+
+CHmTab::~CHmTab()
+{
+	if (m_hPenUnder[0] != nullptr) {
+		::DeleteObject(m_hPenUnder[0]);
+	}
+	if (m_hPenUnder[1] != nullptr) {
+		::DeleteObject(m_hPenUnder[1]);
+	}
+
+	if (m_hPenUnderWnd != nullptr) {
+		::DeleteObject(m_hPenUnderWnd);
+	}
+}
+
+BOOL CHmTab::RegisterWndClass()
+{
+	WNDCLASS wc;
+	wc.lpszClassName = BYHMTAB_CLASS;
+	wc.hInstance = AfxGetInstanceHandle();
+	wc.lpfnWndProc = WindowProc;
+	wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+	wc.hIcon = 0;
+	wc.lpszMenuName = NULL;
+	wc.hbrBackground = NULL;
+	wc.style = CS_GLOBALCLASS|CS_DBLCLKS;
+	wc.cbClsExtra = 0;
+	wc.cbWndExtra = 0;
+	
+	// 注册自定义类
+	return (::RegisterClass(&wc) != 0);
+}
+
+CHmTab* CHmTab::Hook(HWND hWnd)
+{
+	CHmTab* pHmTab = (CHmTab*)GetProp(hWnd, BYSTAG_HMTAB);
+	if(pHmTab == NULL)
+	{
+		pHmTab = new CHmTab;
+		pHmTab->m_hWnd = hWnd;
+
+		SetProp(hWnd, BYSTAG_HMTAB, (HANDLE)pHmTab);
+	}
+	
+	return pHmTab;
+}
+
+void CHmTab::Release()
+{
+	// delete
+	delete this;
+}
+
+void CHmTab::SetPaddingLeft(int value)
+{
+	m_nPaddingLeft = value;
+}
+
+void CHmTab::SetItemMarginLeft(int value)
+{
+	m_nItemMarginLeft = value;
+}
+
+void CHmTab::SetTextColor(COLORREF color1, COLORREF color2)
+{
+	m_crText[0] = color1;
+	m_crText[1] = color2;
+	InvalidateRect(m_hWnd, NULL, TRUE);
+}
+
+int CHmTab::AddItem(const char* pszText,BOOL bUpdate/* = TRUE*/)
+{
+	HMTABITEM item;
+	memset(&item, 0, sizeof(HMTABITEM));
+	strcpy_s(item.szText, MHITEM_TEXT_MAX, pszText);
+	m_items.push_back(item);
+
+	if (bUpdate) {
+		InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+
+	return 0;
+}
+
+int CHmTab::DeleteItem(const char* pszText, BOOL bUpdate/* = TRUE*/)
+{
+	for (auto iter = m_items.begin(); iter != m_items.end(); iter++) {
+		if (strcmp((*iter).szText, pszText) == 0) {
+			m_items.erase(iter);
+			break;
+		}
+	}
+
+	if (bUpdate) {
+		InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+
+	return 0;
+}
+
+void CHmTab::Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1/* = 0*/, DWORD_PTR dwData2/* = 0*/)
+{
+	HWND hParent;
+	hParent = GetParent(m_hWnd);
+	if (hParent != NULL) {
+		BYHMTAB_NMHDR iii_nmhdr;
+		iii_nmhdr.nmhdr.hwndFrom = m_hWnd;
+		iii_nmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
+		iii_nmhdr.nmhdr.code = nCode;
+		iii_nmhdr.dwData = dwData;
+		iii_nmhdr.dwData1 = dwData1;
+		iii_nmhdr.dwData2 = dwData2;
+		SendMessage(hParent, WM_NOTIFY, (WPARAM)iii_nmhdr.nmhdr.idFrom, (LPARAM)&iii_nmhdr);
+	}
+}
+
+////////////////////////////////
+// 拦截窗口消息函数
+LRESULT CALLBACK CHmTab::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)   
+{
+	CHmTab* pHmTab = (CHmTab *)GetProp(hWnd, BYSTAG_HMTAB);
+	if(pHmTab == NULL && uMsg != WM_NCCREATE)
+	{
+		return ::DefWindowProc(hWnd, uMsg, wParam, lParam);   
+	}
+
+	
+	// 如果Hook则响应消息
+	ASSERT(hWnd);
+	switch(uMsg)   
+	{
+	case WM_NCCREATE:
+		return OnNcCreate(hWnd, wParam, lParam);
+
+	case WM_DESTROY:
+		return pHmTab->OnDestroy(wParam, lParam);
+
+	case WM_PAINT:
+		return pHmTab->OnPaint(wParam, lParam);
+
+	case WM_TIMER:
+		return pHmTab->OnTimer(wParam, lParam);
+
+	case WM_MOUSEMOVE:
+		return pHmTab->OnMouseMove(wParam, lParam);
+
+	case WM_LBUTTONDOWN:
+		return pHmTab->OnLButtonDown(wParam, lParam);
+
+	case WM_SETCURSOR:
+		return pHmTab->OnSetCursor(wParam, lParam);
+
+	case WM_SIZE:
+		return pHmTab->OnSize(wParam, lParam);
+
+	case WM_GETDLGCODE:
+		return DLGC_WANTALLKEYS;
+
+	default:
+		break;
+	}
+	
+	return ::DefWindowProc(hWnd, uMsg, wParam, lParam);   
+}  
+
+///////////////////////////////
+// WM_NCCREATE
+// 窗口创建前的初始化工作
+LRESULT CHmTab::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+	CHmTab* pHmTab = (CHmTab *)GetProp(hWnd, BYSTAG_HMTAB);
+	ASSERT(pHmTab == NULL);
+
+	Hook(hWnd);
+	return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_DESTROY
+LRESULT CHmTab::OnDestroy(WPARAM wParam, LPARAM lParam)
+{
+	Release();
+	return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_TIMER
+LRESULT CHmTab::OnTimer(WPARAM wParam, LPARAM lParam)
+{
+	if (wParam == 1) {
+		POINT pt;
+		GetCursorPos(&pt);
+		::ScreenToClient(m_hWnd, &pt);
+
+		HMTABITEM* pLastHighItem = m_pHighItem;
+		HighTest(pt, m_pHighItem, nullptr);
+		if (m_pHighItem != pLastHighItem) {
+			::InvalidateRect(m_hWnd, NULL, TRUE);
+		}
+
+		if (m_pHighItem == nullptr) {
+			::KillTimer(m_hWnd, 1);
+		}
+	}
+
+	return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_MOUSEMOVE
+LRESULT CHmTab::OnMouseMove(WPARAM wParam, LPARAM lParam)
+{
+	POINT pt;
+	pt.x = LOWORD(lParam);
+	pt.y = HIWORD(lParam);
+
+	HMTABITEM* pLastHighItem = m_pHighItem;
+	int nHitCode = HighTest(pt, m_pHighItem, nullptr);
+	if (m_pHighItem != pLastHighItem) {
+		RECT rcClient;
+		GetClientRect(m_hWnd, &rcClient);
+		::InvalidateRect(m_hWnd, &rcClient, TRUE);
+	}
+	if (m_pHighItem != NULL) {
+		::KillTimer(m_hWnd, 1);
+		::SetTimer(m_hWnd, 1, 100, NULL);
+	}
+
+	::SetProp(m_hWnd, HMTAB_HITCODETEST, (HANDLE)(__int64)nHitCode);
+	return ::DefWindowProc(m_hWnd, WM_MOUSEMOVE, wParam, lParam);
+}
+
+/*
+ * WM_LBUTTONDOWN
+ * 鼠标左键按下
+ */
+LRESULT CHmTab::OnLButtonDown(WPARAM wParam, LPARAM lParam)
+{
+	POINT pt, ptNew;
+	pt.x = LOWORD(lParam);
+	pt.y = HIWORD(lParam);
+
+	BOOL bButtonUp = FALSE;
+	int nClickIndex = -1;
+	HighTest(pt, m_pPressItem, &nClickIndex);
+	if (m_pPressItem != NULL) {
+		m_pHighItem = NULL;
+		::InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+
+
+	// 捕捉鼠标消息,检测是否拖动
+	HMTABITEM* pPressItem = NULL;
+	if (m_pPressItem != NULL) {
+		::KillTimer(m_hWnd, 1);
+		if (::GetCapture() == NULL) {
+			SetCapture(m_hWnd);
+			ASSERT(m_hWnd == GetCapture());
+			AfxLockTempMaps();
+			for (;;)
+			{
+				MSG msg;
+				VERIFY(::GetMessage(&msg, NULL, 0, 0));
+
+				if (GetCapture() != m_hWnd) break;
+
+				switch (msg.message)
+				{
+				case WM_MOUSEMOVE:
+					ptNew = msg.pt;
+					::ScreenToClient(m_hWnd, &ptNew);
+					HighTest(ptNew, pPressItem, &nClickIndex);
+					if (pPressItem != m_pPressItem) {
+						m_pPressItem = nullptr;
+						::InvalidateRect(m_hWnd, NULL, TRUE);
+					}
+					break;
+
+				case WM_LBUTTONUP:
+					ptNew = msg.pt;
+					::ScreenToClient(m_hWnd, &ptNew);
+					HighTest(ptNew, pPressItem, &nClickIndex);
+					if (m_pPressItem != nullptr && pPressItem == m_pPressItem) {
+						m_nCurSel = nClickIndex;
+						bButtonUp = TRUE;
+					}
+					goto ExitLoop;
+
+				case WM_KEYDOWN:
+					if (msg.wParam == VK_ESCAPE) {
+						goto ExitLoop;
+					}
+					break;
+
+				default:
+					DispatchMessage(&msg);
+					break;
+				}
+			}
+
+		ExitLoop:
+			m_pPressItem = NULL;
+			ReleaseCapture();
+			::InvalidateRect(m_hWnd, NULL, TRUE);
+
+			if (bButtonUp) {
+				Notify((int)BYHMTAB_SEL_CHANGED, m_nCurSel);
+			}
+
+			AfxUnlockTempMaps(FALSE);
+		}
+	}
+
+
+	return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_SETCURSOR
+LRESULT CHmTab::OnSetCursor(WPARAM wParam, LPARAM lParam)
+{
+	int nHitCode = (int)(__int64)GetProp(m_hWnd, HMTAB_HITCODETEST);
+	switch (nHitCode)
+	{
+	case HMTAB_HT_NOWHERE:
+	case HMTAB_HT_ITEM:
+		SetCursor(::LoadCursor(NULL, IDC_ARROW));
+		return TRUE;
+
+	case HMTAB_HT_HIGT_ITEM:
+		SetCursor(::LoadCursor(NULL, IDC_HAND));
+		return TRUE;
+
+	default:
+		break;
+	}
+
+	return ::DefWindowProc(m_hWnd, WM_SETCURSOR, wParam, lParam);
+}
+
+/*
+ * WM_SIZE
+ */
+LRESULT CHmTab::OnSize(WPARAM wParam, LPARAM lParam)
+{
+	::InvalidateRect(m_hWnd, NULL, TRUE);
+	return ::DefWindowProc(m_hWnd, WM_SIZE, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_PAINT
+LRESULT CHmTab::OnPaint(WPARAM wParam, LPARAM lParam)
+{
+	HDC hDC, hMemDC;
+	HBITMAP hBitmap;
+	RECT rcClient;
+	CString strText;
+	HFONT hFont1, hFont2;
+	HBRUSH hBrushBK;
+
+
+	// BeginPaint
+	PAINTSTRUCT ps;
+	hDC = BeginPaint(m_hWnd, &ps);
+	GetClientRect(m_hWnd, &rcClient);
+
+	hMemDC = ::CreateCompatibleDC(hDC);
+	hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left,
+		rcClient.bottom - rcClient.top);
+	::SelectObject(hMemDC, hBitmap);
+	::SetBkMode(hMemDC, TRANSPARENT);
+
+
+	HFONT hFontDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+	CFont* pFont = CFont::FromHandle(hFontDefault);
+	LOGFONT lf;
+	pFont->GetLogFont(&lf);
+	hFont1 = ::CreateFontIndirect(&lf);
+	lf.lfHeight -= 5;
+	hFont2 = ::CreateFontIndirect(&lf);
+
+
+	// 背景颜色
+	hBrushBK = CreateSolidBrush(m_crBkgnd);
+	::FillRect(hMemDC, &rcClient, hBrushBK);
+	DeleteObject(hBrushBK);
+
+
+	SelectObject(hMemDC, m_hPenUnderWnd);
+	::MoveToEx(hMemDC, rcClient.left, rcClient.bottom - 2, NULL);
+	::LineTo(hMemDC, rcClient.right, rcClient.bottom - 2);
+
+
+
+	// 绘制子项
+	SIZE sizeItem;
+	RECT rcItem, rcText;
+	rcItem.top = rcClient.top;
+	rcItem.bottom = rcClient.bottom-1;
+	rcItem.left = m_nPaddingLeft;
+	int index = 0;
+	for (int i = 0; i < m_items.size(); i++) {
+		auto& item = m_items.at(i);
+		::SelectObject(hMemDC, i == m_nCurSel ? hFont2 : hFont1);
+		::SetTextColor(hMemDC, i == m_nCurSel ? m_crText[1] : m_crText[0]);
+		::GetTextExtentPoint32(hMemDC, item.szText, (int)strlen(item.szText), &sizeItem);
+		rcItem.left += m_nItemMarginLeft;
+		rcItem.right = rcItem.left + (int)sizeItem.cx;
+
+		::CopyRect(&rcText, &rcItem);
+		rcText.bottom -= m_nPaddingBottom;
+		::DrawText(hMemDC, item.szText, (int)strlen(item.szText), &rcText,
+			DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS);
+		::CopyRect(&item.rect, &rcItem);
+
+
+		// 下划线?
+		if (i == m_nCurSel || &item == m_pHighItem) {
+			HPEN hOldPen = (HPEN)::SelectObject(hMemDC, i == m_nCurSel ? m_hPenUnder[0] : m_hPenUnder[1]);
+			::MoveToEx(hMemDC, item.rect.left, item.rect.bottom - 3, NULL);
+			::LineTo(hMemDC, item.rect.right, item.rect.bottom - 3);
+			::SelectObject(hMemDC, hOldPen);
+		}
+
+
+		index++;
+		rcItem.left = rcItem.right;
+	}
+	::DeleteObject(hFont1);
+	::DeleteObject(hFont2);
+
+
+	// EndPaint
+	::BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
+		hMemDC, 0, 0, SRCCOPY);
+	EndPaint(m_hWnd, &ps);
+	::DeleteObject(hBitmap);
+	::DeleteDC(hMemDC);
+
+
+	return 1;
+}
+
+void CHmTab::SetBkgndColor(COLORREF cr)
+{
+	m_crBkgnd = cr;
+}
+
+/*
+ * 检测坐标点所在的项
+ * 返回, TYGTLITEM
+ */
+int CHmTab::HighTest(POINT pt, OUT HMTABITEM*& pItem, int* pnIndex)
+{
+	// 检测是否在某个子项
+	int nRet = HMTAB_HT_NOWHERE;
+	pItem = NULL;
+	for (int i = 0; i < m_items.size(); i++) {
+		auto& item = m_items.at(i);
+		if (::PtInRect(&item.rect, pt)) {
+			pItem = &item;
+			nRet = pItem == m_pHighItem ? HMTAB_HT_HIGT_ITEM : HMTAB_HT_ITEM;
+			if (pnIndex != nullptr) *pnIndex = i;
+			break;
+		}
+	}
+
+
+	return nRet;
+}
+
+int CHmTab::GetCurSel()
+{
+	return m_nCurSel;
+}
+
+void CHmTab::SetCurSel(int index)
+{
+	if (0 <= index && index <= m_items.size()) {
+		m_nCurSel = index;
+		InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+}
+
+int CHmTab::GetItemCount()
+{
+	return (int)m_items.size();
+}
diff --git a/SourceCode/Bond/BondEq/HmTab.h b/SourceCode/Bond/BondEq/HmTab.h
new file mode 100644
index 0000000..600b5b1
--- /dev/null
+++ b/SourceCode/Bond/BondEq/HmTab.h
@@ -0,0 +1,130 @@
+// HmTab.h: interface for the CHmTab class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_HMTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
+#define AFX_HMTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_
+
+
+#pragma comment(lib, "Msimg32.lib")			// TransparentBlt
+#include <vector>
+
+
+
+//====== HmTab =====================================================
+
+#ifndef NOHMTAB
+
+#ifdef _WIN32
+
+#define BYHMTAB_CLASSA       "BYHmTab"
+#define BYHMTAB_CLASSW       L"BYHmTab"
+
+#ifdef UNICODE
+#define  BYHMTAB_CLASS       BYHMTAB_CLASSW
+#else
+#define  BYHMTAB_CLASS       BYHMTAB_CLASSA
+#endif
+
+#else
+#define BYHMTAB_CLASS        "BYHmTab"
+#endif
+
+
+#define BYSTAG_HMTAB		 _T("ISHMTAB")
+
+
+//====== WM_NOTIFY codes (NMHDR.code values) ==================================
+#define BYHMTAB_FIRST				 (0U-1190U)       //
+#define BYHMTAB_LAST				 (0U-1150U)
+#define BYHMTAB_SEL_CHANGED	 		 (BYHMTAB_FIRST - 1)
+
+
+
+
+typedef struct tagBYHMTAB_NMHDR
+{
+	NMHDR		nmhdr;
+	DWORD_PTR	dwData;
+	DWORD_PTR	dwData1;
+	DWORD_PTR	dwData2;
+} BYHMTAB_NMHDR;
+
+#define MHITEM_TEXT_MAX		64
+
+typedef struct tagHMTABITEM
+{
+	int id;
+	char szText[MHITEM_TEXT_MAX];
+	RECT rect;
+} HMTABITEM;
+
+#define HMTAB_HITCODETEST			_T("HitCode")
+#define HMTAB_HT_NOWHERE			0x1
+#define HMTAB_HT_ITEM				0x2
+#define HMTAB_HT_HIGT_ITEM			0x4
+
+
+#endif
+
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+class CHmTab
+{
+public:
+	CHmTab();
+	virtual ~CHmTab();
+
+public:
+	static BOOL RegisterWndClass();
+	static CHmTab* Hook(HWND hWnd);
+	void Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1 = 0, DWORD_PTR dwData2 = 0);
+	void Release();
+	void SetBkgndColor(COLORREF cr);
+	static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+	static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
+	LRESULT OnDestroy(WPARAM wParam, LPARAM lParam);
+	LRESULT OnTimer(WPARAM wParam, LPARAM lParam);
+	LRESULT OnPaint(WPARAM wParam, LPARAM lParam);
+	LRESULT OnSetCursor(WPARAM wParam, LPARAM lParam);
+	LRESULT OnSize(WPARAM wParam, LPARAM lParam);
+	LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
+	LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam);
+
+
+public:
+	void SetPaddingLeft(int value);
+	void SetItemMarginLeft(int value);
+	void SetTextColor(COLORREF color1, COLORREF color2);
+	int AddItem(const char* pszText, BOOL bUpdate = TRUE);
+	int DeleteItem(const char* pszText, BOOL bUpdate = TRUE);
+	int HighTest(POINT pt, OUT HMTABITEM*& pItem, int* pnIndex);
+	int GetCurSel();
+	void SetCurSel(int index);
+	int GetItemCount();
+
+
+private:
+	HWND		m_hWnd;
+	COLORREF m_crBkgnd;
+
+private:
+	int m_nCurSel;
+	std::vector< HMTABITEM > m_items;
+	HMTABITEM* m_pHighItem;
+	HMTABITEM* m_pPressItem;
+	int m_nPaddingLeft;
+	int m_nPaddingBottom;
+	int m_nItemMarginLeft;
+	COLORREF m_crText[2];
+	HPEN m_hPenUnder[2];
+	HPEN m_hPenUnderWnd;
+};
+
+#endif // !defined(AFX_HMTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
diff --git a/SourceCode/Bond/BondEq/HmVerticalTab.cpp b/SourceCode/Bond/BondEq/HmVerticalTab.cpp
new file mode 100644
index 0000000..940ba53
--- /dev/null
+++ b/SourceCode/Bond/BondEq/HmVerticalTab.cpp
@@ -0,0 +1,576 @@
+// HmVerticalTab.cpp: implementation of the CHmVerticalTab class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "HmVerticalTab.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CHmVerticalTab::CHmVerticalTab()
+{
+	m_hWnd = NULL;
+	m_crBkgnd = RGB(250, 250, 255);
+	m_nPaddingTop = 12;
+	m_nItemMarginTop = 1;
+	m_crText[0] = RGB(17, 14, 39);
+	m_crText[1] = RGB(255, 255, 255);
+	m_crItemBkgnd[0] = RGB(67, 153, 233);
+	m_crItemBkgnd[1] = RGB(188, 219, 248);
+	m_hbrItemBkgnd[0] = CreateSolidBrush(m_crItemBkgnd[0]);
+	m_hbrItemBkgnd[1] = CreateSolidBrush(m_crItemBkgnd[1]);
+	m_pPressItem = nullptr;
+	m_pHighItem = nullptr;
+
+	LOGBRUSH lb;
+	lb.lbColor = RGB(225, 127, 39);
+	lb.lbHatch = 0;
+	lb.lbStyle = BS_SOLID;
+	DWORD iStyle = PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_SQUARE | PS_JOIN_MITER;
+	m_hPenUnder[0] = ExtCreatePen(iStyle, 3, &lb, 0, NULL);
+	lb.lbColor = RGB(225, 127, 39);
+	m_hPenUnder[1] = ExtCreatePen(iStyle, 2, &lb, 0, NULL);
+	lb.lbColor = RGB(223, 226, 230);
+	m_hPenUnderWnd = ExtCreatePen(iStyle, 1, &lb, 0, NULL);
+	m_nCurSel = 0;
+	m_nItemHeight = 36;
+	m_bShowHightLine = FALSE;
+}
+
+CHmVerticalTab::~CHmVerticalTab()
+{
+	if (m_hPenUnder[0] != nullptr) {
+		::DeleteObject(m_hPenUnder[0]);
+	}
+	if (m_hPenUnder[1] != nullptr) {
+		::DeleteObject(m_hPenUnder[1]);
+	}
+
+	if (m_hPenUnderWnd != nullptr) {
+		::DeleteObject(m_hPenUnderWnd);
+	}
+}
+
+BOOL CHmVerticalTab::RegisterWndClass()
+{
+	WNDCLASS wc;
+	wc.lpszClassName = HMVERTICALTAB_CLASS;
+	wc.hInstance = AfxGetInstanceHandle();
+	wc.lpfnWndProc = WindowProc;
+	wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+	wc.hIcon = 0;
+	wc.lpszMenuName = NULL;
+	wc.hbrBackground = NULL;
+	wc.style = CS_GLOBALCLASS|CS_DBLCLKS;
+	wc.cbClsExtra = 0;
+	wc.cbWndExtra = 0;
+	
+	// 注册自定义类
+	return (::RegisterClass(&wc) != 0);
+}
+
+CHmVerticalTab* CHmVerticalTab::Hook(HWND hWnd)
+{
+	CHmVerticalTab* pHmTab = (CHmVerticalTab*)GetProp(hWnd, TAG_HMVERTICALTAB);
+	if(pHmTab == NULL)
+	{
+		pHmTab = new CHmVerticalTab();
+		pHmTab->m_hWnd = hWnd;
+
+		SetProp(hWnd, TAG_HMVERTICALTAB, (HANDLE)pHmTab);
+	}
+	
+	return pHmTab;
+}
+
+void CHmVerticalTab::Release()
+{
+	::DeleteObject(m_hbrItemBkgnd[0]);
+	::DeleteObject(m_hbrItemBkgnd[1]);
+
+	// delete
+	delete this;
+}
+
+void CHmVerticalTab::SetPaddingTop(int value)
+{
+	m_nPaddingTop = value;
+}
+
+void CHmVerticalTab::SetItemMarginTop(int value)
+{
+	m_nItemMarginTop = value;
+}
+
+void CHmVerticalTab::SetTextColor(COLORREF color1, COLORREF color2)
+{
+	m_crText[0] = color1;
+	m_crText[1] = color2;
+	InvalidateRect(m_hWnd, NULL, TRUE);
+}
+
+void CHmVerticalTab::SetItemBkgndColor(COLORREF color1, COLORREF color2)
+{
+	m_crItemBkgnd[0] = color1;
+	m_crItemBkgnd[1] = color2;
+	::DeleteObject(m_hbrItemBkgnd[0]);
+	::DeleteObject(m_hbrItemBkgnd[1]);
+	m_hbrItemBkgnd[0] = CreateSolidBrush(m_crItemBkgnd[0]);
+	m_hbrItemBkgnd[1] = CreateSolidBrush(m_crItemBkgnd[1]);
+
+	InvalidateRect(m_hWnd, NULL, TRUE);
+}
+
+void CHmVerticalTab::SetHightLineVisible(BOOL bVisible)
+{
+	m_bShowHightLine = bVisible;
+}
+
+int CHmVerticalTab::AddItem(const char* pszText, void* pContext/* = nullptr*/, BOOL bUpdate/* = TRUE*/)
+{
+	HMVERTICALTABITEM item;
+	memset(&item, 0, sizeof(HMVERTICALTABITEM));
+	strcpy_s(item.szText, HMVERTICALTAB_ITEM_TEXT_MAX, pszText);
+	item.context = pContext;
+	m_items.push_back(item);
+
+	if (bUpdate) {
+		InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+
+	return 0;
+}
+
+int CHmVerticalTab::DeleteItem(const char* pszText, BOOL bUpdate/* = TRUE*/)
+{
+	for (auto iter = m_items.begin(); iter != m_items.end(); iter++) {
+		if (strcmp((*iter).szText, pszText) == 0) {
+			m_items.erase(iter);
+			break;
+		}
+	}
+
+	if (bUpdate) {
+		InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+
+	return 0;
+}
+
+void* CHmVerticalTab::GetContext(unsigned int index)
+{
+	if (index >= m_items.size()) return nullptr;
+	auto& item = m_items.at(index);
+	return item.context;
+}
+
+void CHmVerticalTab::Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1/* = 0*/, DWORD_PTR dwData2/* = 0*/)
+{
+	HWND hParent;
+	hParent = GetParent(m_hWnd);
+	if (hParent != NULL) {
+		HMVERTICALTAB_NMHDR tab_nmhdr;
+		tab_nmhdr.nmhdr.hwndFrom = m_hWnd;
+		tab_nmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
+		tab_nmhdr.nmhdr.code = nCode;
+		tab_nmhdr.dwData = dwData;
+		tab_nmhdr.dwData1 = dwData1;
+		tab_nmhdr.dwData2 = dwData2;
+		SendMessage(hParent, WM_NOTIFY, (WPARAM)tab_nmhdr.nmhdr.idFrom, (LPARAM)&tab_nmhdr);
+	}
+}
+
+////////////////////////////////
+// 拦截窗口消息函数
+LRESULT CALLBACK CHmVerticalTab::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+	CHmVerticalTab* pHmTab = (CHmVerticalTab *)GetProp(hWnd, TAG_HMVERTICALTAB);
+	if(pHmTab == NULL && uMsg != WM_NCCREATE)
+	{
+		return ::DefWindowProc(hWnd, uMsg, wParam, lParam);   
+	}
+
+	
+	// 如果Hook则响应消息
+	ASSERT(hWnd);
+	switch(uMsg)   
+	{
+	case WM_NCCREATE:
+		return OnNcCreate(hWnd, wParam, lParam);
+
+	case WM_DESTROY:
+		return pHmTab->OnDestroy(wParam, lParam);
+
+	case WM_PAINT:
+		return pHmTab->OnPaint(wParam, lParam);
+
+	case WM_TIMER:
+		return pHmTab->OnTimer(wParam, lParam);
+
+	case WM_MOUSEMOVE:
+		return pHmTab->OnMouseMove(wParam, lParam);
+
+	case WM_LBUTTONDOWN:
+		return pHmTab->OnLButtonDown(wParam, lParam);
+
+	case WM_SETCURSOR:
+		return pHmTab->OnSetCursor(wParam, lParam);
+
+	case WM_SIZE:
+		return pHmTab->OnSize(wParam, lParam);
+
+	case WM_GETDLGCODE:
+		return DLGC_WANTALLKEYS;
+
+	default:
+		break;
+	}
+	
+	return ::DefWindowProc(hWnd, uMsg, wParam, lParam);   
+}  
+
+///////////////////////////////
+// WM_NCCREATE
+// 窗口创建前的初始化工作
+LRESULT CHmVerticalTab::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+	CHmVerticalTab* pHmTab = (CHmVerticalTab *)GetProp(hWnd, TAG_HMVERTICALTAB);
+	ASSERT(pHmTab == NULL);
+
+	Hook(hWnd);
+	return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_DESTROY
+LRESULT CHmVerticalTab::OnDestroy(WPARAM wParam, LPARAM lParam)
+{
+	Release();
+	return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_TIMER
+LRESULT CHmVerticalTab::OnTimer(WPARAM wParam, LPARAM lParam)
+{
+	if (wParam == 1) {
+		POINT pt;
+		GetCursorPos(&pt);
+		::ScreenToClient(m_hWnd, &pt);
+
+		HMVERTICALTABITEM* pLastHighItem = m_pHighItem;
+		HighTest(pt, m_pHighItem, nullptr);
+		if (m_pHighItem != pLastHighItem) {
+			::InvalidateRect(m_hWnd, NULL, TRUE);
+		}
+
+		if (m_pHighItem == nullptr) {
+			::KillTimer(m_hWnd, 1);
+		}
+	}
+
+	return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_MOUSEMOVE
+LRESULT CHmVerticalTab::OnMouseMove(WPARAM wParam, LPARAM lParam)
+{
+	POINT pt;
+	pt.x = LOWORD(lParam);
+	pt.y = HIWORD(lParam);
+
+	HMVERTICALTABITEM* pLastHighItem = m_pHighItem;
+	int nHitCode = HighTest(pt, m_pHighItem, nullptr);
+	if (m_pHighItem != pLastHighItem) {
+		RECT rcClient;
+		GetClientRect(m_hWnd, &rcClient);
+		::InvalidateRect(m_hWnd, &rcClient, TRUE);
+	}
+	if (m_pHighItem != NULL) {
+		::KillTimer(m_hWnd, 1);
+		::SetTimer(m_hWnd, 1, 100, NULL);
+	}
+
+	::SetProp(m_hWnd, HMTAB_HITCODETEST, (HANDLE)(__int64)nHitCode);
+	return ::DefWindowProc(m_hWnd, WM_MOUSEMOVE, wParam, lParam);
+}
+
+/*
+ * WM_LBUTTONDOWN
+ * 鼠标左键按下
+ */
+LRESULT CHmVerticalTab::OnLButtonDown(WPARAM wParam, LPARAM lParam)
+{
+	POINT pt, ptNew;
+	pt.x = LOWORD(lParam);
+	pt.y = HIWORD(lParam);
+
+	BOOL bButtonUp = FALSE;
+	int nClickIndex = -1;
+	HighTest(pt, m_pPressItem, &nClickIndex);
+	if (m_pPressItem != NULL) {
+		m_pHighItem = NULL;
+		::InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+
+
+	// 捕捉鼠标消息,检测是否拖动
+	HMVERTICALTABITEM* pPressItem = NULL;
+	if (m_pPressItem != NULL) {
+		::KillTimer(m_hWnd, 1);
+		if (::GetCapture() == NULL) {
+			SetCapture(m_hWnd);
+			ASSERT(m_hWnd == GetCapture());
+			AfxLockTempMaps();
+			for (;;)
+			{
+				MSG msg;
+				VERIFY(::GetMessage(&msg, NULL, 0, 0));
+
+				if (GetCapture() != m_hWnd) break;
+
+				switch (msg.message)
+				{
+				case WM_MOUSEMOVE:
+					ptNew = msg.pt;
+					::ScreenToClient(m_hWnd, &ptNew);
+					HighTest(ptNew, pPressItem, &nClickIndex);
+					if (pPressItem != m_pPressItem) {
+						m_pPressItem = nullptr;
+						::InvalidateRect(m_hWnd, NULL, TRUE);
+					}
+					break;
+
+				case WM_LBUTTONUP:
+					ptNew = msg.pt;
+					::ScreenToClient(m_hWnd, &ptNew);
+					HighTest(ptNew, pPressItem, &nClickIndex);
+					if (m_pPressItem != nullptr && pPressItem == m_pPressItem) {
+						m_nCurSel = nClickIndex;
+						bButtonUp = TRUE;
+					}
+					goto ExitLoop;
+
+				case WM_KEYDOWN:
+					if (msg.wParam == VK_ESCAPE) {
+						goto ExitLoop;
+					}
+					break;
+
+				default:
+					DispatchMessage(&msg);
+					break;
+				}
+			}
+
+		ExitLoop:
+			m_pPressItem = NULL;
+			ReleaseCapture();
+			::InvalidateRect(m_hWnd, NULL, TRUE);
+
+			if (bButtonUp) {
+				Notify((int)HMVERTICALTAB_SEL_CHANGED, m_nCurSel);
+			}
+
+			AfxUnlockTempMaps(FALSE);
+		}
+	}
+
+
+	return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_SETCURSOR
+LRESULT CHmVerticalTab::OnSetCursor(WPARAM wParam, LPARAM lParam)
+{
+	int nHitCode = (int)(__int64)GetProp(m_hWnd, HMTAB_HITCODETEST);
+	switch (nHitCode)
+	{
+	case HMTAB_HT_NOWHERE:
+	case HMTAB_HT_ITEM:
+		SetCursor(::LoadCursor(NULL, IDC_ARROW));
+		return TRUE;
+
+	case HMTAB_HT_HIGT_ITEM:
+		SetCursor(::LoadCursor(NULL, IDC_HAND));
+		return TRUE;
+
+	default:
+		break;
+	}
+
+	return ::DefWindowProc(m_hWnd, WM_SETCURSOR, wParam, lParam);
+}
+
+/*
+ * WM_SIZE
+ */
+LRESULT CHmVerticalTab::OnSize(WPARAM wParam, LPARAM lParam)
+{
+	::InvalidateRect(m_hWnd, NULL, TRUE);
+	return ::DefWindowProc(m_hWnd, WM_SIZE, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_PAINT
+LRESULT CHmVerticalTab::OnPaint(WPARAM wParam, LPARAM lParam)
+{
+	HDC hDC, hMemDC;
+	HBITMAP hBitmap;
+	RECT rcClient;
+	CString strText;
+	HFONT hFont1, hFont2;
+	HBRUSH hBrushBK;
+
+
+	// BeginPaint
+	PAINTSTRUCT ps;
+	hDC = BeginPaint(m_hWnd, &ps);
+	GetClientRect(m_hWnd, &rcClient);
+
+	hMemDC = ::CreateCompatibleDC(hDC);
+	hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left,
+		rcClient.bottom - rcClient.top);
+	::SelectObject(hMemDC, hBitmap);
+	::SetBkMode(hMemDC, TRANSPARENT);
+
+
+	HFONT hFontDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+	CFont* pFont = CFont::FromHandle(hFontDefault);
+	LOGFONT lf;
+	pFont->GetLogFont(&lf);
+	hFont1 = ::CreateFontIndirect(&lf);
+	lf.lfWeight = FW_BOLD;
+	hFont2 = ::CreateFontIndirect(&lf);
+
+
+	// 背景颜色
+	hBrushBK = CreateSolidBrush(m_crBkgnd);
+	::FillRect(hMemDC, &rcClient, hBrushBK);
+	DeleteObject(hBrushBK);
+
+
+	SelectObject(hMemDC, m_hPenUnderWnd);
+	::MoveToEx(hMemDC, rcClient.left, rcClient.bottom - 2, NULL);
+	::LineTo(hMemDC, rcClient.right, rcClient.bottom - 2);
+
+
+
+	// 绘制子项
+	SIZE sizeItem;
+	RECT rcItem, rcText;
+	rcItem.left = rcClient.left;
+	rcItem.right = rcClient.right-1;
+	rcItem.top = m_nPaddingTop;
+	int index = 0;
+	for (int i = 0; i < m_items.size(); i++) {
+		auto& item = m_items.at(i);
+		::SelectObject(hMemDC, i == m_nCurSel ? hFont2 : hFont1);
+		::SetTextColor(hMemDC, i == m_nCurSel ? m_crText[1] : m_crText[0]);
+		::GetTextExtentPoint32(hMemDC, item.szText, (int)strlen(item.szText), &sizeItem);
+		rcItem.top += m_nItemMarginTop;
+		rcItem.bottom = rcItem.top + m_nItemHeight;
+
+		if (i == m_nCurSel) {
+			::FillRect(hMemDC, &rcItem, m_hbrItemBkgnd[0]);
+		}
+		else if(&item == m_pHighItem) {
+			::FillRect(hMemDC, &rcItem, m_hbrItemBkgnd[1]);
+		}
+
+		::CopyRect(&rcText, &rcItem);
+		::DrawText(hMemDC, item.szText, (int)strlen(item.szText), &rcText,
+			DT_VCENTER | DT_CENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
+		::CopyRect(&item.rect, &rcItem);
+
+
+		// 右侧高亮划线?
+		if (m_bShowHightLine && (i == m_nCurSel || &item == m_pHighItem)) {
+			HPEN hOldPen = (HPEN)::SelectObject(hMemDC, i == m_nCurSel ? m_hPenUnder[0] : m_hPenUnder[1]);
+			::MoveToEx(hMemDC, item.rect.right - 3, item.rect.top, NULL);
+			::LineTo(hMemDC, item.rect.right - 3, item.rect.bottom);
+			::SelectObject(hMemDC, hOldPen);
+		}
+
+
+		index++;
+		rcItem.top = rcItem.bottom;
+	}
+	::DeleteObject(hFont1);
+	::DeleteObject(hFont2);
+
+
+	// 侧边线
+	HPEN hPen = CreatePen(PS_SOLID, 1, RGB(202, 204, 211));
+	HPEN hOldPen = (HPEN)::SelectObject(hMemDC, hPen);
+	::MoveToEx(hMemDC, rcClient.right - 1, 0, NULL);
+	::LineTo(hMemDC, rcClient.right - 1, rcClient.bottom - 1);
+	::SelectObject(hMemDC, hOldPen);
+
+
+	// EndPaint
+	::BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
+		hMemDC, 0, 0, SRCCOPY);
+	EndPaint(m_hWnd, &ps);
+	::DeleteObject(hBitmap);
+	::DeleteDC(hMemDC);
+
+
+	return 1;
+}
+
+void CHmVerticalTab::SetBkgndColor(COLORREF cr)
+{
+	m_crBkgnd = cr;
+}
+
+/*
+ * 检测坐标点所在的项
+ * 返回, TYGTLITEM
+ */
+int CHmVerticalTab::HighTest(POINT pt, OUT HMVERTICALTABITEM*& pItem, int* pnIndex)
+{
+	// 检测是否在某个子项
+	int nRet = HMTAB_HT_NOWHERE;
+	pItem = NULL;
+	for (int i = 0; i < m_items.size(); i++) {
+		auto& item = m_items.at(i);
+		if (::PtInRect(&item.rect, pt)) {
+			pItem = &item;
+			nRet = pItem == m_pHighItem ? HMTAB_HT_HIGT_ITEM : HMTAB_HT_ITEM;
+			if (pnIndex != nullptr) *pnIndex = i;
+			break;
+		}
+	}
+
+
+	return nRet;
+}
+
+int CHmVerticalTab::GetCurSel()
+{
+	return m_nCurSel;
+}
+
+void CHmVerticalTab::SetCurSel(int index)
+{
+	if (0 <= index && index <= m_items.size()) {
+		m_nCurSel = index;
+		InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+}
+
+int CHmVerticalTab::GetItemCount()
+{
+	return (int)m_items.size();
+}
diff --git a/SourceCode/Bond/BondEq/HmVerticalTab.h b/SourceCode/Bond/BondEq/HmVerticalTab.h
new file mode 100644
index 0000000..3e191f3
--- /dev/null
+++ b/SourceCode/Bond/BondEq/HmVerticalTab.h
@@ -0,0 +1,136 @@
+// HmVerticalTab.h: interface for the CHmTab class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_HMVERTICALTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
+#define AFX_HMVERTICALTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_
+
+
+#pragma comment(lib, "Msimg32.lib")			// TransparentBlt
+#include <vector>
+
+
+
+//====== HmTab =====================================================
+
+#ifndef NOHMVERTICALTAB
+
+#ifdef _WIN32
+
+#define HMVERTICALTAB_CLASSA       "HmVerticalTab"
+#define HMVERTICALTAB_CLASSW       L"HmVerticalTab"
+
+#ifdef UNICODE
+#define  HMVERTICALTAB_CLASS       HMVERTICALTAB_CLASSW
+#else
+#define  HMVERTICALTAB_CLASS       HMVERTICALTAB_CLASSA
+#endif
+
+#else
+#define HMVERTICALTAB_CLASS        "HmVerticalTab"
+#endif
+
+
+#define TAG_HMVERTICALTAB		 _T("IsHmVerticalTab")
+
+
+//====== WM_NOTIFY codes (NMHDR.code values) ==================================
+#define HMVERTICALTAB_FIRST			(0U-3370U)       //
+#define HMVERTICALTAB_LAST			(0U-3350U)
+#define HMVERTICALTAB_SEL_CHANGED	(HMVERTICALTAB_FIRST - 1)
+
+
+
+typedef struct tagHMVERTICALTAB_NMHDR
+{
+	NMHDR		nmhdr;
+	DWORD_PTR	dwData;
+	DWORD_PTR	dwData1;
+	DWORD_PTR	dwData2;
+} HMVERTICALTAB_NMHDR;
+
+#define HMVERTICALTAB_ITEM_TEXT_MAX		64
+
+typedef struct tagHMVERTICALTABITEM
+{
+	int id;
+	char szText[HMVERTICALTAB_ITEM_TEXT_MAX];
+	RECT rect;
+	void* context;
+} HMVERTICALTABITEM;
+
+#define HMTAB_HITCODETEST			_T("HitCode")
+#define HMTAB_HT_NOWHERE			0x1
+#define HMTAB_HT_ITEM				0x2
+#define HMTAB_HT_HIGT_ITEM			0x4
+
+
+#endif
+
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+class CHmVerticalTab
+{
+public:
+	CHmVerticalTab();
+	virtual ~CHmVerticalTab();
+
+public:
+	static BOOL RegisterWndClass();
+	static CHmVerticalTab* Hook(HWND hWnd);
+	void Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1 = 0, DWORD_PTR dwData2 = 0);
+	void Release();
+	void SetBkgndColor(COLORREF cr);
+	static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+	static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
+	LRESULT OnDestroy(WPARAM wParam, LPARAM lParam);
+	LRESULT OnTimer(WPARAM wParam, LPARAM lParam);
+	LRESULT OnPaint(WPARAM wParam, LPARAM lParam);
+	LRESULT OnSetCursor(WPARAM wParam, LPARAM lParam);
+	LRESULT OnSize(WPARAM wParam, LPARAM lParam);
+	LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
+	LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam);
+
+
+public:
+	void SetPaddingTop(int value);
+	void SetItemMarginTop(int value);
+	void SetTextColor(COLORREF color1, COLORREF color2);
+	void SetItemBkgndColor(COLORREF color1, COLORREF color2);
+	void SetHightLineVisible(BOOL bVisible);
+	int AddItem(const char* pszText, void* pContext = nullptr, BOOL bUpdate = TRUE);
+	int DeleteItem(const char* pszText, BOOL bUpdate = TRUE);
+	void* GetContext(unsigned int index);
+	int HighTest(POINT pt, OUT HMVERTICALTABITEM*& pItem, int* pnIndex);
+	int GetCurSel();
+	void SetCurSel(int index);
+	int GetItemCount();
+
+
+private:
+	HWND		m_hWnd;
+	COLORREF m_crBkgnd;
+
+private:
+	int m_nCurSel;
+	int m_nItemHeight;
+	std::vector< HMVERTICALTABITEM > m_items;
+	HMVERTICALTABITEM* m_pHighItem;
+	HMVERTICALTABITEM* m_pPressItem;
+	int m_nPaddingTop;
+	int m_nItemMarginTop;
+	COLORREF m_crText[2];
+	COLORREF m_crItemBkgnd[2];		// 子项背景色,0:选中,1:高亮
+	HBRUSH m_hbrItemBkgnd[2];		// 上述两项预创建
+	HPEN m_hPenUnder[2];
+	HPEN m_hPenUnderWnd;
+	BOOL m_bShowHightLine;
+};
+
+#endif // !defined(AFX_HMVERTICALTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
diff --git a/SourceCode/Bond/BondEq/HorizontalLine.cpp b/SourceCode/Bond/BondEq/HorizontalLine.cpp
new file mode 100644
index 0000000..e306993
--- /dev/null
+++ b/SourceCode/Bond/BondEq/HorizontalLine.cpp
@@ -0,0 +1,203 @@
+// HorizontalLine.cpp: implementation of the CHorizontalLine class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "HorizontalLine.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CHorizontalLine::CHorizontalLine()
+{
+	m_hWnd = NULL;
+	m_crBkgnd = RGB(255, 255, 255);
+	m_crLineColor = RGB(222, 222, 222);
+}
+
+CHorizontalLine::~CHorizontalLine()
+{
+}
+
+BOOL CHorizontalLine::RegisterWndClass()
+{
+	WNDCLASS wc;
+	wc.lpszClassName = BYHORIZONTALLINE_CLASS;
+	wc.hInstance = AfxGetInstanceHandle();
+	wc.lpfnWndProc = WindowProc;
+	wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+	wc.hIcon = 0;
+	wc.lpszMenuName = NULL;
+	wc.hbrBackground = NULL;
+	wc.style = CS_GLOBALCLASS|CS_DBLCLKS;
+	wc.cbClsExtra = 0;
+	wc.cbWndExtra = 0;
+	
+	// 注册自定义类
+	return (::RegisterClass(&wc) != 0);
+}
+
+CHorizontalLine* CHorizontalLine::Hook(HWND hWnd)
+{
+	CHorizontalLine* pHorizontalLine = (CHorizontalLine*)GetProp(hWnd, BYSTAG_HORIZONTALLINE);
+	if(pHorizontalLine == NULL)
+	{
+		pHorizontalLine = new CHorizontalLine;
+		pHorizontalLine->m_hWnd = hWnd;
+
+		SetProp(hWnd, BYSTAG_HORIZONTALLINE, (HANDLE)pHorizontalLine);
+	}
+	
+	return pHorizontalLine;
+}
+
+void CHorizontalLine::Release()
+{
+	// delete
+	delete this;
+}
+
+void CHorizontalLine::Notify(int nCode, int dwData, int dwData1/* = 0*/, int dwData2/* = 0*/)
+{
+	HWND hParent;
+	hParent = GetParent(m_hWnd);
+	if(hParent != NULL) {
+		BYHORIZONTALLINE_NMHDR iii_nmhdr;
+		iii_nmhdr.nmhdr.hwndFrom = m_hWnd;
+		iii_nmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
+		iii_nmhdr.nmhdr.code = nCode;
+		iii_nmhdr.dwData = dwData;
+		iii_nmhdr.dwData1 = dwData1;
+		iii_nmhdr.dwData2 = dwData2;
+		SendMessage(hParent, WM_NOTIFY, (WPARAM)iii_nmhdr.nmhdr.idFrom, (LPARAM)&iii_nmhdr);
+	}
+}
+
+////////////////////////////////
+// 拦截窗口消息函数
+LRESULT CALLBACK CHorizontalLine::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)   
+{
+	CHorizontalLine* pHorizontalLine = (CHorizontalLine *)GetProp(hWnd, BYSTAG_HORIZONTALLINE);
+	if(pHorizontalLine == NULL && uMsg != WM_NCCREATE)
+	{
+		return ::DefWindowProc(hWnd, uMsg, wParam, lParam);   
+	}
+
+	
+	// 如果Hook则响应消息
+	ASSERT(hWnd);
+	switch(uMsg)   
+	{
+	case WM_NCCREATE:
+		return OnNcCreate(hWnd, wParam, lParam);
+
+	case WM_DESTROY:
+		return pHorizontalLine->OnDestroy(wParam, lParam);
+
+	case WM_PAINT:
+		return pHorizontalLine->OnPaint(wParam, lParam);
+
+	case WM_TIMER:
+		return pHorizontalLine->OnTimer(wParam, lParam);
+
+	case WM_GETDLGCODE:
+		return DLGC_WANTALLKEYS;
+
+	default:
+		break;
+	}
+	
+	return ::DefWindowProc(hWnd, uMsg, wParam, lParam);   
+}  
+
+///////////////////////////////
+// WM_NCCREATE
+// 窗口创建前的初始化工作
+LRESULT CHorizontalLine::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+	CHorizontalLine* pHorizontalLine = (CHorizontalLine *)GetProp(hWnd, BYSTAG_HORIZONTALLINE);
+	ASSERT(pHorizontalLine == NULL);
+
+	Hook(hWnd);
+	return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_DESTROY
+LRESULT CHorizontalLine::OnDestroy(WPARAM wParam, LPARAM lParam)
+{
+	Release();
+	return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_TIMER
+LRESULT CHorizontalLine::OnTimer(WPARAM wParam, LPARAM lParam)
+{
+	return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam);
+}
+
+
+///////////////////////////////
+// WM_PAINT
+LRESULT CHorizontalLine::OnPaint(WPARAM wParam, LPARAM lParam)
+{
+	HDC hDC, hMemDC;
+	HBITMAP hBitmap;
+	RECT rcClient;
+	CString strText;
+	HFONT hFont;
+	HBRUSH hBrushBK;
+
+
+	// BeginPaint
+	PAINTSTRUCT ps;
+	hDC = BeginPaint(m_hWnd, &ps);
+	GetClientRect(m_hWnd, &rcClient);
+
+	hMemDC = ::CreateCompatibleDC(hDC);
+	hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right-rcClient.left,
+		rcClient.bottom-rcClient.top);
+	::SelectObject(hMemDC, hBitmap);
+
+	hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+	::SelectObject(hMemDC, hFont);
+
+	
+	// 背景颜色
+	hBrushBK = CreateSolidBrush( m_crBkgnd );
+	::FillRect(hMemDC, &rcClient, hBrushBK);
+	DeleteObject(hBrushBK);
+
+
+	// 画线
+	HPEN hPen = CreatePen(PS_SOLID, 1, m_crLineColor);
+	HPEN hOldPen = (HPEN)::SelectObject(hMemDC, hPen);
+	::MoveToEx(hMemDC, 0, 0, NULL);
+	LineTo(hMemDC, rcClient.right, 0);
+	::SelectObject(hMemDC, hOldPen);
+
+
+	// EndPaint
+	::BitBlt(hDC, 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,
+		hMemDC, 0, 0, SRCCOPY);
+	EndPaint(m_hWnd, &ps);
+	::DeleteObject(hBitmap);
+	::DeleteDC(hMemDC);
+
+	
+	return 1;
+}
+
+void CHorizontalLine::SetBkgndColor(COLORREF cr)
+{
+	m_crBkgnd = cr;
+}
+
diff --git a/SourceCode/Bond/BondEq/HorizontalLine.h b/SourceCode/Bond/BondEq/HorizontalLine.h
new file mode 100644
index 0000000..14d4b62
--- /dev/null
+++ b/SourceCode/Bond/BondEq/HorizontalLine.h
@@ -0,0 +1,86 @@
+// HorizontalLine.h: interface for the CHorizontalLine class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_HORIZONTALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
+#define AFX_HORIZONTALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_
+
+
+#pragma comment(lib, "Msimg32.lib")			// TransparentBlt
+
+
+
+//====== HorizontalLine =====================================================
+
+#ifndef NOHORIZONTALLINE
+
+#ifdef _WIN32
+
+#define BYHORIZONTALLINE_CLASSA       "BYHorizontalLine"
+#define BYHORIZONTALLINE_CLASSW       L"BYHorizontalLine"
+
+#ifdef UNICODE
+#define  BYHORIZONTALLINE_CLASS       BYHORIZONTALLINE_CLASSW
+#else
+#define  BYHORIZONTALLINE_CLASS       BYHORIZONTALLINE_CLASSA
+#endif
+
+#else
+#define BYHORIZONTALLINE_CLASS        "BYHorizontalLine"
+#endif
+
+
+#define BYSTAG_HORIZONTALLINE		 _T("ISHORIZONTALLINE")
+
+
+//====== WM_NOTIFY codes (NMHDR.code values) ==================================
+#define BYHORIZONTALLINE_FIRST				 (0U-590U)       //
+#define BYHORIZONTALLINE_LAST				 (0U-550U)
+#define BYHORIZONTALLINE_		 			 (BYHORIZONTALLINE_FIRST - 1)
+
+
+typedef struct tagBYHORIZONTALLINE_NMHDR
+{
+	NMHDR		nmhdr;
+	DWORD		dwData;
+	DWORD		dwData1;
+	DWORD		dwData2;
+} BYHORIZONTALLINE_NMHDR;
+
+
+
+#endif
+
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+class CHorizontalLine
+{
+public:
+	CHorizontalLine();
+	virtual ~CHorizontalLine();
+
+public:
+	static BOOL RegisterWndClass();
+	static CHorizontalLine* Hook(HWND hWnd);
+	void Notify(int nCode, int dwData, int dwData1 = 0, int dwData2 = 0);
+	void Release();
+	void SetBkgndColor(COLORREF cr);
+	static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+	static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
+	LRESULT OnDestroy(WPARAM wParam, LPARAM lParam);
+	LRESULT OnTimer(WPARAM wParam, LPARAM lParam);
+	LRESULT OnPaint(WPARAM wParam, LPARAM lParam);
+
+private:
+	HWND		m_hWnd;
+	COLORREF m_crBkgnd;
+	COLORREF m_crLineColor;
+};
+
+#endif // !defined(AFX_HORIZONTALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
diff --git a/SourceCode/Bond/BondEq/Log.cpp b/SourceCode/Bond/BondEq/Log.cpp
new file mode 100644
index 0000000..8f2ce20
--- /dev/null
+++ b/SourceCode/Bond/BondEq/Log.cpp
@@ -0,0 +1,214 @@
+#include "stdafx.h"
+#include "Log.h"
+
+
+static const char* pszLevel[] = {" [Debug] ", " [Info] ", " [Warn] ", " [Error] "};
+
+CLog::CLog()
+{
+	m_nLevel = 0;
+	m_nOutputTarget = OT_TRACE;
+	m_bAutoAppendTime = TRUE;
+	m_strEquipmentId = _T("Unknown");
+	m_nDay = 0;
+	m_funOnLog = nullptr;
+	InitializeCriticalSection(&m_criticalSection);
+}
+
+
+CLog::~CLog()
+{
+	DeleteCriticalSection(&m_criticalSection);
+}
+
+CLog *CLog::GetLog(void)
+{
+	static CLog* pLog = NULL;
+	if (pLog == NULL) {
+		static CLog log;
+		pLog = &log;
+	}
+
+	return pLog;
+}
+
+void CLog::SetOnLogCallback(ONLOG funOnLog)
+{
+	m_funOnLog = funOnLog;
+}
+
+void CLog::SetOutputTarget(int flag)
+{
+	m_nOutputTarget = flag;
+}
+
+void CLog::SetEquipmentId(const char* pszEquipmentId)
+{
+	m_strEquipmentId = pszEquipmentId;
+}
+
+void CLog::SetAutoAppendTimeString(BOOL bAutoAppendTime)
+{
+	m_bAutoAppendTime = bAutoAppendTime;
+}
+
+void CLog::Batch()
+{
+	if (m_file.m_hFile != CFile::hFileNull) {
+		m_file.Close();
+	}
+}
+
+BOOL CLog::BatchAndNew(int& nDay)
+{
+	Batch();
+	if ( (m_nOutputTarget & OT_FILE) && m_file.m_hFile == CFile::hFileNull) {
+		CString strFilepath;
+		BOOL bRet = m_file.Open(MakeFilepathD(strFilepath, nDay), CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite | CFile::shareDenyWrite);
+		if (bRet) {
+			m_file.SeekToEnd();
+		}
+		return bRet;
+	}
+
+	return FALSE;
+}
+
+#define BUFFERSIZE		1024*10
+void CLog::LogFormat(int nLevel, const char* pszTag, char* szMessage, ...)
+{
+	// 检查日期是否有变化,有变化则结批
+	Lock();
+	_SYSTEMTIME sysTime;
+	GetLocalTime(&sysTime);
+	if(m_nDay != sysTime.wDay) {
+		int nDay = 0;
+		if (BatchAndNew(nDay)) {
+			m_nDay = nDay;
+		}
+	}
+	Unlock();
+
+	if (nLevel < m_nLevel) {
+		return;
+	}
+
+	char szFullMessage[BUFFERSIZE];
+	char szFormatMessage[BUFFERSIZE];
+
+	// format message
+	va_list ap;
+	va_start(ap, szMessage);
+	_vsnprintf_s(szFormatMessage, BUFFERSIZE, szMessage, ap);
+	va_end(ap);
+
+	if (m_bAutoAppendTime) {
+		CString strTime;
+		strcpy_s(szFullMessage, BUFFERSIZE, (LPTSTR)(LPCTSTR)GetCurTime(strTime));
+	}
+	strcat_s(szFullMessage, BUFFERSIZE, pszLevel[nLevel]);
+	strcat_s(szFullMessage, szFormatMessage);
+	strcat_s(szFullMessage, BUFFERSIZE, "\n");
+
+	if (m_nOutputTarget & OT_FILE) {
+		Lock();
+		if (m_file.m_hFile != CFile::hFileNull) {
+			m_file.WriteString(szFullMessage);
+		}
+		Unlock();
+	}
+	if (m_nOutputTarget & OT_ODSTRING) {
+		OutputDebugStringA(szFullMessage);
+	}
+	else if(m_nOutputTarget & OT_TRACE) {
+		TRACE(szFormatMessage);
+	}
+
+	if (m_funOnLog != nullptr) {
+		m_funOnLog(nLevel, szFullMessage);
+	}
+}
+
+void CLog::Log(int nLevel, const char* pszTag, const char* szMessage)
+{
+	// 检查日期是否有变化,有变化则结批
+	Lock();
+	_SYSTEMTIME sysTime;
+	GetLocalTime(&sysTime);
+	if (m_nDay != sysTime.wDay) {
+		int nDay = 0;
+		if (BatchAndNew(nDay)) {
+			m_nDay = nDay;
+		}
+	}
+	Unlock();
+
+	if (nLevel < m_nLevel) {
+		return;
+	}
+
+	CString strMsg;
+	if (m_bAutoAppendTime) {
+		CString strTime;
+		GetCurTime(strTime);
+		strMsg.Append(strTime);
+	}
+	strMsg.Append(pszTag);
+	strMsg.Append(szMessage);
+	strMsg.Append("\n");
+
+	if (m_nOutputTarget & OT_FILE) {
+		Lock();
+		if (m_file.m_hFile != CFile::hFileNull) {
+			m_file.WriteString(strMsg);
+		}
+		Unlock();
+	}
+	if (m_nOutputTarget & OT_ODSTRING) {
+		OutputDebugStringA(strMsg);
+	}
+	else if (m_nOutputTarget & OT_TRACE) {
+		TRACE(strMsg);
+	}
+
+	if (m_funOnLog != nullptr) {
+		m_funOnLog(nLevel, strMsg);
+	}
+}
+
+CString& CLog::GetCurTime(CString& strTime)
+{
+	_SYSTEMTIME sysTime;
+	GetLocalTime(&sysTime);
+	strTime.Format(_T("%d/%02d/%02d %02d:%02d:%02d.%03d"), sysTime.wYear, sysTime.wMonth, sysTime.wDay,
+		sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds);
+	return strTime;
+}
+
+CString& CLog::MakeFilepath(CString& strFilepath)
+{
+	_SYSTEMTIME sysTime;
+	GetLocalTime(&sysTime);
+	strFilepath.Format(_T("%s\\Log(%s)_%d_%02d_%02d.log"), (LPTSTR)(LPCTSTR)m_strLogsDir,
+		(LPTSTR)(LPCTSTR)m_strEquipmentId,
+		sysTime.wYear, sysTime.wMonth, sysTime.wDay);
+
+	return strFilepath;
+}
+
+CString& CLog::MakeFilepathD(CString& strFilepath, int& day)
+{
+	_SYSTEMTIME sysTime;
+	GetLocalTime(&sysTime);
+	strFilepath.Format(_T("%s\\Log(%s)_%d_%02d_%02d.log"), (LPTSTR)(LPCTSTR)m_strLogsDir,
+		(LPTSTR)(LPCTSTR)m_strEquipmentId,
+		sysTime.wYear, sysTime.wMonth, sysTime.wDay);
+	day = sysTime.wDay;
+
+	return strFilepath;
+}
+
+void CLog::SetLogsDir(CString strDir)
+{
+	m_strLogsDir = strDir;
+}
diff --git a/SourceCode/Bond/BondEq/Log.h b/SourceCode/Bond/BondEq/Log.h
new file mode 100644
index 0000000..ee28e15
--- /dev/null
+++ b/SourceCode/Bond/BondEq/Log.h
@@ -0,0 +1,61 @@
+#pragma once
+#include <functional>
+
+
+#define LEVEL_DEBUG		0
+#define LEVEL_INFO		1
+#define LEVEL_WARN		2
+#define LEVEL_ERROR		3
+
+
+#define LOGD(msg, ...)		CLog::GetLog()->LogFormat(LEVEL_DEBUG, "", msg, __VA_ARGS__)
+#define LOGI(msg, ...)		CLog::GetLog()->LogFormat(LEVEL_INFO, "", msg, __VA_ARGS__)
+#define LOGW(msg, ...)		CLog::GetLog()->LogFormat(LEVEL_WARN, "", msg, __VA_ARGS__)
+#define LOGE(msg, ...)		CLog::GetLog()->LogFormat(LEVEL_ERROR, "", msg, __VA_ARGS__)
+
+
+#define OT_FILE			0x01
+#define OT_ODSTRING		0x02
+#define OT_TRACE		0x04
+#define LOGBATHCH()				CLog::GetLog()->Batch()
+#define LOGNEW()				CLog::GetLog()->BatchAndNew()
+
+typedef std::function<void(int level, const char* pszMessage)> ONLOG;
+
+class CLog
+{
+public:
+	CLog();
+	~CLog();
+
+public:
+	void SetOnLogCallback(ONLOG funOnLog);
+	static CLog *GetLog(void);
+	void SetOutputTarget(int flag);
+	void SetEquipmentId(const char* pszEquipmentId);
+	static CString& GetCurTime(CString& strTime);
+	CString& MakeFilepath(CString& strFilepath);
+	CString& MakeFilepathD(CString& strFilepath, int& day);
+	void LogFormat(int nLevel, const char* pszTag, char* szMessage, ...);
+	void Log(int nLevel, const char* pszTag, const char* szMessage);
+	void SetAutoAppendTimeString(BOOL bAutoAppendTime);
+	void SetLogsDir(CString strDir);
+	void Batch();
+	BOOL BatchAndNew(int& nDay);
+
+private:
+	inline void Lock() { EnterCriticalSection(&m_criticalSection); }
+	inline void Unlock() { LeaveCriticalSection(&m_criticalSection); }
+
+private:
+	ONLOG m_funOnLog;
+	int m_nOutputTarget;
+	int m_nLevel;
+	BOOL m_bAutoAppendTime;
+	CString m_strLogsDir;
+	CString m_strEquipmentId;
+	CStdioFile m_file;
+	int m_nDay;						// 按日保存一条记录,比较此数字,以决定是否结批并创建新文件
+	CRITICAL_SECTION m_criticalSection;
+};
+
diff --git a/SourceCode/Bond/BondEq/LogEdit.cpp b/SourceCode/Bond/BondEq/LogEdit.cpp
new file mode 100644
index 0000000..0e9fd35
--- /dev/null
+++ b/SourceCode/Bond/BondEq/LogEdit.cpp
@@ -0,0 +1,87 @@
+#include "stdafx.h"
+#include "LogEdit.h"
+
+
+#define MENU_ITEM_SEL_ALL		0x666
+#define MENU_ITEM_COPY			0x667
+#define MENU_ITEM_CLEAR			0x668
+
+CLogEdit::CLogEdit()
+{
+	m_nMaxLineCount = 0xffff;
+}
+
+
+CLogEdit::~CLogEdit()
+{
+}
+
+BEGIN_MESSAGE_MAP(CLogEdit, CEdit)
+	ON_WM_CONTEXTMENU()
+END_MESSAGE_MAP()
+
+void CLogEdit::SetMaxLineCount(int line)
+{
+	m_nMaxLineCount = line;
+}
+
+void CLogEdit::OnContextMenu(CWnd* pWnd, CPoint point)
+{
+	HMENU hMenu = CreatePopupMenu();
+	InsertMenu(hMenu, 0, MF_BYPOSITION, MENU_ITEM_SEL_ALL, "全选");
+	InsertMenu(hMenu, 1, MF_BYPOSITION, MENU_ITEM_COPY, "复制");
+	InsertMenu(hMenu, 2, MF_BYPOSITION | MF_SEPARATOR, NULL, NULL);	
+	InsertMenu(hMenu, 3, MF_BYPOSITION, MENU_ITEM_CLEAR, "全部清除");
+	int cmd = ::TrackPopupMenu(hMenu,
+		TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
+		point.x, point.y + 2, 0, m_hWnd, NULL);
+	DestroyMenu(hMenu);
+
+	if (cmd == MENU_ITEM_SEL_ALL) {
+		SetFocus();
+		this->SetSel(0, -1);
+	}
+	else if (cmd == MENU_ITEM_COPY) {
+		this->Copy();
+	}
+	else if (cmd == MENU_ITEM_CLEAR) {
+		SetWindowText(_T(""));
+	}
+}
+
+void CLogEdit::AppendText(const char* pszText)
+{
+	// 获取选择范围以便恢复
+	int nStart, nEnd;
+	GetSel(nStart, nEnd);
+
+
+	// 超过指定行数则删除最前面的行
+	int nLineCount = GetLineCount();
+	while (nLineCount > m_nMaxLineCount) {
+		int nLin1End = LineIndex(1);
+		nStart -= nLin1End;
+		if (nStart < 0) nStart = 0;
+		nEnd -= nLin1End;
+		if (nEnd < 0) nEnd = 0;
+
+		SetSel(0, nLin1End);
+		ReplaceSel(_T(""));
+		nLineCount = GetLineCount();
+	}
+
+
+	// 追加到最后
+	int length = GetWindowTextLength();
+	SetSel(length, length);
+	ReplaceSel(pszText);
+	PostMessage(WM_VSCROLL, SB_BOTTOM, 0);
+
+
+	// 恢复
+	if (nStart == 0 && nEnd == 0) {
+		nStart = GetWindowTextLength();
+		nEnd = nStart;
+	}
+	SetSel(nStart, nEnd);
+}
diff --git a/SourceCode/Bond/BondEq/LogEdit.h b/SourceCode/Bond/BondEq/LogEdit.h
new file mode 100644
index 0000000..cdccb5c
--- /dev/null
+++ b/SourceCode/Bond/BondEq/LogEdit.h
@@ -0,0 +1,21 @@
+#pragma once
+#include "afxwin.h"
+class CLogEdit :
+	public CEdit
+{
+public:
+	CLogEdit();
+	~CLogEdit();
+
+public:
+	void SetMaxLineCount(int line);
+	void AppendText(const char* pszText);
+
+
+private:
+	int m_nMaxLineCount;
+
+	DECLARE_MESSAGE_MAP()
+	afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
+};
+
diff --git a/SourceCode/Bond/BondEq/Model.cpp b/SourceCode/Bond/BondEq/Model.cpp
new file mode 100644
index 0000000..017bc5a
--- /dev/null
+++ b/SourceCode/Bond/BondEq/Model.cpp
@@ -0,0 +1,357 @@
+#include "stdafx.h"
+#include "Common.h"
+#include "Log.h"
+#include "Model.h"
+#include "Log.h"
+#include "ToolUnits.h"
+
+
+CModel* g_pModel = NULL;
+void CALLBACK ModerTimerProc(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
+{
+	if (g_pModel != NULL) {
+		g_pModel->onTimer(nTimerid);
+	}
+}
+
+
+CModel::CModel()
+{
+	m_pObservableEmitter = nullptr;
+	m_pObservable = nullptr;
+	m_pServo = nullptr;
+	m_pEqBond1 = nullptr;
+	m_nTimerID = 0;
+}
+
+
+CModel::~CModel()
+{
+}
+
+IObservable* CModel::getObservable()
+{
+	return m_pObservable;
+}
+
+void CModel::setWorkDir(const char* pszWorkDir)
+{
+	m_strWorkDir = pszWorkDir;
+}
+
+int CModel::init()
+{
+	CString strIniFile;
+	CString strUnitId;
+	strIniFile.Format(_T("%s\\Configuration.ini"), (LPTSTR)(LPCTSTR)m_strWorkDir);
+	m_configuration.setFilepath((LPTSTR)(LPCTSTR)strIniFile);
+	m_configuration.getUnitId(strUnitId);
+
+
+	/*
+	char szUnitId[256], szDataDir[MAX_PATH];
+	char szModeType[256];
+	CString strIniFile;
+	strIniFile.Format(_T("%s\\configuration.ini"), (LPTSTR)(LPCTSTR)m_strWorkDir);
+	GetPrivateProfileString("Equipment", "UNITID", _T(""), szUnitId, 256, strIniFile);
+	GetPrivateProfileString("Equipment", "ModelType", _T("GB2860"), szModeType, 256, strIniFile);
+	GetPrivateProfileString("APP", "DataDir", _T(""), szDataDir, MAX_PATH, strIniFile);
+	m_strDataDir = szDataDir;
+	CToolUnits::createDir(szDataDir);
+	*/
+
+
+	// Log
+	CString strLogDir;
+	strLogDir.Format(_T("%s\\Log"), (LPTSTR)(LPCTSTR)m_strWorkDir);
+	::CreateDirectory(strLogDir, NULL);
+	CLog::GetLog()->SetOnLogCallback([&](int level, const char* pszMessage) -> void {
+		notifyTextAndInt(RX_CODE_LOG, pszMessage, level);
+	});
+	CLog::GetLog()->SetAutoAppendTimeString(TRUE);
+	CLog::GetLog()->SetOutputTarget(OT_FILE);
+	CLog::GetLog()->SetLogsDir(strLogDir);
+	CLog::GetLog()->SetEquipmentId((LPTSTR)(LPCTSTR)strUnitId);
+	LOGI("\r\n\r\n~~~ Prog Start! ~~~");
+
+
+	// 创建Servo
+	BEQ_CreateServo(m_pServo, "BLServo");
+	ASSERT(m_pServo);
+	BEQ::ServoListener listener;
+	listener.onRemoteEqConnecting = [&](void* pServo, void* pRemoteEiuipment) -> void {
+		BEQ::IRemoteEquipment* p = (BEQ::IRemoteEquipment*)pRemoteEiuipment;
+		char szBuffer[256];
+		p->getName(szBuffer, 256);
+		LOGI("<ServoListener>正在连接远程设备(%s)...", szBuffer);
+	};
+	listener.onRemoteEqConnected = [&](void* pServo, void* pRemoteEiuipment) -> void {
+		BEQ::IRemoteEquipment* p = (BEQ::IRemoteEquipment*)pRemoteEiuipment;
+		char szBuffer[256];
+		p->getName(szBuffer, 256);
+		LOGI("<ServoListener>连接远程设备(%s)成功.", szBuffer);
+		notifyPtr(RX_CODE_REMOTEEQ_STATE_CHANGED, pRemoteEiuipment);
+	};
+	listener.onRemoteEqConnectFailed = [&](void* pServo, void* pRemoteEiuipment, int errorCode) -> void {
+		BEQ::IRemoteEquipment* p = (BEQ::IRemoteEquipment*)pRemoteEiuipment;
+		char szBuffer[256];
+		p->getName(szBuffer, 256);
+		LOGW("<ServoListener>连接远程设备(%s)失败.", szBuffer);
+	};
+	listener.onRemoteEqDisconnecting = [&](void* pServo, void* pRemoteEiuipment) -> void {
+		BEQ::IRemoteEquipment* p = (BEQ::IRemoteEquipment*)pRemoteEiuipment;
+		char szBuffer[256];
+		p->getName(szBuffer, 256);
+		LOGI("<ServoListener>正在断开远程设备(%s).", szBuffer);
+	};
+	listener.onRemoteEqDisconnected = [&](void* pServo, void* pRemoteEiuipment) -> void {
+		BEQ::IRemoteEquipment* p = (BEQ::IRemoteEquipment*)pRemoteEiuipment;
+		char szBuffer[256];
+		p->getName(szBuffer, 256);
+		LOGW("<ServoListener>远程设备(%s)连接断开.", szBuffer);
+		notifyPtr(RX_CODE_REMOTEEQ_STATE_CHANGED, pRemoteEiuipment);
+	};
+	listener.onRemoteEqReadRawdata = [&](void* pServo, void* pRemoteEiuipment, const char* pszData, int len) -> void {
+		BEQ::IRemoteEquipment* p = (BEQ::IRemoteEquipment*)pRemoteEiuipment;
+		char szBuffer[256];
+		p->getName(szBuffer, 256);
+		LOGD("<ServoListener>收到远程设备(%s)原始数据(%s).", szBuffer, std::string(pszData, len).c_str());
+	};
+	listener.onRemoteEqEventUpdate = [&](void* pServo, void* pRemoteEiuipment, void* pUnit, BEQ::REMOTE_EQ_EVENT eventCode) -> void {
+		BEQ::IRemoteEquipment* p = (BEQ::IRemoteEquipment*)pRemoteEiuipment;
+		char szBuffer[256];
+		p->getName(szBuffer, 256);
+		LOGD("<ServoListener>远程设备(%s)onRemoteEqEventUpdate.", szBuffer);
+	};
+	m_pServo->setListener(listener);
+
+
+	m_pObservable = RX_AllocaObservable([&](IObservableEmitter* e) -> void {
+		m_pObservableEmitter = e;			// 保存发射器
+	});
+
+
+	m_nTimerID = (int)SetTimer(NULL, 1, 1000, (TIMERPROC)ModerTimerProc);
+	g_pModel = this;
+
+
+	return 0;
+}
+
+int CModel::createRemoteEqs()
+{
+	// 从配置中读取远程机器配置
+	CString strIp, strIniFile;
+	UINT nPort, nDoorCount;
+	strIniFile.Format(_T("%s\\Configuration.ini"), (LPTSTR)(LPCTSTR)m_strWorkDir);
+	CConfiguration configuration((LPTSTR)(LPCTSTR)strIniFile);
+	configuration.getBond1(strIp, nPort, nDoorCount);
+	m_pServo->createRemoteEquipment(m_pEqBond1, (LPTSTR)(LPCTSTR)strIp, nPort);
+	ASSERT(m_pEqBond1);
+	m_pEqBond1->addUnit("UNITA", nDoorCount);
+	m_pServo->connectRemoteEquipment(m_pEqBond1);
+
+	return 0;
+}
+
+int CModel::term()
+{
+	CLog::GetLog()->SetOnLogCallback(nullptr);
+	return 0;
+}
+
+CServo& CModel::getServo()
+{
+	return m_servo;
+}
+
+BEQ::IRemoteEquipment* CModel::getBond1()
+{
+	return m_pEqBond1;
+}
+
+int CModel::notify(int code)
+{
+	/* code */
+	if (m_pObservableEmitter != NULL) {
+		IAny* pAny = RX_AllocaAny();
+		if (pAny != NULL) {
+			pAny->addRef();
+			pAny->setCode(code);
+			m_pObservableEmitter->onNext(pAny);
+			pAny->release();
+		}
+	}
+
+	return 1;
+}
+
+int CModel::notifyPtr(int code, void* ptr/* = NULL*/)
+{
+	/* code */
+	if (m_pObservableEmitter != NULL) {
+		IAny* pAny = RX_AllocaAny();
+		if (pAny != NULL) {
+			pAny->addRef();
+			pAny->setCode(code);
+			pAny->setPtrValue("ptr", ptr);
+			m_pObservableEmitter->onNext(pAny);
+			pAny->release();
+		}
+	}
+
+	return 1;
+}
+
+int CModel::notifyObj(int code, IRxObject* pObj)
+{
+	/* code */
+	if (m_pObservableEmitter != NULL) {
+		IAny* pAny = RX_AllocaAny();
+		if (pAny != NULL) {
+			pAny->addRef();
+			pAny->setCode(code);
+			pAny->setObject("obj", pObj);
+			m_pObservableEmitter->onNext(pAny);
+			pAny->release();
+		}
+	}
+
+	return 1;
+}
+
+int CModel::notifyObjAndPtr(int code, IRxObject* pObj, void* ptr)
+{
+	/* code */
+	if (m_pObservableEmitter != NULL) {
+		IAny* pAny = RX_AllocaAny();
+		if (pAny != NULL) {
+			pAny->addRef();
+			pAny->setCode(code);
+			pAny->setObject("obj", pObj);
+			pAny->setPtrValue("ptr", ptr);
+			m_pObservableEmitter->onNext(pAny);
+			pAny->release();
+		}
+	}
+
+	return 1;
+}
+
+int CModel::notifyInt(int code, int exCode)
+{
+	if (m_pObservableEmitter != NULL) {
+		IAny* pAny = RX_AllocaAny();
+		if (pAny != NULL) {
+			pAny->addRef();
+			pAny->setCode(code);
+			pAny->setIntValue("exCode", exCode);
+			m_pObservableEmitter->onNext(pAny);
+			pAny->release();
+		}
+	}
+
+	return 0;
+}
+
+int CModel::notifyObjAndInt(int code, IRxObject* pObj1, IRxObject* pObj2, int exCode)
+{
+	if (m_pObservableEmitter != NULL) {
+		IAny* pAny = RX_AllocaAny();
+		if (pAny != NULL) {
+			pAny->addRef();
+			pAny->setCode(code);
+			if (pObj1 != nullptr) pAny->setObject("obj", pObj1);
+			if (pObj2 != nullptr) pAny->setObject("obj2", pObj2);
+			pAny->setIntValue("exCode", exCode);
+			m_pObservableEmitter->onNext(pAny);
+			pAny->release();
+		}
+	}
+
+	return 0;
+}
+
+int CModel::notifyText(int code, const char* pszText)
+{
+	if (m_pObservableEmitter != NULL) {
+		IAny* pAny = RX_AllocaAny();
+		if (pAny != NULL) {
+			pAny->addRef();
+			pAny->setCode(code);
+			pAny->setStringValue("text", pszText);
+			m_pObservableEmitter->onNext(pAny);
+			pAny->release();
+		}
+	}
+
+	return 0;
+}
+
+int CModel::notifyTextAndInt(int code, const char* pszText, int exCode)
+{
+	if (m_pObservableEmitter != NULL) {
+		IAny* pAny = RX_AllocaAny();
+		if (pAny != NULL) {
+			pAny->addRef();
+			pAny->setCode(code);
+			pAny->setStringValue("text", pszText);
+			pAny->setIntValue("exCode", exCode);
+			m_pObservableEmitter->onNext(pAny);
+			pAny->release();
+		}
+	}
+
+	return 0;
+}
+
+int CModel::notifyPtrAndInt(int code, void* ptr1, void* ptr2, int exCode)
+{
+	if (m_pObservableEmitter != NULL) {
+		IAny* pAny = RX_AllocaAny();
+		if (pAny != NULL) {
+			pAny->addRef();
+			pAny->setCode(code);
+			pAny->setPtrValue("ptr", ptr1);
+			pAny->setPtrValue("ptr1", ptr1);
+			pAny->setPtrValue("ptr2", ptr2);
+			pAny->setIntValue("exCode", exCode);
+			m_pObservableEmitter->onNext(pAny);
+			pAny->release();
+		}
+	}
+
+	return 0;
+}
+
+int CModel::notifyMesMsg(int code, int stream, int function, const char* pszText)
+{
+	if (m_pObservableEmitter != NULL) {
+		IAny* pAny = RX_AllocaAny();
+		if (pAny != NULL) {
+			pAny->addRef();
+			pAny->setCode(code);
+			pAny->setIntValue("stream", stream);
+			pAny->setIntValue("function", function);
+			pAny->setStringValue("text", pszText);
+			m_pObservableEmitter->onNext(pAny);
+			pAny->release();
+		}
+	}
+
+	return 0;
+}
+
+void CModel::onTimer(UINT nTimerid)
+{
+	ULONGLONG tick = GetTickCount64();
+	int interval = m_configuration.getP2RemoteEqReconnectInterval() * 1000;
+
+	if (m_pEqBond1 != nullptr) {
+		if (!m_pEqBond1->isConnected()) {
+			if (tick - m_pEqBond1->getConnectTick() > interval) {
+				m_pEqBond1->connect();
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/Model.h b/SourceCode/Bond/BondEq/Model.h
new file mode 100644
index 0000000..db77ee0
--- /dev/null
+++ b/SourceCode/Bond/BondEq/Model.h
@@ -0,0 +1,50 @@
+#pragma once
+#include "Servo.h"
+#include "Configuration.h"
+
+
+class CModel
+{
+public:
+	CModel();
+	~CModel();
+
+public:
+	IObservable* getObservable();
+	void setWorkDir(const char* pszWorkDir);
+	int init();
+	int term();
+	void onTimer(UINT nTimerid);
+	int createRemoteEqs();
+	CServo& getServo();
+	BEQ::IRemoteEquipment* getBond1();
+
+public:
+	int notify(int code);
+	int notifyPtr(int code, void* ptr = NULL);
+	int notifyObj(int code, IRxObject* pObj);
+	int notifyObjAndPtr(int code, IRxObject* pObj, void* ptr);
+	int notifyObjAndInt(int code, IRxObject* pObj1, IRxObject* pObj2, int exCode);
+	int notifyInt(int code, int exCode);
+	int notifyText(int code, const char* pszText);
+	int notifyPtrAndInt(int code, void* ptr1, void* ptr2, int exCode);
+	int notifyTextAndInt(int code, const char* pszText, int exCode);
+	int notifyMesMsg(int code, int stream, int function, const char* pszText);
+
+public:
+	CConfiguration m_configuration;
+
+
+private:
+	IObservable* m_pObservable;
+	IObservableEmitter* m_pObservableEmitter;
+	CString m_strWorkDir;
+	CString m_strDataDir;
+
+private:
+	CServo m_servo;
+	BEQ::IServo* m_pServo;
+	BEQ::IRemoteEquipment* m_pEqBond1;
+	int m_nTimerID;
+};
+
diff --git a/SourceCode/Bond/BondEq/ReadMe.txt b/SourceCode/Bond/BondEq/ReadMe.txt
new file mode 100644
index 0000000..02af367
--- /dev/null
+++ b/SourceCode/Bond/BondEq/ReadMe.txt
@@ -0,0 +1,67 @@
+锘�================================================================================
+    MICROSOFT 鍩虹绫诲簱 : BondServo 椤圭洰姒傝堪
+===============================================================================
+
+搴旂敤绋嬪簭鍚戝宸蹭负鎮ㄥ垱寤轰簡姝� BondServo 搴旂敤绋嬪簭銆傛搴旂敤绋嬪簭涓嶄粎婕旂ず Microsoft 鍩虹绫荤殑鍩烘湰浣跨敤鏂规硶锛岃繕鍙綔涓烘偍缂栧啓搴旂敤绋嬪簭鐨勮捣鐐广��
+
+鏈枃浠舵瑕佷粙缁嶇粍鎴� BondServo 搴旂敤绋嬪簭鐨勬瘡涓枃浠剁殑鍐呭銆�
+
+BondServo.vcxproj
+    杩欐槸浣跨敤搴旂敤绋嬪簭鍚戝鐢熸垚鐨� VC++ 椤圭洰鐨勪富椤圭洰鏂囦欢锛屽叾涓寘鍚敓鎴愯鏂囦欢鐨� Visual C++ 鐨勭増鏈俊鎭紝浠ュ強鏈夊叧浣跨敤搴旂敤绋嬪簭鍚戝閫夋嫨鐨勫钩鍙般�侀厤缃拰椤圭洰鍔熻兘鐨勪俊鎭��
+
+BondServo.vcxproj.filters
+    杩欐槸浣跨敤鈥滃簲鐢ㄧ▼搴忓悜瀵尖�濈敓鎴愮殑 VC++ 椤圭洰绛涢�夊櫒鏂囦欢銆傚畠鍖呭惈鏈夊叧椤圭洰鏂囦欢涓庣瓫閫夊櫒涔嬮棿鐨勫叧鑱斾俊鎭�傚湪 IDE 涓紝閫氳繃杩欑鍏宠仈锛屽湪鐗瑰畾鑺傜偣涓嬩互鍒嗙粍褰㈠紡鏄剧ず鍏锋湁鐩镐技鎵╁睍鍚嶇殑鏂囦欢銆備緥濡傦紝鈥�.cpp鈥濇枃浠朵笌鈥滄簮鏂囦欢鈥濈瓫閫夊櫒鍏宠仈銆�
+
+BondServo.h
+    杩欐槸搴旂敤绋嬪簭鐨勪富澶存枃浠躲��
+    鍏朵腑鍖呮嫭鍏朵粬椤圭洰鐗瑰畾鐨勬爣澶达紙鍖呮嫭 Resource.h锛夛紝骞跺0鏄� CBondServoApp 搴旂敤绋嬪簭绫汇��
+
+BondServo.cpp
+    杩欐槸鍖呭惈搴旂敤绋嬪簭绫� CBondServoApp 鐨勪富搴旂敤绋嬪簭婧愭枃浠躲��
+
+BondServo.rc
+    杩欐槸绋嬪簭浣跨敤鐨勬墍鏈� Microsoft Windows 璧勬簮鐨勫垪琛ㄣ�傚畠鍖呮嫭 RES 瀛愮洰褰曚腑瀛樺偍鐨勫浘鏍囥�佷綅鍥惧拰鍏夋爣銆傛鏂囦欢鍙互鐩存帴鍦� Microsoft Visual C++ 涓繘琛岀紪杈戙�傞」鐩祫婧愬寘鍚湪 2052 涓��
+
+res\BondServo.ico
+    杩欐槸鐢ㄤ綔搴旂敤绋嬪簭鍥炬爣鐨勫浘鏍囨枃浠躲�傛鍥炬爣鍖呮嫭鍦ㄤ富璧勬簮鏂囦欢 BondServo.rc 涓��
+
+res\BondServo.rc2
+    姝ゆ枃浠跺寘鍚笉鍦� Microsoft Visual C++ 涓繘琛岀紪杈戠殑璧勬簮銆傛偍搴旇灏嗕笉鍙敱璧勬簮缂栬緫鍣ㄧ紪杈戠殑鎵�鏈夎祫婧愭斁鍦ㄦ鏂囦欢涓��
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+搴旂敤绋嬪簭鍚戝鍒涘缓涓�涓璇濇绫伙細
+
+BondServoDlg.h銆丅ondServoDlg.cpp - 瀵硅瘽妗�
+    杩欎簺鏂囦欢鍖呭惈 CBondServoDlg 绫汇�傛绫诲畾涔夊簲鐢ㄧ▼搴忕殑涓诲璇濇鐨勮涓恒�傚璇濇妯℃澘鍖呭惈鍦� BondServo.rc 涓紝璇ユ枃浠跺彲浠ュ湪 Microsoft Visual C++ 涓紪杈戙��
+
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬鍔熻兘锛�
+
+ActiveX 鎺т欢
+    璇ュ簲鐢ㄧ▼搴忓寘鍚浣跨敤 ActiveX 鎺т欢鐨勬敮鎸併��
+
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬鏍囧噯鏂囦欢:
+
+StdAfx.h, StdAfx.cpp
+    杩欎簺鏂囦欢鐢ㄤ簬鐢熸垚鍚嶄负 BondServo.pch 鐨勯缂栬瘧澶� (PCH) 鏂囦欢鍜屽悕涓� StdAfx.obj 鐨勯缂栬瘧绫诲瀷鏂囦欢銆�
+
+Resource.h
+    杩欐槸鏍囧噯澶存枃浠讹紝鍙敤浜庡畾涔夋柊鐨勮祫婧� ID銆侻icrosoft Visual C++ 灏嗚鍙栧苟鏇存柊姝ゆ枃浠躲��
+
+BondServo.manifest
+	Windows XP 浣跨敤搴旂敤绋嬪簭娓呭崟鏂囦欢鏉ユ弿杩扮壒瀹氱増鏈殑骞惰绋嬪簭闆嗙殑搴旂敤绋嬪簭渚濊禆椤广�傚姞杞界▼搴忎娇鐢ㄨ繖浜涗俊鎭潵浠庣▼搴忛泦缂撳瓨涓姞杞界浉搴旂殑绋嬪簭闆嗭紝骞朵繚鎶ゅ叾涓嶈搴旂敤绋嬪簭璁块棶銆傚簲鐢ㄧ▼搴忔竻鍗曞彲鑳戒細鍖呭惈鍦ㄥ唴锛屼互浣滀负涓庡簲鐢ㄧ▼搴忓彲鎵ц鏂囦欢瀹夎鍦ㄥ悓涓�鏂囦欢澶逛腑鐨勫閮� .manifest 鏂囦欢杩涜閲嶆柊鍒嗗彂锛屽畠杩樺彲鑳戒互璧勬簮鐨勫舰寮忓寘鍚湪鍙墽琛屾枃浠朵腑銆�
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬娉ㄩ噴:
+
+搴旂敤绋嬪簭鍚戝浣跨敤鈥淭ODO:鈥濇潵鎸囩ず搴旀坊鍔犳垨鑷畾涔夌殑婧愪唬鐮侀儴鍒嗐��
+
+濡傛灉搴旂敤绋嬪簭浣跨敤鍏变韩 DLL 涓殑 MFC锛屾偍灏嗛渶瑕侀噸鏂板垎鍙� MFC DLL銆傚鏋滃簲鐢ㄧ▼搴忔墍浣跨敤鐨勮瑷�涓庢搷浣滅郴缁熺殑鍖哄煙璁剧疆涓嶅悓锛屽垯杩橀渶瑕侀噸鏂板垎鍙戠浉搴旂殑鏈湴鍖栬祫婧� mfc110XXX.DLL銆�
+鏈夊叧涓婅堪璇濋鐨勬洿澶氫俊鎭紝璇峰弬瑙� MSDN 鏂囨。涓湁鍏抽噸鏂板垎鍙� Visual C++ 搴旂敤绋嬪簭鐨勯儴鍒嗐��
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/SourceCode/Bond/BondEq/Resource.h b/SourceCode/Bond/BondEq/Resource.h
new file mode 100644
index 0000000..4348670
--- /dev/null
+++ b/SourceCode/Bond/BondEq/Resource.h
Binary files differ
diff --git a/SourceCode/Bond/BondEq/Servo.cpp b/SourceCode/Bond/BondEq/Servo.cpp
new file mode 100644
index 0000000..20d78a2
--- /dev/null
+++ b/SourceCode/Bond/BondEq/Servo.cpp
@@ -0,0 +1,17 @@
+#include "stdafx.h"
+#include "Servo.h"
+
+
+CServo::CServo()
+{
+}
+
+
+CServo::~CServo()
+{
+}
+
+BOOL CServo::isRunning()
+{
+	return FALSE;
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/Servo.h b/SourceCode/Bond/BondEq/Servo.h
new file mode 100644
index 0000000..2cbc006
--- /dev/null
+++ b/SourceCode/Bond/BondEq/Servo.h
@@ -0,0 +1,11 @@
+#pragma once
+class CServo
+{
+public:
+	CServo();
+	~CServo();
+
+public:
+	BOOL isRunning();
+};
+
diff --git a/SourceCode/Bond/BondEq/SetPage1.cpp b/SourceCode/Bond/BondEq/SetPage1.cpp
new file mode 100644
index 0000000..23b606f
--- /dev/null
+++ b/SourceCode/Bond/BondEq/SetPage1.cpp
@@ -0,0 +1,45 @@
+// SetPage1.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "SetPage1.h"
+#include "afxdialogex.h"
+
+
+// CSetPage1 对话框
+
+IMPLEMENT_DYNAMIC(CSetPage1, CBaseSetPage)
+
+CSetPage1::CSetPage1(CWnd* pParent /*=NULL*/)
+	: CBaseSetPage(IDD_SET_PAGE1, pParent)
+{
+
+}
+
+CSetPage1::~CSetPage1()
+{
+}
+
+void CSetPage1::DoDataExchange(CDataExchange* pDX)
+{
+	CBaseSetPage::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CSetPage1, CBaseSetPage)
+END_MESSAGE_MAP()
+
+
+// CSetPage1 消息处理程序
+
+
+BOOL CSetPage1::OnInitDialog()
+{
+	CBaseSetPage::OnInitDialog();
+
+	// TODO:  在此添加额外的初始化
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 异常: OCX 属性页应返回 FALSE
+}
diff --git a/SourceCode/Bond/BondEq/SetPage1.h b/SourceCode/Bond/BondEq/SetPage1.h
new file mode 100644
index 0000000..ec3bdcd
--- /dev/null
+++ b/SourceCode/Bond/BondEq/SetPage1.h
@@ -0,0 +1,26 @@
+#pragma once
+#include "BaseSetPage.h"
+
+
+// CSetPage1 对话框
+
+class CSetPage1 : public CBaseSetPage
+{
+	DECLARE_DYNAMIC(CSetPage1)
+
+public:
+	CSetPage1(CWnd* pParent = NULL);   // 标准构造函数
+	virtual ~CSetPage1();
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_SET_PAGE1 };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+};
diff --git a/SourceCode/Bond/BondEq/SetPage2.cpp b/SourceCode/Bond/BondEq/SetPage2.cpp
new file mode 100644
index 0000000..a5e6b72
--- /dev/null
+++ b/SourceCode/Bond/BondEq/SetPage2.cpp
@@ -0,0 +1,62 @@
+// SetPage2.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "SetPage2.h"
+#include "afxdialogex.h"
+
+
+// CSetPage2 对话框
+
+IMPLEMENT_DYNAMIC(CSetPage2, CBaseSetPage)
+
+CSetPage2::CSetPage2(CWnd* pParent /*=NULL*/)
+	: CBaseSetPage(IDD_SET_PAGE2, pParent)
+{
+
+}
+
+CSetPage2::~CSetPage2()
+{
+}
+
+void CSetPage2::DoDataExchange(CDataExchange* pDX)
+{
+	CBaseSetPage::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CSetPage2, CBaseSetPage)
+	ON_EN_CHANGE(IDC_EDIT_REMOTEEQ_RECONNECT_INTERVAL, &CSetPage2::OnEnChangeEditRemoteeqReconnectInterval)
+END_MESSAGE_MAP()
+
+
+// CSetPage2 消息处理程序
+
+
+BOOL CSetPage2::OnInitDialog()
+{
+	CBaseSetPage::OnInitDialog();
+
+
+	// 读取配置
+	int nReconnectInterval = theApp.m_model.m_configuration.getP2RemoteEqReconnectInterval();
+	SetDlgItemInt(IDC_EDIT_REMOTEEQ_RECONNECT_INTERVAL, nReconnectInterval);
+
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 异常: OCX 属性页应返回 FALSE
+}
+
+void CSetPage2::OnApply()
+{
+	// 保存配置
+	int nReconnectInterval = GetDlgItemInt(IDC_EDIT_REMOTEEQ_RECONNECT_INTERVAL);
+	theApp.m_model.m_configuration.setP2RemoteEqReconnectInterval(nReconnectInterval);
+}
+
+void CSetPage2::OnEnChangeEditRemoteeqReconnectInterval()
+{
+	OnModify();
+}
diff --git a/SourceCode/Bond/BondEq/SetPage2.h b/SourceCode/Bond/BondEq/SetPage2.h
new file mode 100644
index 0000000..b8f15af
--- /dev/null
+++ b/SourceCode/Bond/BondEq/SetPage2.h
@@ -0,0 +1,32 @@
+#pragma once
+#include "BaseSetPage.h"
+
+
+// CSetPage2 对话框
+
+class CSetPage2 : public CBaseSetPage
+{
+	DECLARE_DYNAMIC(CSetPage2)
+
+public:
+	CSetPage2(CWnd* pParent = NULL);   // 标准构造函数
+	virtual ~CSetPage2();
+
+
+public:
+	virtual void OnApply();
+
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_SET_PAGE2 };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg void OnEnChangeEditRemoteeqReconnectInterval();
+};
diff --git a/SourceCode/Bond/BondEq/SettingsDlg.cpp b/SourceCode/Bond/BondEq/SettingsDlg.cpp
new file mode 100644
index 0000000..3e73340
--- /dev/null
+++ b/SourceCode/Bond/BondEq/SettingsDlg.cpp
@@ -0,0 +1,191 @@
+// SettingsDlg.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "SettingsDlg.h"
+#include "afxdialogex.h"
+
+
+// CSettingsDlg 对话框
+
+IMPLEMENT_DYNAMIC(CSettingsDlg, CDialogEx)
+
+CSettingsDlg::CSettingsDlg(CWnd* pParent /*=NULL*/)
+	: CDialogEx(IDD_DIALOG_SETTINGS, pParent)
+{
+	m_crBkgnd = RGB(239, 244, 254);
+	m_pTab = nullptr;
+	m_bInit = FALSE;
+}
+
+CSettingsDlg::~CSettingsDlg()
+{
+}
+
+void CSettingsDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CSettingsDlg, CDialogEx)
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_WM_SIZE()
+	ON_NOTIFY(HMVERTICALTAB_SEL_CHANGED, IDC_TAB1, &CSettingsDlg::OnTabSelChanged)
+	ON_BN_CLICKED(IDC_BUTTON_APPLY, &CSettingsDlg::OnBnClickedButtonApply)
+	ON_BN_CLICKED(IDOK, &CSettingsDlg::OnBnClickedOk)
+	ON_MESSAGE(ID_MSG_PAGE_MODIFY, &CSettingsDlg::OnPageModify)
+END_MESSAGE_MAP()
+
+
+// CSettingsDlg 消息处理程序
+
+
+BOOL CSettingsDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	CSetPage1* pPage1 = new CSetPage1();
+	pPage1->Create(IDD_SET_PAGE1, this);
+
+	CSetPage2* pPage2 = new CSetPage2();
+	pPage2->Create(IDD_SET_PAGE2, this);
+
+	m_pTab = CHmVerticalTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd);
+	m_pTab->SetPaddingTop(3);
+	m_pTab->SetBkgndColor(RGB(235, 235, 243));
+	m_pTab->AddItem(_T("常规设置"), pPage1);
+	m_pTab->AddItem(_T("杀毒"), pPage2);
+	m_pTab->AddItem(_T("实时防护"));
+	m_pTab->AddItem(_T("清理加速"));
+	m_pTab->AddItem(_T("漏洞修复"));
+
+	ShowChildPage(0);
+	Resize();
+	m_bInit = TRUE;
+
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 异常: OCX 属性页应返回 FALSE
+}
+
+HBRUSH CSettingsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+void CSettingsDlg::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+	for (unsigned int i = 0; i < 5; i++) {
+		CBaseSetPage* pPage = (CBaseSetPage*)m_pTab->GetContext(i);
+		if (pPage != nullptr) {
+			pPage->DestroyWindow();
+			delete pPage;
+		}
+	}
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+}
+
+void CSettingsDlg::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+	if (nullptr == GetDlgItem(IDC_TAB1)) return;
+	Resize();
+}
+
+void CSettingsDlg::Resize()
+{
+	CWnd* pItem;
+	CRect rcClient, rcItem;
+	int x, y;
+
+	x = 1;
+	GetClientRect(&rcClient);
+	pItem = GetDlgItem(IDC_TAB1);
+	pItem->GetClientRect(&rcItem);
+	pItem->MoveWindow(x, 1, rcItem.Width(), rcClient.Height() - 2);
+	x += rcItem.Width();
+	x += 1;
+
+	pItem = GetDlgItem(IDC_BUTTON_APPLY);
+	pItem->GetWindowRect(&rcItem);
+	ScreenToClient(&rcItem);
+	y = rcItem.top - 12;
+
+	for (unsigned int i = 0; i < 5; i++) {
+		CBaseSetPage* pPage = (CBaseSetPage*)m_pTab->GetContext(i);
+		if (pPage != nullptr) {
+			pPage->MoveWindow(x, 1, rcClient.Width() - x - 1, y - 2);
+		}
+	}
+}
+
+void CSettingsDlg::OnTabSelChanged(NMHDR* nmhdr, LRESULT* result)
+{
+	HMVERTICALTAB_NMHDR* pNmhdrex = (HMVERTICALTAB_NMHDR*)nmhdr;
+	ShowChildPage((unsigned int)pNmhdrex->dwData);
+
+	*result = 0;
+}
+
+void CSettingsDlg::ShowChildPage(unsigned int index)
+{
+	ASSERT(0 <= index && index < 5);
+	for (unsigned int i = 0; i < 5; i++) {
+		CBaseSetPage* pPage = (CBaseSetPage*)m_pTab->GetContext(i);
+		if (pPage != nullptr) {
+			pPage->ShowWindow(i == index ? SW_SHOW : SW_HIDE);
+		}
+
+	}
+}
+
+void CSettingsDlg::OnBnClickedButtonApply()
+{
+	for (unsigned int i = 0; i < 5; i++) {
+		CBaseSetPage* pPage = (CBaseSetPage*)m_pTab->GetContext(i);
+		if (pPage != nullptr) {
+			pPage->OnApply();
+		}
+	}
+
+	GetDlgItem(IDC_BUTTON_APPLY)->EnableWindow(FALSE);
+}
+
+void CSettingsDlg::OnBnClickedOk()
+{
+	for (unsigned int i = 0; i < 5; i++) {
+		CBaseSetPage* pPage = (CBaseSetPage*)m_pTab->GetContext(i);
+		if (pPage != nullptr) {
+			pPage->OnApply();
+		}
+	}
+
+	CDialogEx::OnOK();
+}
+
+LRESULT CSettingsDlg::OnPageModify(WPARAM wParam, LPARAM lParam)
+{
+	if (m_bInit) {
+		GetDlgItem(IDC_BUTTON_APPLY)->EnableWindow(TRUE);
+	}
+
+	return 0;
+}
diff --git a/SourceCode/Bond/BondEq/SettingsDlg.h b/SourceCode/Bond/BondEq/SettingsDlg.h
new file mode 100644
index 0000000..427184f
--- /dev/null
+++ b/SourceCode/Bond/BondEq/SettingsDlg.h
@@ -0,0 +1,47 @@
+#pragma once
+#include "HmVerticalTab.h"
+#include "SetPage1.h"
+#include "SetPage2.h"
+
+
+// CSettingsDlg 对话框
+
+class CSettingsDlg : public CDialogEx
+{
+	DECLARE_DYNAMIC(CSettingsDlg)
+
+public:
+	CSettingsDlg(CWnd* pParent = NULL);   // 标准构造函数
+	virtual ~CSettingsDlg();
+
+
+private:
+	void Resize();
+	void ShowChildPage(unsigned int index);
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+	CHmVerticalTab* m_pTab;
+	BOOL m_bInit;
+
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_DIALOG_SETTINGS };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnTabSelChanged(NMHDR* nmhdr, LRESULT* result);
+	afx_msg void OnBnClickedButtonApply();
+	afx_msg void OnBnClickedOk();
+	afx_msg	LRESULT OnPageModify(WPARAM wParam, LPARAM lParam);
+};
diff --git a/SourceCode/Bond/BondEq/ToolUnits.cpp b/SourceCode/Bond/BondEq/ToolUnits.cpp
new file mode 100644
index 0000000..fecc6c1
--- /dev/null
+++ b/SourceCode/Bond/BondEq/ToolUnits.cpp
@@ -0,0 +1,147 @@
+#include "stdafx.h"
+#include "ToolUnits.h"
+#include <chrono>
+
+
+CToolUnits::CToolUnits()
+{
+}
+
+
+CToolUnits::~CToolUnits()
+{
+}
+
+std::string CToolUnits::timeToString(ULONGLONG time)
+{
+	ULONGLONG time1, time2;
+	time1 = time / 1000000000;
+	time2 = time % 1000000000;
+
+	char buffer1[256], buffer[128];
+	struct tm timeinfo;
+	time_t t = time_t(time1);
+	localtime_s(&timeinfo, &t);
+	strftime(buffer, 128, "%Y-%m-%d %H:%M:%S", &timeinfo);
+	sprintf_s(buffer1, 256, "%s.%lld", buffer, time2);
+	return std::string(buffer1);
+}
+
+std::string CToolUnits::timeToString2(ULONGLONG time)
+{
+	ULONGLONG time1;
+	time1 = time / 1000;
+
+	char buffer[256];
+	struct tm timeinfo;
+	time_t t = time_t(time1);
+	localtime_s(&timeinfo, &t);
+	strftime(buffer, 128, "%Y-%m-%d %H:%M:%S", &timeinfo);
+	return std::string(buffer);
+}
+
+std::string CToolUnits::timeToString3(ULONGLONG time)
+{
+	ULONGLONG time1;
+	int ms;
+	time1 = time / 1000;
+	ms = time % 1000;
+
+	char buffer1[256], buffer[128];
+	struct tm timeinfo;
+	time_t t = time_t(time1);
+	localtime_s(&timeinfo, &t);
+	strftime(buffer, 128, "%Y-%m-%d %H:%M:%S", &timeinfo);
+	sprintf_s(buffer1, 256, "%s.%03d", buffer, ms);
+	return std::string(buffer1);
+}
+
+ULONGLONG CToolUnits::stringToTime(const char* pszTime)
+{
+	struct tm tm;
+
+	memset(&tm, 0, sizeof(tm));
+	sscanf_s(pszTime, "%d-%d-%d %d:%d:%d",
+		&tm.tm_year, &tm.tm_mon, &tm.tm_mday,
+		&tm.tm_hour, &tm.tm_min, &tm.tm_sec);
+	tm.tm_year -= 1900;
+	tm.tm_mon--;
+
+	return mktime(&tm) * 1000;
+}
+
+ULONGLONG CToolUnits::getTimestamp()
+{
+	auto now = std::chrono::system_clock::now();
+	auto duration_in_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
+	uint64_t timestamp = duration_in_milliseconds.count();
+	return timestamp;
+}
+
+void CToolUnits::createDir(const char* pszDir)
+{
+	CString strDir = pszDir;
+	int lastIndex = 0;
+	int index = strDir.Find(_T("\\"), lastIndex);
+	while (index > 0) {
+		CString strTempDir = strDir.Left(index);
+		CreateDirectory(strTempDir, NULL);
+
+		lastIndex = index + 1;
+		index = strDir.Find(_T("\\"), lastIndex);
+	}
+	CreateDirectory(strDir, NULL);
+}
+
+CString& CToolUnits::floatToString1(float value, CString& strOut)
+{
+	strOut.Format(_T("%.1f"), value);
+	return strOut;
+}
+
+CString& CToolUnits::floatToString3(float value, CString& strOut)
+{
+	strOut.Format(_T("%.3f"), value);
+	return strOut;
+}
+
+
+BOOL CToolUnits::copyTextToClipboard(CWnd* pWnd, const CString& strText)
+{
+	if (OpenClipboard(pWnd->GetSafeHwnd())) {
+		EmptyClipboard();
+
+		HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (strText.GetLength() + 1) * sizeof(TCHAR));
+		if (hglbCopy == NULL) {
+			CloseClipboard();
+			return FALSE;
+		}
+
+		LPTSTR lptstrCopy = (LPTSTR)GlobalLock(hglbCopy);
+		strcpy_s(lptstrCopy, strText.GetLength()+1, strText);
+		GlobalUnlock(hglbCopy);
+		SetClipboardData(CF_TEXT, hglbCopy);
+		CloseClipboard();
+		GlobalFree(hglbCopy);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+std::string CToolUnits::getCurrentExePath() {
+	char path[MAX_PATH];
+	GetModuleFileName(NULL, path, MAX_PATH);
+	std::string exePath(path);
+	return exePath.substr(0, exePath.find_last_of("\\/"));
+}
+
+bool CToolUnits::isFile(const std::string& path) {
+	DWORD attributes = GetFileAttributes(path.c_str());
+	return (attributes != INVALID_FILE_ATTRIBUTES && !(attributes & FILE_ATTRIBUTE_DIRECTORY));
+}
+
+bool CToolUnits::isDirectory(const std::string& path) {
+	DWORD attributes = GetFileAttributes(path.c_str());
+	return (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY));
+}
diff --git a/SourceCode/Bond/BondEq/ToolUnits.h b/SourceCode/Bond/BondEq/ToolUnits.h
new file mode 100644
index 0000000..3dfc929
--- /dev/null
+++ b/SourceCode/Bond/BondEq/ToolUnits.h
@@ -0,0 +1,24 @@
+#pragma once
+#include <string>
+
+class CToolUnits
+{
+public:
+	CToolUnits();
+	~CToolUnits();
+
+public:
+	static std::string timeToString(ULONGLONG time);
+	static std::string timeToString2(ULONGLONG time);
+	static std::string timeToString3(ULONGLONG time);
+	static ULONGLONG stringToTime(const char* pszTime);
+	static CString& floatToString1(float value, CString& strOut);
+	static CString& floatToString3(float value, CString& strOut);
+	static ULONGLONG getTimestamp();
+	static void createDir(const char* pszDir);
+	static BOOL copyTextToClipboard(CWnd* pWnd, const CString& strText);
+	static std::string getCurrentExePath();
+	static bool isFile(const std::string& path);
+	static bool isDirectory(const std::string& path);
+};
+
diff --git a/SourceCode/Bond/BondEq/TopToolbar.cpp b/SourceCode/Bond/BondEq/TopToolbar.cpp
new file mode 100644
index 0000000..25a56bc
--- /dev/null
+++ b/SourceCode/Bond/BondEq/TopToolbar.cpp
@@ -0,0 +1,189 @@
+// TopToolbar.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "TopToolbar.h"
+#include "afxdialogex.h"
+#include "Common.h"
+
+
+// CTopToolbar 对话框
+
+IMPLEMENT_DYNAMIC(CTopToolbar, CDialogEx)
+
+CTopToolbar::CTopToolbar(CWnd* pParent /*=NULL*/)
+	: CDialogEx(IDD_TOP_TOOLBAR, pParent)
+{
+	m_crBkgnd = TOP_TOOLBAR_BACKGROUND;
+	m_hbrBkgnd = nullptr;
+}
+
+CTopToolbar::~CTopToolbar()
+{
+}
+
+void CTopToolbar::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_BUTTON_RUN, m_btnRun);
+	DDX_Control(pDX, IDC_BUTTON_STOP, m_btnStop);
+	DDX_Control(pDX, IDC_BUTTON_SETTINGS, m_btnSettings);
+	DDX_Control(pDX, IDC_BUTTON_OPERATOR, m_btnOperator);
+}
+
+
+BEGIN_MESSAGE_MAP(CTopToolbar, CDialogEx)
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_WM_SIZE()
+	ON_NOTIFY(BLBUTTON_MENU_ITEM_CLICKED, IDC_BUTTON_OPERATOR, &CTopToolbar::OnButtonOperatorMenuClicked)
+END_MESSAGE_MAP()
+
+
+// CTopToolbar 消息处理程序
+
+
+BOOL CTopToolbar::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	InitBtn(m_btnRun, "Run_High_32.ico", "Run_Gray_32.ico");
+	InitBtn(m_btnStop, "Stop_High_32.ico", "Stop_Gray_32.ico");
+	InitBtn(m_btnSettings, "Settings_High_32.ico", "Settings_Gray_32.ico");
+	InitBtn(m_btnOperator, "Operator_High_32.ico", "Operator_Gray_32.ico");
+	HMENU hMenu = LoadMenu(AfxGetInstanceHandle(), MAKEINTRESOURCEA(IDR_MENU_OPEATOR));
+	m_btnOperator.SetMenu(hMenu);
+
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 异常: OCX 属性页应返回 FALSE
+}
+
+
+HBRUSH CTopToolbar::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+
+void CTopToolbar::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+		m_hbrBkgnd = nullptr;
+	}
+}
+
+
+void CTopToolbar::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+	if (GetDlgItem(IDC_BUTTON_RUN) == nullptr) return;
+	Resize();
+}
+
+#define BTN_WIDTH		60
+#define BTN_HEIGHT		30
+void CTopToolbar::Resize()
+{
+	CWnd* pItem;
+	CRect rcClient, rcItem;
+	GetClientRect(&rcClient);
+	int nBthHeight = (rcClient.Height() - 10);
+	int x = 2, y = 3;
+
+	pItem = GetDlgItem(IDC_BUTTON_RUN);
+	pItem->MoveWindow(x, y, BTN_WIDTH, nBthHeight);
+	x += BTN_WIDTH;
+	x += 2;
+
+	pItem = GetDlgItem(IDC_BUTTON_STOP);
+	pItem->MoveWindow(x, y, BTN_WIDTH, nBthHeight);
+	x += BTN_WIDTH;
+	x += 2;
+
+	pItem = GetDlgItem(IDC_TOOLBAR_LINE1);
+	pItem->MoveWindow(x, y + 6, 2, nBthHeight - 12);
+	x += 4;
+
+	pItem = GetDlgItem(IDC_BUTTON_SETTINGS);
+	pItem->MoveWindow(x, y, BTN_WIDTH, nBthHeight);
+	x += BTN_WIDTH;
+	x += 2;
+
+	x = rcClient.right - 5 - BTN_WIDTH - 20;
+	pItem = GetDlgItem(IDC_BUTTON_OPERATOR);
+	pItem->MoveWindow(x, y, BTN_WIDTH + 20, nBthHeight);
+
+
+	CWnd* pLine = GetDlgItem(IDC_LINE1);
+	pLine->MoveWindow(0, rcClient.bottom - 2, rcClient.Width(), 2);
+}
+
+void CTopToolbar::InitBtn(CBlButton& btn, const char* pszIcon1, const char* pszIcon2)
+{
+	CString strIcon1, strIcon2;
+	HICON hIcon1, hIcon2;
+	strIcon1.Format(_T("%s\\Res\\%s"), theApp.m_strAppDir, pszIcon1);
+	strIcon2.Format(_T("%s\\Res\\%s"), theApp.m_strAppDir, pszIcon2);
+	hIcon1 = (HICON)::LoadImage(AfxGetInstanceHandle(),
+		strIcon1, IMAGE_ICON, 32, 32,
+		LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+	hIcon2 = (HICON)::LoadImage(AfxGetInstanceHandle(),
+		strIcon2, IMAGE_ICON, 32, 32,
+		LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+	btn.SetBkgndColor(BS_NORMAL, TOP_TOOLBAR_BACKGROUND);
+	btn.SetBkgndColor(BS_PRESS, RGB(185, 209, 234));
+	btn.SetBkgndColor(BS_DISABLE, TOP_TOOLBAR_BACKGROUND);
+	btn.SetFrameColor(BS_NORMAL, TOP_TOOLBAR_BACKGROUND);
+	btn.SetFrameColor(BS_PRESS, RGB(185, 209, 234));
+	btn.SetFrameColor(BS_HOVER, RGB(185, 209, 234));
+	btn.SetFrameColor(BS_DISABLE, TOP_TOOLBAR_BACKGROUND);
+	btn.SetIcon(hIcon1, hIcon2, 32);
+}
+
+CWnd* CTopToolbar::GetBtn(UINT nId)
+{
+	return GetDlgItem(nId);
+}
+
+void CTopToolbar::SetOperatorBtnText(const char* pszText)
+{
+	m_btnOperator.SetWindowText(pszText);
+}
+
+BOOL CTopToolbar::OnCommand(WPARAM wParam, LPARAM lParam)
+{
+	switch (LOWORD(wParam)) {
+	case IDC_BUTTON_RUN:
+	case IDC_BUTTON_STOP:
+	case IDC_BUTTON_SETTINGS:
+		GetParent()->SendMessage(ID_MSG_TOOLBAR_BTN_CLICKED, 0, LOWORD(wParam));
+		break;
+	}
+
+	return CDialogEx::OnCommand(wParam, lParam);
+}
+
+void CTopToolbar::OnButtonOperatorMenuClicked(NMHDR* pNMHDR, LRESULT* pResult)
+{
+	BLBUTTON_NMHDR* pblbNmhdr = reinterpret_cast<BLBUTTON_NMHDR*>(pNMHDR);
+	GetParent()->SendMessage(ID_MSG_TOOLBAR_BTN_CLICKED, (int)pblbNmhdr->dwData, IDC_BUTTON_OPERATOR);
+
+
+	*pResult = 0;
+}
+
diff --git a/SourceCode/Bond/BondEq/TopToolbar.h b/SourceCode/Bond/BondEq/TopToolbar.h
new file mode 100644
index 0000000..8b33d3e
--- /dev/null
+++ b/SourceCode/Bond/BondEq/TopToolbar.h
@@ -0,0 +1,54 @@
+#pragma once
+#include "BlButton.h"
+
+
+#define ID_MSG_TOOLBAR_BTN_CLICKED		WM_USER + 20368
+
+// CTopToolbar 对话框
+
+class CTopToolbar : public CDialogEx
+{
+	DECLARE_DYNAMIC(CTopToolbar)
+
+public:
+	CTopToolbar(CWnd* pParent = NULL);   // 标准构造函数
+	virtual ~CTopToolbar();
+
+
+public:
+	CWnd* GetBtn(UINT nId);
+	void SetOperatorBtnText(const char* pszText);
+
+private:
+	void Resize();
+	void InitBtn(CBlButton& btn, const char* pszIcon1, const char* pszIcon2);
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+
+
+private:
+	CBlButton m_btnRun;
+	CBlButton m_btnStop;
+	CBlButton m_btnSettings;
+	CBlButton m_btnOperator;
+
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_TOP_TOOLBAR };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
+	afx_msg void OnButtonOperatorMenuClicked(NMHDR* pNMHDR, LRESULT* pResult);
+};
diff --git a/SourceCode/Bond/BondEq/VerticalLine.cpp b/SourceCode/Bond/BondEq/VerticalLine.cpp
new file mode 100644
index 0000000..440eb14
--- /dev/null
+++ b/SourceCode/Bond/BondEq/VerticalLine.cpp
@@ -0,0 +1,310 @@
+// VerticalLine.cpp: implementation of the CVerticalLine class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "VerticalLine.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CVerticalLine::CVerticalLine()
+{
+	m_hWnd = NULL;
+	m_crBkgnd = RGB(255, 255, 255);
+	m_crLineColor = RGB(222, 222, 222);
+	m_bEnableResize = FALSE;
+}
+
+CVerticalLine::~CVerticalLine()
+{
+}
+
+BOOL CVerticalLine::RegisterWndClass()
+{
+	WNDCLASS wc;
+	wc.lpszClassName = BYVERTICALLINE_CLASS;
+	wc.hInstance = AfxGetInstanceHandle();
+	wc.lpfnWndProc = WindowProc;
+	wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+	wc.hIcon = 0;
+	wc.lpszMenuName = NULL;
+	wc.hbrBackground = NULL;
+	wc.style = CS_GLOBALCLASS|CS_DBLCLKS;
+	wc.cbClsExtra = 0;
+	wc.cbWndExtra = 0;
+	
+	// 注册自定义类
+	return (::RegisterClass(&wc) != 0);
+}
+
+CVerticalLine* CVerticalLine::Hook(HWND hWnd)
+{
+	CVerticalLine* pVerticalLine = (CVerticalLine*)GetProp(hWnd, BYSTAG_VERTICALLINE);
+	if(pVerticalLine == NULL)
+	{
+		pVerticalLine = new CVerticalLine;
+		pVerticalLine->m_hWnd = hWnd;
+
+		SetProp(hWnd, BYSTAG_VERTICALLINE, (HANDLE)pVerticalLine);
+	}
+	
+	return pVerticalLine;
+}
+
+void CVerticalLine::Release()
+{
+	// delete
+	delete this;
+}
+
+void CVerticalLine::Notify(int nCode, int dwData, int dwData1/* = 0*/, int dwData2/* = 0*/)
+{
+	HWND hParent;
+	hParent = GetParent(m_hWnd);
+	if(hParent != NULL) {
+		BYVERTICALLINE_NMHDR iii_nmhdr;
+		iii_nmhdr.nmhdr.hwndFrom = m_hWnd;
+		iii_nmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
+		iii_nmhdr.nmhdr.code = nCode;
+		iii_nmhdr.dwData = dwData;
+		iii_nmhdr.dwData1 = dwData1;
+		iii_nmhdr.dwData2 = dwData2;
+		SendMessage(hParent, WM_NOTIFY, (WPARAM)iii_nmhdr.nmhdr.idFrom, (LPARAM)&iii_nmhdr);
+	}
+}
+
+////////////////////////////////
+// 拦截窗口消息函数
+LRESULT CALLBACK CVerticalLine::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)   
+{
+	CVerticalLine* pVerticalLine = (CVerticalLine *)GetProp(hWnd, BYSTAG_VERTICALLINE);
+	if(pVerticalLine == NULL && uMsg != WM_NCCREATE)
+	{
+		return ::DefWindowProc(hWnd, uMsg, wParam, lParam);   
+	}
+
+	
+	// 如果Hook则响应消息
+	ASSERT(hWnd);
+	switch(uMsg)   
+	{
+	case WM_NCCREATE:
+		return OnNcCreate(hWnd, wParam, lParam);
+
+	case WM_DESTROY:
+		return pVerticalLine->OnDestroy(wParam, lParam);
+
+	case WM_PAINT:
+		return pVerticalLine->OnPaint(wParam, lParam);
+
+	case WM_TIMER:
+		return pVerticalLine->OnTimer(wParam, lParam);
+
+	case WM_SETCURSOR:
+		return pVerticalLine->OnSetCursor(wParam, lParam);
+
+	case WM_LBUTTONDOWN:
+		return pVerticalLine->OnLButtonDown(wParam, lParam);
+
+	case WM_GETDLGCODE:
+		return DLGC_WANTALLKEYS;
+
+	default:
+		break;
+	}
+	
+	return ::DefWindowProc(hWnd, uMsg, wParam, lParam);   
+}  
+
+///////////////////////////////
+// WM_NCCREATE
+// 窗口创建前的初始化工作
+LRESULT CVerticalLine::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+	CVerticalLine* pVerticalLine = (CVerticalLine *)GetProp(hWnd, BYSTAG_VERTICALLINE);
+	ASSERT(pVerticalLine == NULL);
+
+	Hook(hWnd);
+	return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_DESTROY
+LRESULT CVerticalLine::OnDestroy(WPARAM wParam, LPARAM lParam)
+{
+	Release();
+	return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_TIMER
+LRESULT CVerticalLine::OnTimer(WPARAM wParam, LPARAM lParam)
+{
+	return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_SETCURSOR
+LRESULT CVerticalLine::OnSetCursor(WPARAM wParam, LPARAM lParam)
+{
+	if(m_bEnableResize) {
+		SetCursor(::LoadCursor(NULL, IDC_SIZEWE));
+		return TRUE;
+	}
+
+	return ::DefWindowProc(m_hWnd, WM_SETCURSOR, wParam, lParam);
+}
+
+/*
+ * WM_LBUTTONDOWN
+ * 鼠标左键按下
+ */
+LRESULT CVerticalLine::OnLButtonDown(WPARAM wParam, LPARAM lParam)
+{
+	if (!m_bEnableResize) {
+		return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam);
+	}
+
+
+	POINT pt, ptNew;
+	pt.x = LOWORD(lParam);
+	pt.y = HIWORD(lParam);
+	int nMoveX = 0;
+
+
+	// 捕捉鼠标消息,检测是否拖动
+	RECT rcParent, rcWindows;
+	GetClientRect(m_hWnd, &rcWindows);
+	::ClientToScreen(m_hWnd, (LPPOINT)&rcWindows);
+	::ClientToScreen(m_hWnd, (LPPOINT)&rcWindows.right);
+	GetClientRect(GetParent(m_hWnd), &rcParent);
+	::ClientToScreen(GetParent(m_hWnd), (LPPOINT)&rcParent);
+	HDC hDC = GetDC(GetDesktopWindow());
+	::DrawFocusRect(hDC, &rcWindows);
+
+	if (::GetCapture() == NULL) {
+		SetCapture(m_hWnd);
+		ASSERT(m_hWnd == GetCapture());
+		AfxLockTempMaps();
+		for (;;) {
+			MSG msg;
+			VERIFY(::GetMessage(&msg, NULL, 0, 0));
+
+			if (GetCapture() != m_hWnd) break;
+
+			switch (msg.message)
+			{
+			case WM_MOUSEMOVE:
+				ptNew = msg.pt;
+				if (ptNew.x < rcParent.left) ptNew.x = rcParent.left;
+				::DrawFocusRect(hDC, &rcWindows);
+				rcWindows.left = ptNew.x - 3;
+				rcWindows.right = ptNew.x + 3;
+				::DrawFocusRect(hDC, &rcWindows);
+				::ScreenToClient(m_hWnd, &ptNew);
+				break;
+
+			case WM_LBUTTONUP:
+				ptNew = msg.pt;
+				::ScreenToClient(m_hWnd, &ptNew);
+				nMoveX = ptNew.x - pt.x;
+				goto ExitLoop;
+
+			case WM_KEYDOWN:
+				if (msg.wParam == VK_ESCAPE) {
+					goto ExitLoop;
+				}
+				break;
+
+			default:
+				DispatchMessage(&msg);
+				break;
+			}
+		}
+
+	ExitLoop:
+		::DrawFocusRect(hDC, &rcWindows);
+		ReleaseDC(GetDesktopWindow(), hDC);
+		ReleaseCapture();
+		::InvalidateRect(m_hWnd, NULL, TRUE);
+		Notify((int)BYVERTICALLINE_MOVEX, nMoveX);
+		AfxUnlockTempMaps(FALSE);
+	}
+
+
+	return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_PAINT
+LRESULT CVerticalLine::OnPaint(WPARAM wParam, LPARAM lParam)
+{
+	HDC hDC, hMemDC;
+	HBITMAP hBitmap;
+	RECT rcClient;
+	CString strText;
+	HFONT hFont;
+	HBRUSH hBrushBK;
+
+
+	// BeginPaint
+	PAINTSTRUCT ps;
+	hDC = BeginPaint(m_hWnd, &ps);
+	GetClientRect(m_hWnd, &rcClient);
+
+	hMemDC = ::CreateCompatibleDC(hDC);
+	hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right-rcClient.left,
+		rcClient.bottom-rcClient.top);
+	::SelectObject(hMemDC, hBitmap);
+
+	hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+	::SelectObject(hMemDC, hFont);
+
+	
+	// 背景颜色
+	hBrushBK = CreateSolidBrush( m_crBkgnd );
+	::FillRect(hMemDC, &rcClient, hBrushBK);
+	DeleteObject(hBrushBK);
+
+
+	// 画线
+	HPEN hPen = CreatePen(PS_SOLID, 1, m_crLineColor);
+	HPEN hOldPen = (HPEN)::SelectObject(hMemDC, hPen);
+	::MoveToEx(hMemDC, rcClient.right-1, 0, NULL);
+	LineTo(hMemDC, rcClient.right - 1, rcClient.bottom);
+	::SelectObject(hMemDC, hOldPen);
+
+
+	// EndPaint
+	::BitBlt(hDC, 0, 0, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,
+		hMemDC, 0, 0, SRCCOPY);
+	EndPaint(m_hWnd, &ps);
+	::DeleteObject(hBitmap);
+	::DeleteDC(hMemDC);
+
+	
+	return 1;
+}
+
+void CVerticalLine::SetBkgndColor(COLORREF cr)
+{
+	m_crBkgnd = cr;
+}
+void CVerticalLine::EnableResize()
+{
+	m_bEnableResize = TRUE;
+}
+
+void CVerticalLine::DisableResize()
+{
+	m_bEnableResize = FALSE;
+}
+
diff --git a/SourceCode/Bond/BondEq/VerticalLine.h b/SourceCode/Bond/BondEq/VerticalLine.h
new file mode 100644
index 0000000..9f22766
--- /dev/null
+++ b/SourceCode/Bond/BondEq/VerticalLine.h
@@ -0,0 +1,94 @@
+// VerticalLine.h: interface for the CVerticalLine class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_VERTICALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
+#define AFX_VERTICALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_
+
+
+#pragma comment(lib, "Msimg32.lib")			// TransparentBlt
+
+
+
+//====== VerticalLine =====================================================
+
+#ifndef NOVERTICALLINE
+
+#ifdef _WIN32
+
+#define BYVERTICALLINE_CLASSA       "BYVerticalLine"
+#define BYVERTICALLINE_CLASSW       L"BYVerticalLine"
+
+#ifdef UNICODE
+#define  BYVERTICALLINE_CLASS       BYVERTICALLINE_CLASSW
+#else
+#define  BYVERTICALLINE_CLASS       BYVERTICALLINE_CLASSA
+#endif
+
+#else
+#define BYVERTICALLINE_CLASS        "BYVerticalLine"
+#endif
+
+
+#define BYSTAG_VERTICALLINE		 _T("ISVERTICALLINE")
+
+
+//====== WM_NOTIFY codes (NMHDR.code values) ==================================
+#define BYVERTICALLINE_FIRST			 (0U-2330U)       //
+#define BYVERTICALLINE_LAST				 (0U-2320U)
+#define BYVERTICALLINE_MOVEX 			 (BYVERTICALLINE_FIRST - 1)
+
+
+typedef struct tagBYVERTICALLINE_NMHDR
+{
+	NMHDR		nmhdr;
+	DWORD		dwData;
+	DWORD		dwData1;
+	DWORD		dwData2;
+} BYVERTICALLINE_NMHDR;
+
+
+
+#endif
+
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+class CVerticalLine
+{
+public:
+	CVerticalLine();
+	virtual ~CVerticalLine();
+	
+
+public:
+	void EnableResize();
+	void DisableResize();
+	static BOOL RegisterWndClass();
+	static CVerticalLine* Hook(HWND hWnd);
+	void Notify(int nCode, int dwData, int dwData1 = 0, int dwData2 = 0);
+	void Release();
+	void SetBkgndColor(COLORREF cr);
+	static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+	static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
+	LRESULT OnDestroy(WPARAM wParam, LPARAM lParam);
+	LRESULT OnTimer(WPARAM wParam, LPARAM lParam);
+	LRESULT OnSetCursor(WPARAM wParam, LPARAM lParam);
+	LRESULT OnPaint(WPARAM wParam, LPARAM lParam);
+	LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
+
+private:
+	HWND		m_hWnd;
+	COLORREF m_crBkgnd;
+	COLORREF m_crLineColor;
+
+private:
+	BOOL m_bEnableResize;
+};
+
+#endif // !defined(AFX_VERTICALLINE_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
diff --git a/SourceCode/Bond/BondEq/View/ChangePasswordDlg.cpp b/SourceCode/Bond/BondEq/View/ChangePasswordDlg.cpp
new file mode 100644
index 0000000..2bfc2c2
--- /dev/null
+++ b/SourceCode/Bond/BondEq/View/ChangePasswordDlg.cpp
@@ -0,0 +1,114 @@
+锘�// CChangePasswordDlg.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "afxdialogex.h"
+#include "ChangePasswordDlg.h"
+#include "UserManager.h"
+
+
+// CChangePasswordDlg 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CChangePasswordDlg, CDialogEx)
+
+CChangePasswordDlg::CChangePasswordDlg(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_DIALOG_CHANGE_PASSWORD, pParent)
+{
+}
+
+CChangePasswordDlg::~CChangePasswordDlg()
+{
+}
+
+bool CChangePasswordDlg::changeUserPassword(UserManager& userManager, const std::string& username, const std::string& newPassword)
+{
+    if (!userManager.changePassword(username, newPassword)) {
+        AfxMessageBox(_T("淇敼鐢ㄦ埛瀵嗙爜澶辫触銆�"));
+        return false;
+    }
+
+    return true;
+}
+
+void CChangePasswordDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_EDIT_CHANGE_USERNAME, m_editUsername);
+	DDX_Control(pDX, IDC_EDIT_CHANGE_CURRENT_PASSWORD, m_editCurrentPassword);
+	DDX_Control(pDX, IDC_EDIT_CHANGE_NEW_PASSWORD, m_editNewPassword);
+	DDX_Control(pDX, IDC_EDIT_CHANGE_CONFIRM_PASSWORD, m_editConfirmPassword);
+}
+
+
+BEGIN_MESSAGE_MAP(CChangePasswordDlg, CDialogEx)
+	ON_BN_CLICKED(IDOK, &CChangePasswordDlg::OnBnClickedOk)
+END_MESSAGE_MAP()
+
+
+// CChangePasswordDlg 娑堟伅澶勭悊绋嬪簭
+
+
+BOOL CChangePasswordDlg::OnInitDialog()
+{
+    CDialogEx::OnInitDialog();
+
+    // 璁剧疆绐楀彛鏍囬鍜屽垵濮嬪��
+    SetWindowText(_T("淇敼瀵嗙爜"));
+
+    UserManager& userManager = UserManager::getInstance();
+    if (userManager.isLoggedIn()) {
+        m_editUsername.SetWindowText(userManager.getCurrentUser().c_str());
+    }
+
+    return TRUE;
+}
+
+void CChangePasswordDlg::OnBnClickedOk()
+{
+    CString username, currentPassword, newPassword, confirmPassword;
+    m_editUsername.GetWindowText(username);
+    m_editCurrentPassword.GetWindowText(currentPassword);
+    m_editNewPassword.GetWindowText(newPassword);
+    m_editConfirmPassword.GetWindowText(confirmPassword);
+
+    if (username.IsEmpty() || currentPassword.IsEmpty() || newPassword.IsEmpty() || confirmPassword.IsEmpty()) {
+        AfxMessageBox(_T("鎵�鏈夊瓧娈靛潎涓哄繀濉」銆�"));
+        return;
+    }
+
+    if (newPassword.Compare(confirmPassword) != 0) {
+        AfxMessageBox(_T("鏂板瘑鐮佷笌纭瀵嗙爜涓嶅尮閰嶃��"));
+        return;
+    }
+
+#ifdef UNICODE
+    std::string strUsername = CStringA(username);
+    std::string strCurrentPassword = CStringA(currentPassword);
+    std::string strNewPassword = CStringA(newPassword);
+#else
+    std::string strUsername = username;
+    std::string strCurrentPassword = currentPassword;
+    std::string strNewPassword = newPassword;
+#endif
+
+    UserManager& userManager = UserManager::getInstance();
+    if (userManager.isLoggedIn() && strCurrentPassword.compare(userManager.getCurrentPass()) == 0) {
+        if (changeUserPassword(userManager, strUsername, strNewPassword)) {
+            EndDialog(IDOK);
+        }
+    }
+    else {
+        if (userManager.login(strUsername, strCurrentPassword)) {
+            if (changeUserPassword(userManager, strUsername, strNewPassword)) {
+                EndDialog(IDOK);
+            }
+            else {
+                userManager.logout();
+            }
+        }
+        else {
+            AfxMessageBox(_T("褰撳墠鐢ㄦ埛鍚嶆垨瀵嗙爜杈撳叆閿欒銆�"));
+        }
+    }
+}
diff --git a/SourceCode/Bond/BondEq/View/ChangePasswordDlg.h b/SourceCode/Bond/BondEq/View/ChangePasswordDlg.h
new file mode 100644
index 0000000..3f6e0b8
--- /dev/null
+++ b/SourceCode/Bond/BondEq/View/ChangePasswordDlg.h
@@ -0,0 +1,37 @@
+锘�#pragma once
+#include "afxdialogex.h"
+#include <string>
+
+class UserManager;
+
+// CChangePasswordDlg 瀵硅瘽妗�
+
+class CChangePasswordDlg : public CDialogEx
+{
+	DECLARE_DYNAMIC(CChangePasswordDlg)
+
+public:
+	CChangePasswordDlg(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CChangePasswordDlg();
+
+private:
+	bool changeUserPassword(UserManager& userManager, const std::string& username, const std::string& newPassword);
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_DIALOG_CHANGE_PASSWORD };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+	virtual BOOL OnInitDialog();
+	afx_msg void OnBnClickedOk();
+	afx_msg void OnBnClickedCancel();
+	DECLARE_MESSAGE_MAP()
+
+private:
+	CEdit m_editUsername;              // 鐢ㄦ埛鍚嶈緭鍏ユ
+	CEdit m_editCurrentPassword;       // 褰撳墠瀵嗙爜杈撳叆妗�
+	CEdit m_editNewPassword;           // 鏂板瘑鐮佽緭鍏ユ
+	CEdit m_editConfirmPassword;       // 纭鏂板瘑鐮佽緭鍏ユ
+};
diff --git a/SourceCode/Bond/BondEq/View/LoginDlg.cpp b/SourceCode/Bond/BondEq/View/LoginDlg.cpp
new file mode 100644
index 0000000..947a37d
--- /dev/null
+++ b/SourceCode/Bond/BondEq/View/LoginDlg.cpp
@@ -0,0 +1,116 @@
+锘�// LoginDlg.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "BondServo.h"
+#include "afxdialogex.h"
+#include "LoginDlg.h"
+#include "UserManager.h"
+#include "ChangePasswordDlg.h"
+
+
+// CLoginDlg 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CLoginDlg, CDialogEx)
+
+CLoginDlg::CLoginDlg(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_DIALOG_LOGIN, pParent)
+{
+}
+
+CLoginDlg::~CLoginDlg()
+{
+}
+
+void CLoginDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_EDIT_USERNAME, m_editUsername);
+	DDX_Control(pDX, IDC_EDIT_PASSWORD, m_editPassword);
+	DDX_Control(pDX, IDC_COMBO_ROLE, m_comboRole);
+	DDX_Control(pDX, IDC_CHECK_REMEMBER_PASSWORD, m_checkRememberPassword);
+}
+
+
+BEGIN_MESSAGE_MAP(CLoginDlg, CDialogEx)
+	ON_BN_CLICKED(IDC_BUTTON_LOGIN, &CLoginDlg::OnBnClickedLogin)
+    ON_STN_CLICKED(IDC_STATIC_CHANGE_PASSWORD, &CLoginDlg::OnBnClickedChangePassword)
+END_MESSAGE_MAP()
+
+
+// CLoginDlg 娑堟伅澶勭悊绋嬪簭
+
+
+BOOL CLoginDlg::OnInitDialog()
+{
+    CDialog::OnInitDialog();
+
+    // 璁剧疆绐楀彛鏍囬鍜屽垵濮嬪��
+    SetWindowText(_T("鐧诲綍"));
+	m_comboRole.AddString(_T("绠$悊鍛�"));
+	m_comboRole.AddString(_T("宸ョ▼甯�"));
+    m_comboRole.AddString(_T("鎿嶄綔鍛�"));
+    m_comboRole.SetCurSel(0);
+
+    // 娣诲姞SS_NOTIFY鏍峰紡
+    CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_CHANGE_PASSWORD);
+    if (pStatic != nullptr) {
+        pStatic->ModifyStyle(0, SS_NOTIFY);
+    }
+
+    UserManager& userManager = UserManager::getInstance();
+	if (userManager.isLoggedIn()) {
+		int nRole = (int)userManager.getCurrentUserRole();
+        if (nRole <= m_comboRole.GetCount()) {
+            m_comboRole.SetCurSel(nRole);
+        }
+
+        if (userManager.isRememberMe()) {
+            m_checkRememberPassword.SetCheck(BST_CHECKED);
+        }
+       
+        userManager.getCurrentUserRole();
+		m_editUsername.SetWindowText(userManager.getCurrentUser().c_str());
+		m_editPassword.SetWindowText(userManager.getCurrentPass().c_str());
+	}
+
+    return TRUE;
+}
+
+void CLoginDlg::OnBnClickedLogin()
+{
+    CString username, password, role;
+    m_editUsername.GetWindowText(username);
+    m_editPassword.GetWindowText(password);
+    m_comboRole.GetLBText(m_comboRole.GetCurSel(), role);
+
+    if (username.IsEmpty() || password.IsEmpty()) {
+        AfxMessageBox(_T("璇疯緭鍏ョ敤鎴峰悕鍜屽瘑鐮併��"));
+        return;
+    }
+
+#ifdef UNICODE
+    std::string strUsername = CStringA(username);
+    std::string strPassword = CStringA(password);
+#else
+    std::string strUsername = username;
+    std::string strPassword = password;
+#endif
+
+    UserManager& userManager = UserManager::getInstance();
+    if (!userManager.login(strUsername, strPassword, (m_checkRememberPassword.GetCheck() == BST_CHECKED))) {
+        AfxMessageBox(_T("鐧诲綍澶辫触銆�"));
+        return;
+    }
+
+    EndDialog(IDOK);
+}
+
+void CLoginDlg::OnBnClickedChangePassword()
+{
+    CChangePasswordDlg changePasswordDlg;
+    changePasswordDlg.DoModal();
+    if (changePasswordDlg.DoModal() == IDOK) {
+        m_editPassword.SetWindowText("");
+    }
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/View/LoginDlg.h b/SourceCode/Bond/BondEq/View/LoginDlg.h
new file mode 100644
index 0000000..e4674d5
--- /dev/null
+++ b/SourceCode/Bond/BondEq/View/LoginDlg.h
@@ -0,0 +1,32 @@
+锘�#pragma once
+#include "afxdialogex.h"
+
+
+// CLoginDlg 瀵硅瘽妗�
+
+class CLoginDlg : public CDialogEx
+{
+	DECLARE_DYNAMIC(CLoginDlg)
+
+public:
+	CLoginDlg(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CLoginDlg();
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_DIALOG_LOGIN };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+	virtual BOOL OnInitDialog();
+	afx_msg void OnBnClickedLogin();
+	afx_msg void OnBnClickedChangePassword();
+	DECLARE_MESSAGE_MAP()
+
+private:
+	CEdit m_editUsername;
+	CEdit m_editPassword;
+	CComboBox m_comboRole;
+	CButton m_checkRememberPassword;
+};
diff --git a/SourceCode/Bond/BondEq/res/BondServo.ico b/SourceCode/Bond/BondEq/res/BondServo.ico
new file mode 100644
index 0000000..d56fbcd
--- /dev/null
+++ b/SourceCode/Bond/BondEq/res/BondServo.ico
Binary files differ
diff --git a/SourceCode/Bond/BondEq/res/BondServo.rc2 b/SourceCode/Bond/BondEq/res/BondServo.rc2
new file mode 100644
index 0000000..9bf6b2e
--- /dev/null
+++ b/SourceCode/Bond/BondEq/res/BondServo.rc2
Binary files differ
diff --git a/SourceCode/Bond/BondEq/res/application.exe.manifest b/SourceCode/Bond/BondEq/res/application.exe.manifest
new file mode 100644
index 0000000..b96c40d
--- /dev/null
+++ b/SourceCode/Bond/BondEq/res/application.exe.manifest
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+    <assemblyIdentity
+         name="XP style manifest"
+         processorArchitecture="amd64"
+         version="1.0.0.0"
+         type="win32"/>
+    <dependency>
+        <dependentAssembly>
+            <assemblyIdentity
+                type="win32"
+                name="Microsoft.Windows.Common-Controls"
+                version="6.0.0.0"
+                processorArchitecture="amd64"
+                publicKeyToken="6595b64144ccf1df"
+                language="*"
+            />
+        </dependentAssembly>
+    </dependency>
+</assembly>
\ No newline at end of file
diff --git a/SourceCode/Bond/BondEq/stdafx.cpp b/SourceCode/Bond/BondEq/stdafx.cpp
new file mode 100644
index 0000000..f41be71
--- /dev/null
+++ b/SourceCode/Bond/BondEq/stdafx.cpp
@@ -0,0 +1,8 @@
+
+// stdafx.cpp : 只包括标准包含文件的源文件
+// BondServo.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+
diff --git a/SourceCode/Bond/BondEq/stdafx.h b/SourceCode/Bond/BondEq/stdafx.h
new file mode 100644
index 0000000..9226195
--- /dev/null
+++ b/SourceCode/Bond/BondEq/stdafx.h
@@ -0,0 +1,78 @@
+
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+
+#pragma once
+
+#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 扩展
+
+
+#include <afxdisp.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 支持
+
+
+
+
+
+
+#include "..\RxWindows1.0\include\RxWindowsLib.h"
+#include "..\BEQLibrarySDK\include\BEQLib.h"
+
+// 数据库模块
+#include "..\DatabaseSDK\include\Database.h"
+#include "..\DatabaseSDK\include\MySQLDatabase.h"
+#include "..\DatabaseSDK\include\SQLiteDatabase.h"
+
+#if defined(_WIN64)
+	#if defined(_DEBUG)
+		#pragma comment(lib, "..\\DatabaseSDK\\lib\\x64\\Debug\\DatabaseEx.lib")
+	#else
+		#pragma comment(lib, "..\\DatabaseSDK\\lib\\x64\\Release\\DatabaseEx.lib")
+	#endif
+#else
+	#if defined(_DEBUG)
+		#pragma comment(lib, "..\\DatabaseSDK\\lib\\Win32\\Debug\\DatabaseEx.lib")
+	#else
+		#pragma comment(lib, "..\\DatabaseSDK\\lib\\Win32\\Release\\DatabaseEx.lib")
+	#endif
+#endif
+
+
+
+
+
+
+#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
+
+
diff --git a/SourceCode/Bond/BondEq/targetver.h b/SourceCode/Bond/BondEq/targetver.h
new file mode 100644
index 0000000..416cebf
--- /dev/null
+++ b/SourceCode/Bond/BondEq/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
+
+// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
+// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
+
+#include <SDKDDKVer.h>
diff --git a/SourceCode/Bond/DatabaseSDK/include/Database.h b/SourceCode/Bond/DatabaseSDK/include/Database.h
new file mode 100644
index 0000000..e7a4733
--- /dev/null
+++ b/SourceCode/Bond/DatabaseSDK/include/Database.h
@@ -0,0 +1,25 @@
+#ifndef DATABASE_H
+#define DATABASE_H
+
+#include <string>
+#include <vector>
+
+#ifdef BUILDING_DLL
+#define DLL_API __declspec(dllexport)
+#else
+#define DLL_API __declspec(dllimport)
+#endif
+
+namespace BL {
+    class DLL_API Database {
+    public:
+        virtual ~Database() {}
+
+        virtual bool connect(const std::string& connectionString, bool createIfNotExists = false) = 0;
+        virtual void disconnect() = 0;
+        virtual bool executeQuery(const std::string& query) = 0;
+        virtual std::vector<std::vector<std::string>> fetchResults(const std::string& query) = 0;
+    };
+}
+
+#endif // DATABASE_H
diff --git a/SourceCode/Bond/DatabaseSDK/include/MySQLDatabase.h b/SourceCode/Bond/DatabaseSDK/include/MySQLDatabase.h
new file mode 100644
index 0000000..fa31e6f
--- /dev/null
+++ b/SourceCode/Bond/DatabaseSDK/include/MySQLDatabase.h
@@ -0,0 +1,25 @@
+#ifndef MYSQL_DATABASE_H
+#define MYSQL_DATABASE_H
+
+#include "Database.h"
+#include <string>
+#include <vector>
+
+namespace BL {
+    class DLL_API MySQLDatabase : public Database {
+    public:
+        MySQLDatabase();
+        virtual ~MySQLDatabase() override;
+
+        bool connect(const std::string& connectionString, bool createIfNotExists = false) override;
+        void disconnect() override;
+        bool executeQuery(const std::string& query) override;
+        std::vector<std::vector<std::string>> fetchResults(const std::string& query) override;
+
+    private:
+        class Impl;            // 前向声明内部实现类
+        Impl* m_impl;          // 使用原始指针指向内部实现类
+    };
+}
+
+#endif // MYSQL_DATABASE_H
diff --git a/SourceCode/Bond/DatabaseSDK/include/SQLiteDatabase.h b/SourceCode/Bond/DatabaseSDK/include/SQLiteDatabase.h
new file mode 100644
index 0000000..9f3c324
--- /dev/null
+++ b/SourceCode/Bond/DatabaseSDK/include/SQLiteDatabase.h
@@ -0,0 +1,25 @@
+#ifndef SQLITE_DATABASE_H
+#define SQLITE_DATABASE_H
+
+#include "Database.h"
+#include <string>
+#include <vector>
+
+namespace BL {
+    class DLL_API SQLiteDatabase : public Database {
+    public:
+        SQLiteDatabase();
+        virtual ~SQLiteDatabase() override;
+
+        bool connect(const std::string& connectionString, bool createIfNotExists = false) override;
+        void disconnect() override;
+        bool executeQuery(const std::string& query) override;
+        std::vector<std::vector<std::string>> fetchResults(const std::string& query) override;
+
+    private:
+        class Impl;           // 声明内部实现类
+        Impl* m_impl;         // 指向内部实现类的指针
+    };
+}
+
+#endif // SQLITE_DATABASE_H
diff --git a/SourceCode/Bond/GangBond2860.sln b/SourceCode/Bond/GangBond2860.sln
new file mode 100644
index 0000000..40d9e58
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860.sln
@@ -0,0 +1,61 @@
+锘�
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.23107.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BEQLibrary", "BEQLibrary\BEQLibrary.vcxproj", "{8421CE64-06F9-48F4-A3F3-ACFB683C94D4}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BEQDemo", "BEQDemo\BEQDemo.vcxproj", "{E374F8A0-F864-49F4-AF5C-F751AAC5F133}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GangBond2860Emulator", "GangBond2860Emulator\GangBond2860Emulator.vcxproj", "{E0EC2761-ABDE-4F89-937C-0B147FE26628}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BondEq", "BondEq\BondEq.vcxproj", "{7864134E-C538-4C0F-AF24-215FFCCBBAB4}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8421CE64-06F9-48F4-A3F3-ACFB683C94D4}.Debug|x64.ActiveCfg = Debug|x64
+		{8421CE64-06F9-48F4-A3F3-ACFB683C94D4}.Debug|x64.Build.0 = Debug|x64
+		{8421CE64-06F9-48F4-A3F3-ACFB683C94D4}.Debug|x86.ActiveCfg = Debug|Win32
+		{8421CE64-06F9-48F4-A3F3-ACFB683C94D4}.Debug|x86.Build.0 = Debug|Win32
+		{8421CE64-06F9-48F4-A3F3-ACFB683C94D4}.Release|x64.ActiveCfg = Release|x64
+		{8421CE64-06F9-48F4-A3F3-ACFB683C94D4}.Release|x64.Build.0 = Release|x64
+		{8421CE64-06F9-48F4-A3F3-ACFB683C94D4}.Release|x86.ActiveCfg = Release|Win32
+		{8421CE64-06F9-48F4-A3F3-ACFB683C94D4}.Release|x86.Build.0 = Release|Win32
+		{E374F8A0-F864-49F4-AF5C-F751AAC5F133}.Debug|x64.ActiveCfg = Debug|x64
+		{E374F8A0-F864-49F4-AF5C-F751AAC5F133}.Debug|x64.Build.0 = Debug|x64
+		{E374F8A0-F864-49F4-AF5C-F751AAC5F133}.Debug|x86.ActiveCfg = Debug|Win32
+		{E374F8A0-F864-49F4-AF5C-F751AAC5F133}.Debug|x86.Build.0 = Debug|Win32
+		{E374F8A0-F864-49F4-AF5C-F751AAC5F133}.Release|x64.ActiveCfg = Release|x64
+		{E374F8A0-F864-49F4-AF5C-F751AAC5F133}.Release|x64.Build.0 = Release|x64
+		{E374F8A0-F864-49F4-AF5C-F751AAC5F133}.Release|x86.ActiveCfg = Release|Win32
+		{E374F8A0-F864-49F4-AF5C-F751AAC5F133}.Release|x86.Build.0 = Release|Win32
+		{E0EC2761-ABDE-4F89-937C-0B147FE26628}.Debug|x64.ActiveCfg = Debug|x64
+		{E0EC2761-ABDE-4F89-937C-0B147FE26628}.Debug|x64.Build.0 = Debug|x64
+		{E0EC2761-ABDE-4F89-937C-0B147FE26628}.Debug|x86.ActiveCfg = Debug|Win32
+		{E0EC2761-ABDE-4F89-937C-0B147FE26628}.Debug|x86.Build.0 = Debug|Win32
+		{E0EC2761-ABDE-4F89-937C-0B147FE26628}.Release|x64.ActiveCfg = Release|x64
+		{E0EC2761-ABDE-4F89-937C-0B147FE26628}.Release|x64.Build.0 = Release|x64
+		{E0EC2761-ABDE-4F89-937C-0B147FE26628}.Release|x86.ActiveCfg = Release|Win32
+		{E0EC2761-ABDE-4F89-937C-0B147FE26628}.Release|x86.Build.0 = Release|Win32
+		{7864134E-C538-4C0F-AF24-215FFCCBBAB4}.Debug|x64.ActiveCfg = Debug|x64
+		{7864134E-C538-4C0F-AF24-215FFCCBBAB4}.Debug|x64.Build.0 = Debug|x64
+		{7864134E-C538-4C0F-AF24-215FFCCBBAB4}.Debug|x86.ActiveCfg = Debug|Win32
+		{7864134E-C538-4C0F-AF24-215FFCCBBAB4}.Debug|x86.Build.0 = Debug|Win32
+		{7864134E-C538-4C0F-AF24-215FFCCBBAB4}.Release|x64.ActiveCfg = Release|x64
+		{7864134E-C538-4C0F-AF24-215FFCCBBAB4}.Release|x64.Build.0 = Release|x64
+		{7864134E-C538-4C0F-AF24-215FFCCBBAB4}.Release|x86.ActiveCfg = Release|Win32
+		{7864134E-C538-4C0F-AF24-215FFCCBBAB4}.Release|x86.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {5E986E48-21B7-4EB6-97A1-49C49C727971}
+	EndGlobalSection
+EndGlobal
diff --git a/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.cpp b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.cpp
new file mode 100644
index 0000000..eee1f56
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.cpp
@@ -0,0 +1,137 @@
+
+// GangBond2860Emulator.cpp : 定义应用程序的类行为。
+//
+
+#include "stdafx.h"
+#include "GangBond2860Emulator.h"
+#include "GangBond2860EmulatorDlg.h"
+#include "HmTab.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+#define VERSION_NUMBER		1
+#define VERSION_NAME		_T("1.0.2")
+
+// CGangBond2860EmulatorApp
+
+BEGIN_MESSAGE_MAP(CGangBond2860EmulatorApp, CWinApp)
+	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CGangBond2860EmulatorApp 构造
+
+CGangBond2860EmulatorApp::CGangBond2860EmulatorApp()
+{
+	// 支持重新启动管理器
+	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
+
+	// TODO: 在此处添加构造代码,
+	// 将所有重要的初始化放置在 InitInstance 中
+
+	// 版本号及版本名称
+	m_nVersionNumber = VERSION_NUMBER;
+	m_strVersionName = VERSION_NAME;
+}
+
+
+// 唯一的一个 CGangBond2860EmulatorApp 对象
+
+CGangBond2860EmulatorApp theApp;
+
+
+// CGangBond2860EmulatorApp 初始化
+
+BOOL CGangBond2860EmulatorApp::InitInstance()
+{
+	// 如果一个运行在 Windows XP 上的应用程序清单指定要
+	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
+	//则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
+	INITCOMMONCONTROLSEX InitCtrls;
+	InitCtrls.dwSize = sizeof(InitCtrls);
+	// 将它设置为包括所有要在应用程序中使用的
+	// 公共控件类。
+	InitCtrls.dwICC = ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&InitCtrls);
+
+	CWinApp::InitInstance();
+
+
+	AfxEnableControlContainer();
+
+	// 创建 shell 管理器,以防对话框包含
+	// 任何 shell 树视图控件或 shell 列表视图控件。
+	CShellManager *pShellManager = new CShellManager;
+
+	// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题
+	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
+
+	// 标准初始化
+	// 如果未使用这些功能并希望减小
+	// 最终可执行文件的大小,则应移除下列
+	// 不需要的特定初始化例程
+	// 更改用于存储设置的注册表项
+	// TODO: 应适当修改该字符串,
+	// 例如修改为公司或组织名
+	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
+
+
+	// 本程序文件目录
+	TCHAR sDrive[_MAX_DRIVE];
+	TCHAR sDir[_MAX_DIR];
+	TCHAR sFilename[_MAX_FNAME], sAppFilename[_MAX_FNAME];
+	TCHAR sExt[_MAX_EXT];
+	GetModuleFileName(AfxGetInstanceHandle(), sAppFilename, _MAX_FNAME);
+	_tsplitpath_s(sAppFilename, sDrive, sDir, sFilename, sExt);
+	m_strAppDir = CString(sDrive) + CString(sDir);
+	m_strAppFile = CString(sFilename);
+
+
+
+	// 控件注册
+	CHmTab::RegisterWndClass();
+
+
+	// 初始化BEQ库
+	BEQ_Initialize();
+
+
+	CGangBond2860EmulatorDlg dlg;
+	m_pMainWnd = &dlg;
+	INT_PTR nResponse = dlg.DoModal();
+	if (nResponse == IDOK)
+	{
+		// TODO: 在此放置处理何时用
+		//  “确定”来关闭对话框的代码
+	}
+	else if (nResponse == IDCANCEL)
+	{
+		// TODO: 在此放置处理何时用
+		//  “取消”来关闭对话框的代码
+	}
+	else if (nResponse == -1)
+	{
+		TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");
+		TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
+	}
+
+	// 删除上面创建的 shell 管理器。
+	if (pShellManager != NULL)
+	{
+		delete pShellManager;
+	}
+
+	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
+	//  而不是启动应用程序的消息泵。
+	return FALSE;
+}
+
+int CGangBond2860EmulatorApp::ExitInstance()
+{
+	BEQ_Term();
+
+	return CWinApp::ExitInstance();
+}
diff --git a/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.h b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.h
new file mode 100644
index 0000000..a96fe03
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.h
@@ -0,0 +1,43 @@
+
+// GangBond2860Emulator.h : PROJECT_NAME 应用程序的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
+#endif
+
+#include "resource.h"		// 主符号
+#include "Model.h"
+
+
+// CGangBond2860EmulatorApp: 
+// 有关此类的实现,请参阅 GangBond2860Emulator.cpp
+//
+
+class CGangBond2860EmulatorApp : public CWinApp
+{
+public:
+	CGangBond2860EmulatorApp();
+
+
+public:
+	CString m_strAppDir;
+	CString m_strAppFile;
+	int m_nVersionNumber;
+	CString m_strVersionName;
+	CModel m_model;
+
+
+// 重写
+public:
+	virtual BOOL InitInstance();
+
+// 实现
+
+	DECLARE_MESSAGE_MAP()
+	virtual int ExitInstance();
+};
+
+extern CGangBond2860EmulatorApp theApp;
\ No newline at end of file
diff --git a/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.rc b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.rc
new file mode 100644
index 0000000..eb97639
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.rc
Binary files differ
diff --git a/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj
new file mode 100644
index 0000000..c41eccf
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj
@@ -0,0 +1,236 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{E0EC2761-ABDE-4F89-937C-0B147FE26628}</ProjectGuid>
+    <RootNamespace>GangBond2860Emulator</RootNamespace>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+    <Keyword>MFCProj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Static</UseOfMfc>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0804</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="GangBond2860Emulator.h" />
+    <ClInclude Include="GangBond2860EmulatorDlg.h" />
+    <ClInclude Include="HmTab.h" />
+    <ClInclude Include="Model.h" />
+    <ClInclude Include="PageEquipment.h" />
+    <ClInclude Include="PageUnit.h" />
+    <ClInclude Include="Resource.h" />
+    <ClInclude Include="stdafx.h" />
+    <ClInclude Include="targetver.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="GangBond2860Emulator.cpp" />
+    <ClCompile Include="GangBond2860EmulatorDlg.cpp" />
+    <ClCompile Include="HmTab.cpp" />
+    <ClCompile Include="Model.cpp" />
+    <ClCompile Include="PageEquipment.cpp" />
+    <ClCompile Include="PageUnit.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="GangBond2860Emulator.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\GangBond2860Emulator.rc2" />
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\GangBond2860Emulator.ico" />
+  </ItemGroup>
+  <ItemGroup>
+    <Manifest Include="res\application.exe.manifest" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+  <ProjectExtensions>
+    <VisualStudio>
+      <UserProperties RESOURCE_FILE="GangBond2860Emulator.rc" />
+    </VisualStudio>
+  </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj.filters b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj.filters
new file mode 100644
index 0000000..d64d349
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj.filters
@@ -0,0 +1,90 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="婧愭枃浠�">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="澶存枃浠�">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="璧勬簮鏂囦欢">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="GangBond2860Emulator.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="GangBond2860EmulatorDlg.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="stdafx.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Resource.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="HmTab.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="PageUnit.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="PageEquipment.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+    <ClInclude Include="Model.h">
+      <Filter>澶存枃浠�</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="GangBond2860Emulator.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="GangBond2860EmulatorDlg.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="HmTab.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="PageUnit.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="PageEquipment.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+    <ClCompile Include="Model.cpp">
+      <Filter>婧愭枃浠�</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="GangBond2860Emulator.rc">
+      <Filter>璧勬簮鏂囦欢</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\GangBond2860Emulator.rc2">
+      <Filter>璧勬簮鏂囦欢</Filter>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\GangBond2860Emulator.ico">
+      <Filter>璧勬簮鏂囦欢</Filter>
+    </Image>
+  </ItemGroup>
+  <ItemGroup>
+    <Manifest Include="res\application.exe.manifest" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj.user b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj.user
new file mode 100644
index 0000000..88a5509
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/GangBond2860Emulator.vcxproj.user
@@ -0,0 +1,4 @@
+锘�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/SourceCode/Bond/GangBond2860Emulator/GangBond2860EmulatorDlg.cpp b/SourceCode/Bond/GangBond2860Emulator/GangBond2860EmulatorDlg.cpp
new file mode 100644
index 0000000..01d8250
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/GangBond2860EmulatorDlg.cpp
@@ -0,0 +1,274 @@
+
+// GangBond2860EmulatorDlg.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "GangBond2860Emulator.h"
+#include "GangBond2860EmulatorDlg.h"
+#include "afxdialogex.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
+
+class CAboutDlg : public CDialogEx
+{
+public:
+	CAboutDlg();
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_ABOUTBOX };
+#endif
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+// 实现
+protected:
+	DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+
+// CGangBond2860EmulatorDlg 对话框
+
+
+
+CGangBond2860EmulatorDlg::CGangBond2860EmulatorDlg(CWnd* pParent /*=NULL*/)
+	: CDialogEx(IDD_GANGBOND2860EMULATOR_DIALOG, pParent)
+{
+	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+	m_pTab = nullptr;
+	m_crBkgnd = RGB(255, 255, 255);
+	m_hbrBkgnd = nullptr;
+	m_pPageEquipment = nullptr;
+	m_pPageUnitA = nullptr;
+	m_pPageUnitB = nullptr;
+}
+
+void CGangBond2860EmulatorDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CGangBond2860EmulatorDlg, CDialogEx)
+	ON_WM_SYSCOMMAND()
+	ON_WM_PAINT()
+	ON_WM_QUERYDRAGICON()
+	ON_WM_CTLCOLOR()
+	ON_WM_DESTROY()
+	ON_WM_SIZE()
+	ON_NOTIFY(BYHMTAB_SEL_CHANGED, IDC_HMTAB1, &CGangBond2860EmulatorDlg::OnTabSelChanged)
+END_MESSAGE_MAP()
+
+
+// CGangBond2860EmulatorDlg 消息处理程序
+
+BOOL CGangBond2860EmulatorDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// 将“关于...”菜单项添加到系统菜单中。
+
+	// IDM_ABOUTBOX 必须在系统命令范围内。
+	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+	ASSERT(IDM_ABOUTBOX < 0xF000);
+
+	CMenu* pSysMenu = GetSystemMenu(FALSE);
+	if (pSysMenu != NULL)
+	{
+		BOOL bNameValid;
+		CString strAboutMenu;
+		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
+		ASSERT(bNameValid);
+		if (!strAboutMenu.IsEmpty())
+		{
+			pSysMenu->AppendMenu(MF_SEPARATOR);
+			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+		}
+	}
+
+	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
+	//  执行此操作
+	SetIcon(m_hIcon, TRUE);			// 设置大图标
+	SetIcon(m_hIcon, FALSE);		// 设置小图标
+
+
+	// 子页面
+	m_pPageEquipment = new CPageEquipment();
+	m_pPageEquipment->Create(IDD_PAGE_EQUIPMENT, this);
+	m_pPageUnitA = new CPageUnit();
+	m_pPageUnitA->Create(IDD_PAGE_UNIT, this);
+	m_pPageUnitA->setName("UNITA");	
+	m_pPageUnitB = new CPageUnit();
+	m_pPageUnitB->Create(IDD_PAGE_UNIT, this);
+	m_pPageUnitB->setName("UNITB");
+
+
+
+	// Tab
+	m_pTab = CHmTab::Hook(GetDlgItem(IDC_HMTAB1)->m_hWnd);
+	m_pTab->SetPaddingLeft(20);
+	m_pTab->SetItemMarginLeft(18);
+	m_pTab->SetBkgndColor(RGB(255, 255, 255));
+	m_pTab->AddItem("机器信息", FALSE);
+	m_pTab->AddItem("UNITA", FALSE);
+	m_pTab->AddItem("UNITB", FALSE);
+	m_pTab->SetCurSel(0);
+
+
+	ShowChildPage(0);
+	// ShowWindow(SW_MAXIMIZE);
+	Resize();
+
+
+
+	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
+}
+
+void CGangBond2860EmulatorDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+	{
+		CAboutDlg dlgAbout;
+		dlgAbout.DoModal();
+	}
+	else
+	{
+		CDialogEx::OnSysCommand(nID, lParam);
+	}
+}
+
+// 如果向对话框添加最小化按钮,则需要下面的代码
+//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
+//  这将由框架自动完成。
+
+void CGangBond2860EmulatorDlg::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 CGangBond2860EmulatorDlg::OnQueryDragIcon()
+{
+	return static_cast<HCURSOR>(m_hIcon);
+}
+
+HBRUSH CGangBond2860EmulatorDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
+{
+	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
+
+	if (nCtlColor == CTLCOLOR_STATIC) {
+		pDC->SetBkColor(m_crBkgnd);
+	}
+
+	if (m_hbrBkgnd == nullptr) {
+		m_hbrBkgnd = CreateSolidBrush(m_crBkgnd);
+	}
+
+	return m_hbrBkgnd;
+}
+
+void CGangBond2860EmulatorDlg::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+	if (m_pPageEquipment != nullptr) {
+		m_pPageEquipment->DestroyWindow();
+		delete m_pPageEquipment;
+		m_pPageEquipment = nullptr;
+	}
+
+	if (m_pPageUnitA != nullptr) {
+		m_pPageUnitA->DestroyWindow();
+		delete m_pPageUnitA;
+		m_pPageUnitA = nullptr;
+	}
+
+	if (m_pPageUnitB != nullptr) {
+		m_pPageUnitB->DestroyWindow();
+		delete m_pPageUnitB;
+		m_pPageUnitB = nullptr;
+	}
+
+	if (m_hbrBkgnd != nullptr) {
+		::DeleteObject(m_hbrBkgnd);
+	}
+}
+
+void CGangBond2860EmulatorDlg::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+	if (GetDlgItem(IDC_HMTAB1) == nullptr) return;
+	Resize();
+}
+
+void CGangBond2860EmulatorDlg::ShowChildPage(int index)
+{
+	ASSERT(0 <= index && index < 3);
+	static CWnd* pPages[] = { m_pPageEquipment, m_pPageUnitA, m_pPageUnitB };
+	for (int i = 0; i < 3; i++) {
+		pPages[i]->ShowWindow(i == index ? SW_SHOW : SW_HIDE);
+	}
+}
+
+void CGangBond2860EmulatorDlg::OnTabSelChanged(NMHDR* nmhdr, LRESULT* result)
+{
+	BYHMTAB_NMHDR* pNmhdrex = (BYHMTAB_NMHDR*)nmhdr;
+	ShowChildPage((int)pNmhdrex->dwData);
+
+	*result = 0;
+}
+
+void CGangBond2860EmulatorDlg::Resize()
+{
+	CRect rcClient, rcItem;
+	GetClientRect(&rcClient);
+
+	int x = 8;
+	int y = 12;
+	GetDlgItem(IDC_HMTAB1)->GetWindowRect(&rcItem);
+	GetDlgItem(IDC_HMTAB1)->MoveWindow(x, y, rcClient.Width() - x * 2, rcItem.Height());
+	y += rcItem.Height();
+	y += 1;
+
+	m_pPageEquipment->MoveWindow(x, y, rcClient.Width() - x * 2, rcClient.Height() - y);
+	m_pPageUnitA->MoveWindow(x, y, rcClient.Width() - x * 2, rcClient.Height() - y);
+	m_pPageUnitB->MoveWindow(x, y, rcClient.Width() - x * 2, rcClient.Height() - y);
+}
diff --git a/SourceCode/Bond/GangBond2860Emulator/GangBond2860EmulatorDlg.h b/SourceCode/Bond/GangBond2860Emulator/GangBond2860EmulatorDlg.h
new file mode 100644
index 0000000..3fb1939
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/GangBond2860EmulatorDlg.h
@@ -0,0 +1,56 @@
+
+// GangBond2860EmulatorDlg.h : 头文件
+//
+
+#pragma once
+#include "HmTab.h"
+#include "PageEquipment.h"
+#include "PageUnit.h"
+
+
+// CGangBond2860EmulatorDlg 对话框
+class CGangBond2860EmulatorDlg : public CDialogEx
+{
+// 构造
+public:
+	CGangBond2860EmulatorDlg(CWnd* pParent = NULL);	// 标准构造函数
+
+
+private:
+	void ShowChildPage(int index);
+	void Resize();
+
+
+private:
+	COLORREF m_crBkgnd;
+	HBRUSH m_hbrBkgnd;
+	CHmTab* m_pTab;
+	CPageEquipment* m_pPageEquipment;
+	CPageUnit* m_pPageUnitA;
+	CPageUnit* m_pPageUnitB;
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_GANGBOND2860EMULATOR_DIALOG };
+#endif
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
+
+
+// 实现
+protected:
+	HICON m_hIcon;
+
+	// 生成的消息映射函数
+	virtual BOOL OnInitDialog();
+	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+	afx_msg void OnPaint();
+	afx_msg HCURSOR OnQueryDragIcon();
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnDestroy();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnTabSelChanged(NMHDR* nmhdr, LRESULT* result);
+};
diff --git a/SourceCode/Bond/GangBond2860Emulator/HmTab.cpp b/SourceCode/Bond/GangBond2860Emulator/HmTab.cpp
new file mode 100644
index 0000000..29e13c9
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/HmTab.cpp
@@ -0,0 +1,529 @@
+// HmTab.cpp: implementation of the CHmTab class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+#include "HmTab.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CHmTab::CHmTab()
+{
+	m_hWnd = NULL;
+	m_crBkgnd = RGB(250, 250, 255);
+	m_nPaddingLeft = 28;
+	m_nPaddingBottom = 12;
+	m_nItemMarginLeft = 8;
+	m_crText[0] = RGB(88, 88, 88);
+	m_crText[1] = RGB(18, 18, 18);
+	m_pPressItem = nullptr;
+	m_pHighItem = nullptr;
+
+	LOGBRUSH lb;
+	lb.lbColor = RGB(225, 127, 39);
+	lb.lbHatch = 0;
+	lb.lbStyle = BS_SOLID;
+	DWORD iStyle = PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_SQUARE | PS_JOIN_MITER;
+	m_hPenUnder[0] = ExtCreatePen(iStyle, 3, &lb, 0, NULL);
+	lb.lbColor = RGB(225, 127, 39);
+	m_hPenUnder[1] = ExtCreatePen(iStyle, 2, &lb, 0, NULL);
+	lb.lbColor = RGB(223, 226, 230);
+	m_hPenUnderWnd = ExtCreatePen(iStyle, 1, &lb, 0, NULL);
+	m_nCurSel = 0;
+}
+
+CHmTab::~CHmTab()
+{
+	if (m_hPenUnder[0] != nullptr) {
+		::DeleteObject(m_hPenUnder[0]);
+	}
+	if (m_hPenUnder[1] != nullptr) {
+		::DeleteObject(m_hPenUnder[1]);
+	}
+
+	if (m_hPenUnderWnd != nullptr) {
+		::DeleteObject(m_hPenUnderWnd);
+	}
+}
+
+BOOL CHmTab::RegisterWndClass()
+{
+	WNDCLASS wc;
+	wc.lpszClassName = BYHMTAB_CLASS;
+	wc.hInstance = AfxGetInstanceHandle();
+	wc.lpfnWndProc = WindowProc;
+	wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+	wc.hIcon = 0;
+	wc.lpszMenuName = NULL;
+	wc.hbrBackground = NULL;
+	wc.style = CS_GLOBALCLASS|CS_DBLCLKS;
+	wc.cbClsExtra = 0;
+	wc.cbWndExtra = 0;
+	
+	// 注册自定义类
+	return (::RegisterClass(&wc) != 0);
+}
+
+CHmTab* CHmTab::Hook(HWND hWnd)
+{
+	CHmTab* pHmTab = (CHmTab*)GetProp(hWnd, BYSTAG_HMTAB);
+	if(pHmTab == NULL)
+	{
+		pHmTab = new CHmTab;
+		pHmTab->m_hWnd = hWnd;
+
+		SetProp(hWnd, BYSTAG_HMTAB, (HANDLE)pHmTab);
+	}
+	
+	return pHmTab;
+}
+
+void CHmTab::Release()
+{
+	// delete
+	delete this;
+}
+
+void CHmTab::SetPaddingLeft(int value)
+{
+	m_nPaddingLeft = value;
+}
+
+void CHmTab::SetItemMarginLeft(int value)
+{
+	m_nItemMarginLeft = value;
+}
+
+void CHmTab::SetTextColor(COLORREF color1, COLORREF color2)
+{
+	m_crText[0] = color1;
+	m_crText[1] = color2;
+	InvalidateRect(m_hWnd, NULL, TRUE);
+}
+
+int CHmTab::AddItem(const char* pszText,BOOL bUpdate/* = TRUE*/)
+{
+	HMTABITEM item;
+	memset(&item, 0, sizeof(HMTABITEM));
+	strcpy_s(item.szText, MHITEM_TEXT_MAX, pszText);
+	m_items.push_back(item);
+
+	if (bUpdate) {
+		InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+
+	return 0;
+}
+
+int CHmTab::DeleteItem(const char* pszText, BOOL bUpdate/* = TRUE*/)
+{
+	for (auto iter = m_items.begin(); iter != m_items.end(); iter++) {
+		if (strcmp((*iter).szText, pszText) == 0) {
+			m_items.erase(iter);
+			break;
+		}
+	}
+
+	if (bUpdate) {
+		InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+
+	return 0;
+}
+
+void CHmTab::Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1/* = 0*/, DWORD_PTR dwData2/* = 0*/)
+{
+	HWND hParent;
+	hParent = GetParent(m_hWnd);
+	if (hParent != NULL) {
+		BYHMTAB_NMHDR iii_nmhdr;
+		iii_nmhdr.nmhdr.hwndFrom = m_hWnd;
+		iii_nmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
+		iii_nmhdr.nmhdr.code = nCode;
+		iii_nmhdr.dwData = dwData;
+		iii_nmhdr.dwData1 = dwData1;
+		iii_nmhdr.dwData2 = dwData2;
+		SendMessage(hParent, WM_NOTIFY, (WPARAM)iii_nmhdr.nmhdr.idFrom, (LPARAM)&iii_nmhdr);
+	}
+}
+
+////////////////////////////////
+// 拦截窗口消息函数
+LRESULT CALLBACK CHmTab::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)   
+{
+	CHmTab* pHmTab = (CHmTab *)GetProp(hWnd, BYSTAG_HMTAB);
+	if(pHmTab == NULL && uMsg != WM_NCCREATE)
+	{
+		return ::DefWindowProc(hWnd, uMsg, wParam, lParam);   
+	}
+
+	
+	// 如果Hook则响应消息
+	ASSERT(hWnd);
+	switch(uMsg)   
+	{
+	case WM_NCCREATE:
+		return OnNcCreate(hWnd, wParam, lParam);
+
+	case WM_DESTROY:
+		return pHmTab->OnDestroy(wParam, lParam);
+
+	case WM_PAINT:
+		return pHmTab->OnPaint(wParam, lParam);
+
+	case WM_TIMER:
+		return pHmTab->OnTimer(wParam, lParam);
+
+	case WM_MOUSEMOVE:
+		return pHmTab->OnMouseMove(wParam, lParam);
+
+	case WM_LBUTTONDOWN:
+		return pHmTab->OnLButtonDown(wParam, lParam);
+
+	case WM_SETCURSOR:
+		return pHmTab->OnSetCursor(wParam, lParam);
+
+	case WM_SIZE:
+		return pHmTab->OnSize(wParam, lParam);
+
+	case WM_GETDLGCODE:
+		return DLGC_WANTALLKEYS;
+
+	default:
+		break;
+	}
+	
+	return ::DefWindowProc(hWnd, uMsg, wParam, lParam);   
+}  
+
+///////////////////////////////
+// WM_NCCREATE
+// 窗口创建前的初始化工作
+LRESULT CHmTab::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+	CHmTab* pHmTab = (CHmTab *)GetProp(hWnd, BYSTAG_HMTAB);
+	ASSERT(pHmTab == NULL);
+
+	Hook(hWnd);
+	return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_DESTROY
+LRESULT CHmTab::OnDestroy(WPARAM wParam, LPARAM lParam)
+{
+	Release();
+	return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_TIMER
+LRESULT CHmTab::OnTimer(WPARAM wParam, LPARAM lParam)
+{
+	if (wParam == 1) {
+		POINT pt;
+		GetCursorPos(&pt);
+		::ScreenToClient(m_hWnd, &pt);
+
+		HMTABITEM* pLastHighItem = m_pHighItem;
+		HighTest(pt, m_pHighItem, nullptr);
+		if (m_pHighItem != pLastHighItem) {
+			::InvalidateRect(m_hWnd, NULL, TRUE);
+		}
+
+		if (m_pHighItem == nullptr) {
+			::KillTimer(m_hWnd, 1);
+		}
+	}
+
+	return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_MOUSEMOVE
+LRESULT CHmTab::OnMouseMove(WPARAM wParam, LPARAM lParam)
+{
+	POINT pt;
+	pt.x = LOWORD(lParam);
+	pt.y = HIWORD(lParam);
+
+	HMTABITEM* pLastHighItem = m_pHighItem;
+	int nHitCode = HighTest(pt, m_pHighItem, nullptr);
+	if (m_pHighItem != pLastHighItem) {
+		RECT rcClient;
+		GetClientRect(m_hWnd, &rcClient);
+		::InvalidateRect(m_hWnd, &rcClient, TRUE);
+	}
+	if (m_pHighItem != NULL) {
+		::KillTimer(m_hWnd, 1);
+		::SetTimer(m_hWnd, 1, 100, NULL);
+	}
+
+	::SetProp(m_hWnd, HMTAB_HITCODETEST, (HANDLE)(__int64)nHitCode);
+	return ::DefWindowProc(m_hWnd, WM_MOUSEMOVE, wParam, lParam);
+}
+
+/*
+ * WM_LBUTTONDOWN
+ * 鼠标左键按下
+ */
+LRESULT CHmTab::OnLButtonDown(WPARAM wParam, LPARAM lParam)
+{
+	POINT pt, ptNew;
+	pt.x = LOWORD(lParam);
+	pt.y = HIWORD(lParam);
+
+	BOOL bButtonUp = FALSE;
+	int nClickIndex = -1;
+	HighTest(pt, m_pPressItem, &nClickIndex);
+	if (m_pPressItem != NULL) {
+		m_pHighItem = NULL;
+		::InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+
+
+	// 捕捉鼠标消息,检测是否拖动
+	HMTABITEM* pPressItem = NULL;
+	if (m_pPressItem != NULL) {
+		::KillTimer(m_hWnd, 1);
+		if (::GetCapture() == NULL) {
+			SetCapture(m_hWnd);
+			ASSERT(m_hWnd == GetCapture());
+			AfxLockTempMaps();
+			for (;;)
+			{
+				MSG msg;
+				VERIFY(::GetMessage(&msg, NULL, 0, 0));
+
+				if (GetCapture() != m_hWnd) break;
+
+				switch (msg.message)
+				{
+				case WM_MOUSEMOVE:
+					ptNew = msg.pt;
+					::ScreenToClient(m_hWnd, &ptNew);
+					HighTest(ptNew, pPressItem, &nClickIndex);
+					if (pPressItem != m_pPressItem) {
+						m_pPressItem = nullptr;
+						::InvalidateRect(m_hWnd, NULL, TRUE);
+					}
+					break;
+
+				case WM_LBUTTONUP:
+					ptNew = msg.pt;
+					::ScreenToClient(m_hWnd, &ptNew);
+					HighTest(ptNew, pPressItem, &nClickIndex);
+					if (m_pPressItem != nullptr && pPressItem == m_pPressItem) {
+						m_nCurSel = nClickIndex;
+						bButtonUp = TRUE;
+					}
+					goto ExitLoop;
+
+				case WM_KEYDOWN:
+					if (msg.wParam == VK_ESCAPE) {
+						goto ExitLoop;
+					}
+					break;
+
+				default:
+					DispatchMessage(&msg);
+					break;
+				}
+			}
+
+		ExitLoop:
+			m_pPressItem = NULL;
+			ReleaseCapture();
+			::InvalidateRect(m_hWnd, NULL, TRUE);
+
+			if (bButtonUp) {
+				Notify((int)BYHMTAB_SEL_CHANGED, m_nCurSel);
+			}
+
+			AfxUnlockTempMaps(FALSE);
+		}
+	}
+
+
+	return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_SETCURSOR
+LRESULT CHmTab::OnSetCursor(WPARAM wParam, LPARAM lParam)
+{
+	int nHitCode = (int)(__int64)GetProp(m_hWnd, HMTAB_HITCODETEST);
+	switch (nHitCode)
+	{
+	case HMTAB_HT_NOWHERE:
+	case HMTAB_HT_ITEM:
+		SetCursor(::LoadCursor(NULL, IDC_ARROW));
+		return TRUE;
+
+	case HMTAB_HT_HIGT_ITEM:
+		SetCursor(::LoadCursor(NULL, IDC_HAND));
+		return TRUE;
+
+	default:
+		break;
+	}
+
+	return ::DefWindowProc(m_hWnd, WM_SETCURSOR, wParam, lParam);
+}
+
+/*
+ * WM_SIZE
+ */
+LRESULT CHmTab::OnSize(WPARAM wParam, LPARAM lParam)
+{
+	::InvalidateRect(m_hWnd, NULL, TRUE);
+	return ::DefWindowProc(m_hWnd, WM_SIZE, wParam, lParam);
+}
+
+///////////////////////////////
+// WM_PAINT
+LRESULT CHmTab::OnPaint(WPARAM wParam, LPARAM lParam)
+{
+	HDC hDC, hMemDC;
+	HBITMAP hBitmap;
+	RECT rcClient;
+	CString strText;
+	HFONT hFont1, hFont2;
+	HBRUSH hBrushBK;
+
+
+	// BeginPaint
+	PAINTSTRUCT ps;
+	hDC = BeginPaint(m_hWnd, &ps);
+	GetClientRect(m_hWnd, &rcClient);
+
+	hMemDC = ::CreateCompatibleDC(hDC);
+	hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left,
+		rcClient.bottom - rcClient.top);
+	::SelectObject(hMemDC, hBitmap);
+	::SetBkMode(hMemDC, TRANSPARENT);
+
+
+	HFONT hFontDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+	CFont* pFont = CFont::FromHandle(hFontDefault);
+	LOGFONT lf;
+	pFont->GetLogFont(&lf);
+	hFont1 = ::CreateFontIndirect(&lf);
+	lf.lfHeight -= 5;
+	hFont2 = ::CreateFontIndirect(&lf);
+
+
+	// 背景颜色
+	hBrushBK = CreateSolidBrush(m_crBkgnd);
+	::FillRect(hMemDC, &rcClient, hBrushBK);
+	DeleteObject(hBrushBK);
+
+
+	SelectObject(hMemDC, m_hPenUnderWnd);
+	::MoveToEx(hMemDC, rcClient.left, rcClient.bottom - 2, NULL);
+	::LineTo(hMemDC, rcClient.right, rcClient.bottom - 2);
+
+
+
+	// 绘制子项
+	SIZE sizeItem;
+	RECT rcItem, rcText;
+	rcItem.top = rcClient.top;
+	rcItem.bottom = rcClient.bottom-1;
+	rcItem.left = m_nPaddingLeft;
+	int index = 0;
+	for (int i = 0; i < m_items.size(); i++) {
+		auto& item = m_items.at(i);
+		::SelectObject(hMemDC, i == m_nCurSel ? hFont2 : hFont1);
+		::SetTextColor(hMemDC, i == m_nCurSel ? m_crText[1] : m_crText[0]);
+		::GetTextExtentPoint32(hMemDC, item.szText, (int)strlen(item.szText), &sizeItem);
+		rcItem.left += m_nItemMarginLeft;
+		rcItem.right = rcItem.left + (int)sizeItem.cx;
+
+		::CopyRect(&rcText, &rcItem);
+		rcText.bottom -= m_nPaddingBottom;
+		::DrawText(hMemDC, item.szText, (int)strlen(item.szText), &rcText,
+			DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS);
+		::CopyRect(&item.rect, &rcItem);
+
+
+		// 下划线?
+		if (i == m_nCurSel || &item == m_pHighItem) {
+			HPEN hOldPen = (HPEN)::SelectObject(hMemDC, i == m_nCurSel ? m_hPenUnder[0] : m_hPenUnder[1]);
+			::MoveToEx(hMemDC, item.rect.left, item.rect.bottom - 3, NULL);
+			::LineTo(hMemDC, item.rect.right, item.rect.bottom - 3);
+			::SelectObject(hMemDC, hOldPen);
+		}
+
+
+		index++;
+		rcItem.left = rcItem.right;
+	}
+	::DeleteObject(hFont1);
+	::DeleteObject(hFont2);
+
+
+	// EndPaint
+	::BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
+		hMemDC, 0, 0, SRCCOPY);
+	EndPaint(m_hWnd, &ps);
+	::DeleteObject(hBitmap);
+	::DeleteDC(hMemDC);
+
+
+	return 1;
+}
+
+void CHmTab::SetBkgndColor(COLORREF cr)
+{
+	m_crBkgnd = cr;
+}
+
+/*
+ * 检测坐标点所在的项
+ * 返回, TYGTLITEM
+ */
+int CHmTab::HighTest(POINT pt, OUT HMTABITEM*& pItem, int* pnIndex)
+{
+	// 检测是否在某个子项
+	int nRet = HMTAB_HT_NOWHERE;
+	pItem = NULL;
+	for (int i = 0; i < m_items.size(); i++) {
+		auto& item = m_items.at(i);
+		if (::PtInRect(&item.rect, pt)) {
+			pItem = &item;
+			nRet = pItem == m_pHighItem ? HMTAB_HT_HIGT_ITEM : HMTAB_HT_ITEM;
+			if (pnIndex != nullptr) *pnIndex = i;
+			break;
+		}
+	}
+
+
+	return nRet;
+}
+
+int CHmTab::GetCurSel()
+{
+	return m_nCurSel;
+}
+
+void CHmTab::SetCurSel(int index)
+{
+	if (0 <= index && index <= m_items.size()) {
+		m_nCurSel = index;
+		InvalidateRect(m_hWnd, NULL, TRUE);
+	}
+}
+
+int CHmTab::GetItemCount()
+{
+	return (int)m_items.size();
+}
diff --git a/SourceCode/Bond/GangBond2860Emulator/HmTab.h b/SourceCode/Bond/GangBond2860Emulator/HmTab.h
new file mode 100644
index 0000000..600b5b1
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/HmTab.h
@@ -0,0 +1,130 @@
+// HmTab.h: interface for the CHmTab class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_HMTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
+#define AFX_HMTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_
+
+
+#pragma comment(lib, "Msimg32.lib")			// TransparentBlt
+#include <vector>
+
+
+
+//====== HmTab =====================================================
+
+#ifndef NOHMTAB
+
+#ifdef _WIN32
+
+#define BYHMTAB_CLASSA       "BYHmTab"
+#define BYHMTAB_CLASSW       L"BYHmTab"
+
+#ifdef UNICODE
+#define  BYHMTAB_CLASS       BYHMTAB_CLASSW
+#else
+#define  BYHMTAB_CLASS       BYHMTAB_CLASSA
+#endif
+
+#else
+#define BYHMTAB_CLASS        "BYHmTab"
+#endif
+
+
+#define BYSTAG_HMTAB		 _T("ISHMTAB")
+
+
+//====== WM_NOTIFY codes (NMHDR.code values) ==================================
+#define BYHMTAB_FIRST				 (0U-1190U)       //
+#define BYHMTAB_LAST				 (0U-1150U)
+#define BYHMTAB_SEL_CHANGED	 		 (BYHMTAB_FIRST - 1)
+
+
+
+
+typedef struct tagBYHMTAB_NMHDR
+{
+	NMHDR		nmhdr;
+	DWORD_PTR	dwData;
+	DWORD_PTR	dwData1;
+	DWORD_PTR	dwData2;
+} BYHMTAB_NMHDR;
+
+#define MHITEM_TEXT_MAX		64
+
+typedef struct tagHMTABITEM
+{
+	int id;
+	char szText[MHITEM_TEXT_MAX];
+	RECT rect;
+} HMTABITEM;
+
+#define HMTAB_HITCODETEST			_T("HitCode")
+#define HMTAB_HT_NOWHERE			0x1
+#define HMTAB_HT_ITEM				0x2
+#define HMTAB_HT_HIGT_ITEM			0x4
+
+
+#endif
+
+
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+class CHmTab
+{
+public:
+	CHmTab();
+	virtual ~CHmTab();
+
+public:
+	static BOOL RegisterWndClass();
+	static CHmTab* Hook(HWND hWnd);
+	void Notify(int nCode, DWORD_PTR dwData, DWORD_PTR dwData1 = 0, DWORD_PTR dwData2 = 0);
+	void Release();
+	void SetBkgndColor(COLORREF cr);
+	static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+	static LRESULT OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
+	LRESULT OnDestroy(WPARAM wParam, LPARAM lParam);
+	LRESULT OnTimer(WPARAM wParam, LPARAM lParam);
+	LRESULT OnPaint(WPARAM wParam, LPARAM lParam);
+	LRESULT OnSetCursor(WPARAM wParam, LPARAM lParam);
+	LRESULT OnSize(WPARAM wParam, LPARAM lParam);
+	LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam);
+	LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam);
+
+
+public:
+	void SetPaddingLeft(int value);
+	void SetItemMarginLeft(int value);
+	void SetTextColor(COLORREF color1, COLORREF color2);
+	int AddItem(const char* pszText, BOOL bUpdate = TRUE);
+	int DeleteItem(const char* pszText, BOOL bUpdate = TRUE);
+	int HighTest(POINT pt, OUT HMTABITEM*& pItem, int* pnIndex);
+	int GetCurSel();
+	void SetCurSel(int index);
+	int GetItemCount();
+
+
+private:
+	HWND		m_hWnd;
+	COLORREF m_crBkgnd;
+
+private:
+	int m_nCurSel;
+	std::vector< HMTABITEM > m_items;
+	HMTABITEM* m_pHighItem;
+	HMTABITEM* m_pPressItem;
+	int m_nPaddingLeft;
+	int m_nPaddingBottom;
+	int m_nItemMarginLeft;
+	COLORREF m_crText[2];
+	HPEN m_hPenUnder[2];
+	HPEN m_hPenUnderWnd;
+};
+
+#endif // !defined(AFX_HMTAB_H__FBB8916A_DE77_4EA3_9C21_E51E6B06194C__INCLUDED_)
diff --git a/SourceCode/Bond/GangBond2860Emulator/Model.cpp b/SourceCode/Bond/GangBond2860Emulator/Model.cpp
new file mode 100644
index 0000000..7c6e87e
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/Model.cpp
@@ -0,0 +1,84 @@
+#include "stdafx.h"
+#include "Model.h"
+
+
+CModel::CModel()
+{
+	m_pEuqipment = nullptr;
+}
+
+
+CModel::~CModel()
+{
+}
+
+BEQ::IEquipment* CModel::createEquipment(const char* pszName)
+{
+	if (m_pEuqipment != nullptr) {
+		return nullptr;
+	}
+
+	m_strEquipmentName = pszName;
+	BEQ_CreateEquipment(m_pEuqipment, pszName);
+	if (m_pEuqipment != nullptr) {
+		BEQ::EquipmentListener listener;
+		listener.onConnected = [&](void* pEquipment, const char* pszAddr, int port) -> int {
+			TRACE("%s:%d连接进入.", pszAddr, port);
+			return 0;
+		};
+		listener.onDisconnected = [&](void* pEquipment, const char* pszAddr, int port) -> int {
+			TRACE("%s:%d连接断开.\n", pszAddr, port);
+			return 0;
+		};
+		listener.onRunRecipe = [&](void* pEquipment, void* pUnit, int id) -> int {
+			BEQ::IUnit* p = (BEQ::IUnit*)pUnit;
+			char szUnitName[256];
+			p->getName(szUnitName, 256);
+			m_mapRecipe[szUnitName] = id;
+			TRACE("%s正在切换至配方%d.\n", szUnitName, id);
+			// 做切换配方的动作
+			Sleep(2000);
+
+			return 0;
+		};
+		listener.onGetRecipeList = [&](void* pEquipment, void* pUnit) -> int {
+			BEQ::IUnit* p = (BEQ::IUnit*)pUnit;
+			char szUnitName[256];
+			p->getName(szUnitName, 256);
+			TRACE("中控请求获取单元[%s]配方列表.\n", szUnitName);
+			// 在此更新配方
+			// p->addRecipe();
+			Sleep(2000);
+
+			// 阻塞方式返回0,
+			// 多线程方式先返回1,在线程中获取完配方后,调用
+			// IEquipment::repRecipeListComplete异步返回数据
+			return 0;
+		};
+		listener.onLoadReady = [&](void* pEquipment, void* pUnit, const char* pszMaterielId, const char* pszRecipeId) -> int {
+			BEQ::IUnit* p = (BEQ::IUnit*)pUnit;
+			char szUnitName[256];
+			p->getName(szUnitName, 256);
+			Sleep(2000);
+
+			return 0;
+		};
+		m_pEuqipment->setEquipmentListener(listener);
+	}
+
+	return m_pEuqipment;
+}
+
+BEQ::IEquipment* CModel::getEquipment()
+{
+	return m_pEuqipment;
+}
+
+int CModel::getRecipeName(const char* pszUnitName)
+{
+	static std::string strEmpty = "";
+	auto iter = m_mapRecipe.find(pszUnitName);
+	if (iter == m_mapRecipe.end()) return 0;
+
+	return iter->second;
+}
\ No newline at end of file
diff --git a/SourceCode/Bond/GangBond2860Emulator/Model.h b/SourceCode/Bond/GangBond2860Emulator/Model.h
new file mode 100644
index 0000000..8023b8d
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/Model.h
@@ -0,0 +1,21 @@
+#pragma once
+#include <string>
+#include <map>
+
+class CModel
+{
+public:
+	CModel();
+	~CModel();
+
+public:
+	BEQ::IEquipment* createEquipment(const char* pszName);
+	BEQ::IEquipment* getEquipment();
+	int getRecipeName(const char* pszUnitName);
+
+private:
+	std::string m_strEquipmentName;
+	BEQ::IEquipment* m_pEuqipment;
+	std::map<std::string, int> m_mapRecipe;
+};
+
diff --git a/SourceCode/Bond/GangBond2860Emulator/PageEquipment.cpp b/SourceCode/Bond/GangBond2860Emulator/PageEquipment.cpp
new file mode 100644
index 0000000..99a86e4
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/PageEquipment.cpp
@@ -0,0 +1,97 @@
+// PageEquipment.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "GangBond2860Emulator.h"
+#include "PageEquipment.h"
+#include "afxdialogex.h"
+
+
+// CPageEquipment 对话框
+
+IMPLEMENT_DYNAMIC(CPageEquipment, CDialogEx)
+
+CPageEquipment::CPageEquipment(CWnd* pParent /*=NULL*/)
+	: CDialogEx(IDD_PAGE_EQUIPMENT, pParent)
+{
+
+}
+
+CPageEquipment::~CPageEquipment()
+{
+}
+
+void CPageEquipment::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CPageEquipment, CDialogEx)
+	ON_BN_CLICKED(IDC_BUTTON_RUN, &CPageEquipment::OnBnClickedButtonRun)
+END_MESSAGE_MAP()
+
+
+// CPageEquipment 消息处理程序
+
+
+BOOL CPageEquipment::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	
+	SetDlgItemText(IDC_EDIT_EQUIPMENT_NAME, _T("GangBond2860"));
+	SetDlgItemText(IDC_EDIT_VERSION, theApp.m_strVersionName);
+	SetDlgItemInt(IDC_EDIT_PORT, 8192);
+
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 异常: OCX 属性页应返回 FALSE
+}
+
+void CPageEquipment::OnBnClickedButtonRun()
+{
+	CString strEquipmentName;
+	GetDlgItemText(IDC_EDIT_EQUIPMENT_NAME, strEquipmentName);
+	if (strEquipmentName.IsEmpty()) {
+		AfxMessageBox(_T("机器名不能为空"));
+		GetDlgItem(IDC_EDIT_EQUIPMENT_NAME)->SetFocus();
+		return;
+	}
+
+	int port;
+	port = GetDlgItemInt(IDC_EDIT_PORT);
+	if (port <= 0) {
+		AfxMessageBox(_T("请输入大于0的端口号"));
+		GetDlgItem(IDC_EDIT_PORT)->SetFocus();
+		return;
+	}
+
+
+	BEQ::IEquipment* pEuqipment;
+	pEuqipment = theApp.m_model.createEquipment((LPTSTR)(LPCTSTR)strEquipmentName);
+	if (pEuqipment != nullptr) {
+		pEuqipment->setVersion((LPTSTR)(LPCTSTR)theApp.m_strVersionName);
+		BEQ::IUnit* pUnitA = pEuqipment->addUnit("UNITA", 5);
+		if (pUnitA != nullptr) {
+			pUnitA->addRecipe(1, "RECIPE1", false);
+			pUnitA->addRecipe(2, "RECIPE2", false);
+			pUnitA->addRecipe(3, "RECIPE3", true);
+		}
+		BEQ::IUnit* pUnitB = pEuqipment->addUnit("UNITB", 5);
+		if (pUnitB != nullptr) {
+			pUnitB->addRecipe(1, "RECIPE1", false);
+			pUnitB->addRecipe(2, "RECIPE2", false);
+			pUnitB->addRecipe(3, "RECIPE3", true);
+		}
+
+		pEuqipment->runOnServerMode(port);
+
+		GetDlgItem(IDC_EDIT_EQUIPMENT_NAME)->EnableWindow(FALSE);
+		GetDlgItem(IDC_EDIT_PORT)->EnableWindow(FALSE);
+		GetDlgItem(IDC_BUTTON_RUN)->EnableWindow(FALSE);
+	}
+	else {
+		AfxMessageBox("创建设备失败");
+	}
+}
diff --git a/SourceCode/Bond/GangBond2860Emulator/PageEquipment.h b/SourceCode/Bond/GangBond2860Emulator/PageEquipment.h
new file mode 100644
index 0000000..fac13cc
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/PageEquipment.h
@@ -0,0 +1,26 @@
+#pragma once
+
+
+// CPageEquipment 对话框
+
+class CPageEquipment : public CDialogEx
+{
+	DECLARE_DYNAMIC(CPageEquipment)
+
+public:
+	CPageEquipment(CWnd* pParent = NULL);   // 标准构造函数
+	virtual ~CPageEquipment();
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_PAGE_EQUIPMENT };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg void OnBnClickedButtonRun();
+};
diff --git a/SourceCode/Bond/GangBond2860Emulator/PageUnit.cpp b/SourceCode/Bond/GangBond2860Emulator/PageUnit.cpp
new file mode 100644
index 0000000..977ccd9
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/PageUnit.cpp
@@ -0,0 +1,406 @@
+// PageUnit.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "GangBond2860Emulator.h"
+#include "PageUnit.h"
+#include "afxdialogex.h"
+#include <chrono>
+
+
+// CPageUnit 对话框
+
+IMPLEMENT_DYNAMIC(CPageUnit, CDialogEx)
+
+CPageUnit::CPageUnit(CWnd* pParent /*=NULL*/)
+	: CDialogEx(IDD_PAGE_UNIT, pParent)
+{
+	m_nIdIndex = 1;
+	m_nTvTime = 0;
+	for (int i = 0; i < 12; i++) {
+		m_fTmp[i] = 10.0f + i;
+	}
+	m_fAir = 300.0;
+	for (int i = 0; i < 5; i++) {
+		m_fPre[i] = 5000.0f + i;
+	}
+	m_nDoorState = 0;
+}
+
+CPageUnit::~CPageUnit()
+{
+}
+
+void CPageUnit::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CPageUnit, CDialogEx)
+	ON_CBN_SELCHANGE(IDC_COMBO_STATE, &CPageUnit::OnCbnSelchangeComboState)
+	ON_BN_CLICKED(IDC_RADIO_CLOSE1, &CPageUnit::OnBnClickedRadioClose1)
+	ON_BN_CLICKED(IDC_RADIO_OPEN1, &CPageUnit::OnBnClickedRadioOpen1)
+	ON_CBN_SELCHANGE(IDC_COMBO_ALARM, &CPageUnit::OnCbnSelchangeComboAlarm)
+	ON_BN_CLICKED(IDC_BUTTON_REMOVE, &CPageUnit::OnBnClickedButtonRemove)
+	ON_BN_CLICKED(IDC_BUTTON_STEP_NEXT, &CPageUnit::OnBnClickedButtonStepNext)
+	ON_WM_TIMER()
+	ON_BN_CLICKED(IDC_RADIO_CLOSE2, &CPageUnit::OnBnClickedRadioClose2)
+	ON_BN_CLICKED(IDC_RADIO_OPEN2, &CPageUnit::OnBnClickedRadioOpen2)
+	ON_BN_CLICKED(IDC_RADIO_CLOSE3, &CPageUnit::OnBnClickedRadioClose3)
+	ON_BN_CLICKED(IDC_RADIO_OPEN3, &CPageUnit::OnBnClickedRadioOpen3)
+	ON_BN_CLICKED(IDC_RADIO_CLOSE4, &CPageUnit::OnBnClickedRadioClose4)
+	ON_BN_CLICKED(IDC_RADIO_OPEN4, &CPageUnit::OnBnClickedRadioOpen4)
+	ON_BN_CLICKED(IDC_RADIO_CLOSE5, &CPageUnit::OnBnClickedRadioClose5)
+	ON_BN_CLICKED(IDC_RADIO_OPEN5, &CPageUnit::OnBnClickedRadioOpen5)
+END_MESSAGE_MAP()
+
+
+// CPageUnit 消息处理程序
+
+
+void CPageUnit::setName(const char* pszName)
+{
+	m_strName = pszName;
+}
+
+BOOL CPageUnit::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+
+	// 机器状态
+	CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_STATE);
+	pComboBox->AddString("IDLE");
+	pComboBox->AddString("RUN");
+	pComboBox->AddString("DOWN");
+	pComboBox->AddString("MAINTENANCE");
+	pComboBox->AddString("MCHG");
+	pComboBox->AddString("E_TIME");
+	pComboBox->SetCurSel(0);
+
+
+	// 告警信息演示
+	pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_ALARM);
+	pComboBox->AddString("没有告警信息");
+	pComboBox->AddString("1,A急停_01");
+	pComboBox->AddString("201,上腔体压合Z轴1异常");
+	pComboBox->AddString("212,分离胶辊调节Z轴异常");
+	pComboBox->AddString("501,分离膜收膜压紧气缸异常");
+	pComboBox->SetCurSel(0);
+
+
+	// 制程
+	pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_STEP);
+	pComboBox->AddString("IDLE");
+	pComboBox->AddString("MATERIAL_RECEIVED");
+	pComboBox->AddString("PROCESSING_STARTED");
+	pComboBox->AddString("PROCESSING");
+	pComboBox->AddString("PROCESSING_COMPLETED");
+	pComboBox->AddString("MATERIAL_REMOVEED");
+	pComboBox->SetCurSel(0);
+
+
+	// 配方
+	CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST_RECIPE);
+	pListBox->AddString("1,RECIPE1");
+	pListBox->AddString("2,RECIPE2");
+	pListBox->AddString("3,RECIPE3");
+
+
+	// 门状态两个按钮
+	CButton* pRadioClose = (CButton*)GetDlgItem(IDC_RADIO_CLOSE1);
+	pRadioClose->SetCheck(BST_CHECKED);
+	pRadioClose = (CButton*)GetDlgItem(IDC_RADIO_CLOSE2);
+	pRadioClose->SetCheck(BST_CHECKED);
+	pRadioClose = (CButton*)GetDlgItem(IDC_RADIO_CLOSE3);
+	pRadioClose->SetCheck(BST_CHECKED);
+	pRadioClose = (CButton*)GetDlgItem(IDC_RADIO_CLOSE4);
+	pRadioClose->SetCheck(BST_CHECKED);
+	pRadioClose = (CButton*)GetDlgItem(IDC_RADIO_CLOSE5);
+	pRadioClose->SetCheck(BST_CHECKED);
+
+	SetTimer(2, 2000, nullptr);
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // 异常: OCX 属性页应返回 FALSE
+}
+
+
+void CPageUnit::OnCbnSelchangeComboState()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_STATE);
+	int state = pComboBox->GetCurSel();
+	pUnit->setState((BEQ::EQ_STATE)state);
+}
+
+void CPageUnit::OnBnClickedRadioClose1()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	m_nDoorState &= ~(0x1 << 0);
+	pUnit->setDoorState(m_nDoorState);
+}
+
+void CPageUnit::OnBnClickedRadioOpen1()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	m_nDoorState |= (0x1 << 0);
+	pUnit->setDoorState(m_nDoorState);
+}
+
+void CPageUnit::OnBnClickedRadioClose2()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	m_nDoorState &= ~(0x1 << 1);
+	pUnit->setDoorState(m_nDoorState);
+}
+
+
+void CPageUnit::OnBnClickedRadioOpen2()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	m_nDoorState |= (0x1 << 1);
+	pUnit->setDoorState(m_nDoorState);
+}
+
+
+void CPageUnit::OnBnClickedRadioClose3()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	m_nDoorState &= ~(0x1 << 2);
+	pUnit->setDoorState(m_nDoorState);
+}
+
+
+void CPageUnit::OnBnClickedRadioOpen3()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	m_nDoorState |= (0x1 << 2);
+	pUnit->setDoorState(m_nDoorState);
+}
+
+
+void CPageUnit::OnBnClickedRadioClose4()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	m_nDoorState &= ~(0x1 << 3);
+	pUnit->setDoorState(m_nDoorState);
+}
+
+
+void CPageUnit::OnBnClickedRadioOpen4()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	m_nDoorState |= (0x1 << 3);
+	pUnit->setDoorState(m_nDoorState);
+}
+
+
+void CPageUnit::OnBnClickedRadioClose5()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	m_nDoorState &= ~(0x1 << 4);
+	pUnit->setDoorState(m_nDoorState);
+}
+
+
+void CPageUnit::OnBnClickedRadioOpen5()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	m_nDoorState |= (0x1 << 4);
+	pUnit->setDoorState(m_nDoorState);
+}
+
+void CPageUnit::OnCbnSelchangeComboAlarm()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_ALARM);
+	int index = pComboBox->GetCurSel();
+	if (index == 0) {
+		pUnit->setAlarm(0, 0, "");
+	}
+	else if (index == 1) {
+		pUnit->setAlarm(1, 1, "急停_01");
+	}
+	else if (index == 2) {
+		pUnit->setAlarm(201, 1, "上腔体压合Z轴1异常");
+	}
+	else if (index == 3) {
+		pUnit->setAlarm(212, 1, "分离胶辊调节Z轴异常");
+	}
+	else if (index == 4) {
+		pUnit->setAlarm(501, 1, "分离膜收膜压紧气缸异常");
+	}
+}
+
+void CPageUnit::OnBnClickedButtonRemove()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_ALARM);
+	pComboBox->SetCurSel(0);
+	pUnit->setAlarm(0, 0, "");
+}
+
+void CPageUnit::OnBnClickedButtonStepNext()
+{
+	BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+	if (pEquipment == nullptr) return;
+	BEQ::IUnit* pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+	if (pUnit == nullptr) return;
+
+	CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_STEP);
+	int index = pComboBox->GetCurSel();
+	if (index == 0) {
+		m_strID.Format("%s%06d", m_strName, m_nIdIndex);
+		m_strID.Delete(0, 4);
+		m_nIdIndex++;
+		SetDlgItemText(IDC_EDIT_ID, m_strID);
+
+		pUnit->stepMaterialReceived((LPTSTR)(LPCTSTR)m_strID);
+		pComboBox->SetCurSel(1);
+	}
+	else if (index == 1) {
+		GetDlgItemText(IDC_EDIT_ID, m_strID);
+		pUnit->stepProcessingStarted((LPTSTR)(LPCTSTR)m_strID);
+		pComboBox->SetCurSel(2);
+	}
+	else if (index == 2) {
+		GetDlgItemText(IDC_EDIT_ID, m_strID);
+		pComboBox->SetCurSel(3);
+		GetDlgItem(IDC_BUTTON_STEP_NEXT)->EnableWindow(FALSE);
+		SetTimer(1, 1000, nullptr);
+	}
+	else if (index == 3) {
+		GetDlgItemText(IDC_EDIT_ID, m_strID);
+		pUnit->stepProcessingCompleted((LPTSTR)(LPCTSTR)m_strID);
+		pComboBox->SetCurSel(4);
+	}
+	else if (index == 4) {
+		GetDlgItemText(IDC_EDIT_ID, m_strID);
+		pUnit->stepMaterialRemoved((LPTSTR)(LPCTSTR)m_strID);
+		pComboBox->SetCurSel(5);
+	}
+	else if (index == 5) {
+		GetDlgItemText(IDC_EDIT_ID, m_strID);
+		pUnit->stepIdle();
+		pComboBox->SetCurSel(0);
+	}
+}
+
+void CPageUnit::OnTimer(UINT_PTR nIDEvent)
+{
+	if (1 == nIDEvent) {
+		BEQ::IUnit* pUnit = nullptr;
+		BEQ::IEquipment* pEquipment = theApp.m_model.getEquipment();
+		if (pEquipment != nullptr) {
+			pUnit = pEquipment->getUnit((LPTSTR)(LPCTSTR)m_strName);
+		}
+
+		static int index = 0;
+		index++;
+		if (index % 3 == 0) {
+			m_nTvTime++;
+			if (pUnit != nullptr) {
+				pUnit->stepProcessing((LPTSTR)(LPCTSTR)m_strID, 3, m_nTvTime);
+			}
+
+			if (m_nTvTime == 3) {
+				m_nTvTime = 0;
+				GetDlgItem(IDC_BUTTON_STEP_NEXT)->EnableWindow(TRUE);
+				KillTimer(1);
+			}
+		}
+
+
+		// 传感器数据
+		CString strTmp, strAir, strPre;
+		for (int i = 0; i < 12; i++) {
+			m_fTmp[i] += 1;
+			strTmp.AppendFormat("%.2f,", m_fTmp[i]);
+		}
+		strTmp.Delete(strTmp.GetLength() - 1);
+		SetDlgItemText(IDC_EDIT_TEMP, strTmp);
+
+		m_fAir += 1;
+		strAir.Format("%.2f", m_fAir);
+		SetDlgItemText(IDC_EDIT_AIR, strAir);
+
+		for (int i = 0; i < 5; i++) {
+			m_fPre[i] += 1;
+			strPre.AppendFormat("%.2f,", m_fPre[i]);
+		}
+		strPre.Delete(strPre.GetLength() - 1);
+		SetDlgItemText(IDC_EDIT_PRE, strPre);
+
+		if (pUnit != nullptr) {
+			auto now = std::chrono::system_clock::now();
+			auto duration_in_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
+			uint64_t timestamp = duration_in_milliseconds.count();
+			pUnit->setDataTimeAndResetData(timestamp);
+			pUnit->addData("TMP", (LPTSTR)(LPCTSTR)strTmp, false);
+			pUnit->addData("AIR", (LPTSTR)(LPCTSTR)strAir, false);
+			pUnit->addData("PRE", (LPTSTR)(LPCTSTR)strPre, true);
+		}
+	}
+	else if (2 == nIDEvent) {
+		int id = theApp.m_model.getRecipeName((LPTSTR)(LPCTSTR)m_strName);
+		CString strText;
+		strText.Format(_T("已切换到配方: %d"), id);
+		SetDlgItemText(IDC_LABEL_RUN_RECIPE, strText);
+	}
+
+	CDialogEx::OnTimer(nIDEvent);
+}
diff --git a/SourceCode/Bond/GangBond2860Emulator/PageUnit.h b/SourceCode/Bond/GangBond2860Emulator/PageUnit.h
new file mode 100644
index 0000000..3b57991
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/PageUnit.h
@@ -0,0 +1,55 @@
+#pragma once
+
+
+// CPageUnit 对话框
+
+class CPageUnit : public CDialogEx
+{
+	DECLARE_DYNAMIC(CPageUnit)
+
+public:
+	CPageUnit(CWnd* pParent = NULL);   // 标准构造函数
+	virtual ~CPageUnit();
+
+public:
+	void setName(const char* pszName);
+
+private:
+	CString m_strName;
+	CString m_strID;
+	int m_nDoorState;
+	int m_nIdIndex;
+	int m_nTvTime;
+
+private:
+	float m_fTmp[12];
+	float m_fAir;
+	float m_fPre[5];
+
+// 对话框数据
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_PAGE_UNIT };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL OnInitDialog();
+	afx_msg void OnCbnSelchangeComboState();
+	afx_msg void OnBnClickedRadioClose1();
+	afx_msg void OnBnClickedRadioOpen1();
+	afx_msg void OnCbnSelchangeComboAlarm();
+	afx_msg void OnBnClickedButtonRemove();
+	afx_msg void OnBnClickedButtonStepNext();
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+	afx_msg void OnBnClickedRadioClose2();
+	afx_msg void OnBnClickedRadioOpen2();
+	afx_msg void OnBnClickedRadioClose3();
+	afx_msg void OnBnClickedRadioOpen3();
+	afx_msg void OnBnClickedRadioClose4();
+	afx_msg void OnBnClickedRadioOpen4();
+	afx_msg void OnBnClickedRadioClose5();
+	afx_msg void OnBnClickedRadioOpen5();
+};
diff --git a/SourceCode/Bond/GangBond2860Emulator/ReadMe.txt b/SourceCode/Bond/GangBond2860Emulator/ReadMe.txt
new file mode 100644
index 0000000..0f1ad65
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/ReadMe.txt
@@ -0,0 +1,67 @@
+锘�================================================================================
+    MICROSOFT 鍩虹绫诲簱 : GangBond2860Emulator 椤圭洰姒傝堪
+===============================================================================
+
+搴旂敤绋嬪簭鍚戝宸蹭负鎮ㄥ垱寤轰簡姝� GangBond2860Emulator 搴旂敤绋嬪簭銆傛搴旂敤绋嬪簭涓嶄粎婕旂ず Microsoft 鍩虹绫荤殑鍩烘湰浣跨敤鏂规硶锛岃繕鍙綔涓烘偍缂栧啓搴旂敤绋嬪簭鐨勮捣鐐广��
+
+鏈枃浠舵瑕佷粙缁嶇粍鎴� GangBond2860Emulator 搴旂敤绋嬪簭鐨勬瘡涓枃浠剁殑鍐呭銆�
+
+GangBond2860Emulator.vcxproj
+    杩欐槸浣跨敤搴旂敤绋嬪簭鍚戝鐢熸垚鐨� VC++ 椤圭洰鐨勪富椤圭洰鏂囦欢锛屽叾涓寘鍚敓鎴愯鏂囦欢鐨� Visual C++ 鐨勭増鏈俊鎭紝浠ュ強鏈夊叧浣跨敤搴旂敤绋嬪簭鍚戝閫夋嫨鐨勫钩鍙般�侀厤缃拰椤圭洰鍔熻兘鐨勪俊鎭��
+
+GangBond2860Emulator.vcxproj.filters
+    杩欐槸浣跨敤鈥滃簲鐢ㄧ▼搴忓悜瀵尖�濈敓鎴愮殑 VC++ 椤圭洰绛涢�夊櫒鏂囦欢銆傚畠鍖呭惈鏈夊叧椤圭洰鏂囦欢涓庣瓫閫夊櫒涔嬮棿鐨勫叧鑱斾俊鎭�傚湪 IDE 涓紝閫氳繃杩欑鍏宠仈锛屽湪鐗瑰畾鑺傜偣涓嬩互鍒嗙粍褰㈠紡鏄剧ず鍏锋湁鐩镐技鎵╁睍鍚嶇殑鏂囦欢銆備緥濡傦紝鈥�.cpp鈥濇枃浠朵笌鈥滄簮鏂囦欢鈥濈瓫閫夊櫒鍏宠仈銆�
+
+GangBond2860Emulator.h
+    杩欐槸搴旂敤绋嬪簭鐨勪富澶存枃浠躲��
+    鍏朵腑鍖呮嫭鍏朵粬椤圭洰鐗瑰畾鐨勬爣澶达紙鍖呮嫭 Resource.h锛夛紝骞跺0鏄� CGangBond2860EmulatorApp 搴旂敤绋嬪簭绫汇��
+
+GangBond2860Emulator.cpp
+    杩欐槸鍖呭惈搴旂敤绋嬪簭绫� CGangBond2860EmulatorApp 鐨勪富搴旂敤绋嬪簭婧愭枃浠躲��
+
+GangBond2860Emulator.rc
+    杩欐槸绋嬪簭浣跨敤鐨勬墍鏈� Microsoft Windows 璧勬簮鐨勫垪琛ㄣ�傚畠鍖呮嫭 RES 瀛愮洰褰曚腑瀛樺偍鐨勫浘鏍囥�佷綅鍥惧拰鍏夋爣銆傛鏂囦欢鍙互鐩存帴鍦� Microsoft Visual C++ 涓繘琛岀紪杈戙�傞」鐩祫婧愬寘鍚湪 2052 涓��
+
+res\GangBond2860Emulator.ico
+    杩欐槸鐢ㄤ綔搴旂敤绋嬪簭鍥炬爣鐨勫浘鏍囨枃浠躲�傛鍥炬爣鍖呮嫭鍦ㄤ富璧勬簮鏂囦欢 GangBond2860Emulator.rc 涓��
+
+res\GangBond2860Emulator.rc2
+    姝ゆ枃浠跺寘鍚笉鍦� Microsoft Visual C++ 涓繘琛岀紪杈戠殑璧勬簮銆傛偍搴旇灏嗕笉鍙敱璧勬簮缂栬緫鍣ㄧ紪杈戠殑鎵�鏈夎祫婧愭斁鍦ㄦ鏂囦欢涓��
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+搴旂敤绋嬪簭鍚戝鍒涘缓涓�涓璇濇绫伙細
+
+GangBond2860EmulatorDlg.h銆丟angBond2860EmulatorDlg.cpp - 瀵硅瘽妗�
+    杩欎簺鏂囦欢鍖呭惈 CGangBond2860EmulatorDlg 绫汇�傛绫诲畾涔夊簲鐢ㄧ▼搴忕殑涓诲璇濇鐨勮涓恒�傚璇濇妯℃澘鍖呭惈鍦� GangBond2860Emulator.rc 涓紝璇ユ枃浠跺彲浠ュ湪 Microsoft Visual C++ 涓紪杈戙��
+
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬鍔熻兘锛�
+
+ActiveX 鎺т欢
+    璇ュ簲鐢ㄧ▼搴忓寘鍚浣跨敤 ActiveX 鎺т欢鐨勬敮鎸併��
+
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬鏍囧噯鏂囦欢:
+
+StdAfx.h, StdAfx.cpp
+    杩欎簺鏂囦欢鐢ㄤ簬鐢熸垚鍚嶄负 GangBond2860Emulator.pch 鐨勯缂栬瘧澶� (PCH) 鏂囦欢鍜屽悕涓� StdAfx.obj 鐨勯缂栬瘧绫诲瀷鏂囦欢銆�
+
+Resource.h
+    杩欐槸鏍囧噯澶存枃浠讹紝鍙敤浜庡畾涔夋柊鐨勮祫婧� ID銆侻icrosoft Visual C++ 灏嗚鍙栧苟鏇存柊姝ゆ枃浠躲��
+
+GangBond2860Emulator.manifest
+	Windows XP 浣跨敤搴旂敤绋嬪簭娓呭崟鏂囦欢鏉ユ弿杩扮壒瀹氱増鏈殑骞惰绋嬪簭闆嗙殑搴旂敤绋嬪簭渚濊禆椤广�傚姞杞界▼搴忎娇鐢ㄨ繖浜涗俊鎭潵浠庣▼搴忛泦缂撳瓨涓姞杞界浉搴旂殑绋嬪簭闆嗭紝骞朵繚鎶ゅ叾涓嶈搴旂敤绋嬪簭璁块棶銆傚簲鐢ㄧ▼搴忔竻鍗曞彲鑳戒細鍖呭惈鍦ㄥ唴锛屼互浣滀负涓庡簲鐢ㄧ▼搴忓彲鎵ц鏂囦欢瀹夎鍦ㄥ悓涓�鏂囦欢澶逛腑鐨勫閮� .manifest 鏂囦欢杩涜閲嶆柊鍒嗗彂锛屽畠杩樺彲鑳戒互璧勬簮鐨勫舰寮忓寘鍚湪鍙墽琛屾枃浠朵腑銆�
+/////////////////////////////////////////////////////////////////////////////
+
+鍏朵粬娉ㄩ噴:
+
+搴旂敤绋嬪簭鍚戝浣跨敤鈥淭ODO:鈥濇潵鎸囩ず搴旀坊鍔犳垨鑷畾涔夌殑婧愪唬鐮侀儴鍒嗐��
+
+濡傛灉搴旂敤绋嬪簭浣跨敤鍏变韩 DLL 涓殑 MFC锛屾偍灏嗛渶瑕侀噸鏂板垎鍙� MFC DLL銆傚鏋滃簲鐢ㄧ▼搴忔墍浣跨敤鐨勮瑷�涓庢搷浣滅郴缁熺殑鍖哄煙璁剧疆涓嶅悓锛屽垯杩橀渶瑕侀噸鏂板垎鍙戠浉搴旂殑鏈湴鍖栬祫婧� mfc110XXX.DLL銆�
+鏈夊叧涓婅堪璇濋鐨勬洿澶氫俊鎭紝璇峰弬瑙� MSDN 鏂囨。涓湁鍏抽噸鏂板垎鍙� Visual C++ 搴旂敤绋嬪簭鐨勯儴鍒嗐��
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/SourceCode/Bond/GangBond2860Emulator/Resource.h b/SourceCode/Bond/GangBond2860Emulator/Resource.h
new file mode 100644
index 0000000..5831ddc
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/Resource.h
Binary files differ
diff --git a/SourceCode/Bond/GangBond2860Emulator/res/GangBond2860Emulator.ico b/SourceCode/Bond/GangBond2860Emulator/res/GangBond2860Emulator.ico
new file mode 100644
index 0000000..d56fbcd
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/res/GangBond2860Emulator.ico
Binary files differ
diff --git a/SourceCode/Bond/GangBond2860Emulator/res/GangBond2860Emulator.rc2 b/SourceCode/Bond/GangBond2860Emulator/res/GangBond2860Emulator.rc2
new file mode 100644
index 0000000..1d313d1
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/res/GangBond2860Emulator.rc2
Binary files differ
diff --git a/SourceCode/Bond/GangBond2860Emulator/res/application.exe.manifest b/SourceCode/Bond/GangBond2860Emulator/res/application.exe.manifest
new file mode 100644
index 0000000..b96c40d
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/res/application.exe.manifest
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+    <assemblyIdentity
+         name="XP style manifest"
+         processorArchitecture="amd64"
+         version="1.0.0.0"
+         type="win32"/>
+    <dependency>
+        <dependentAssembly>
+            <assemblyIdentity
+                type="win32"
+                name="Microsoft.Windows.Common-Controls"
+                version="6.0.0.0"
+                processorArchitecture="amd64"
+                publicKeyToken="6595b64144ccf1df"
+                language="*"
+            />
+        </dependentAssembly>
+    </dependency>
+</assembly>
\ No newline at end of file
diff --git a/SourceCode/Bond/GangBond2860Emulator/stdafx.cpp b/SourceCode/Bond/GangBond2860Emulator/stdafx.cpp
new file mode 100644
index 0000000..6386fb7
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/stdafx.cpp
@@ -0,0 +1,8 @@
+
+// stdafx.cpp : 只包括标准包含文件的源文件
+// GangBond2860Emulator.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+
diff --git a/SourceCode/Bond/GangBond2860Emulator/stdafx.h b/SourceCode/Bond/GangBond2860Emulator/stdafx.h
new file mode 100644
index 0000000..dd7169c
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/stdafx.h
@@ -0,0 +1,54 @@
+
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+
+#pragma once
+
+#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 扩展
+
+
+#include <afxdisp.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 支持
+
+
+
+
+#include "..\BEQLibrarySDK\include\BEQLib.h"
+
+
+
+
+#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
+
+
diff --git a/SourceCode/Bond/GangBond2860Emulator/targetver.h b/SourceCode/Bond/GangBond2860Emulator/targetver.h
new file mode 100644
index 0000000..416cebf
--- /dev/null
+++ b/SourceCode/Bond/GangBond2860Emulator/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。
+
+// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
+// 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。
+
+#include <SDKDDKVer.h>
diff --git a/SourceCode/Bond/RxWindows1.0/include/IAny.h b/SourceCode/Bond/RxWindows1.0/include/IAny.h
new file mode 100644
index 0000000..d6230b1
--- /dev/null
+++ b/SourceCode/Bond/RxWindows1.0/include/IAny.h
@@ -0,0 +1,34 @@
+#pragma once
+#include <string>
+#include "IRxObject.h"
+
+class IAny
+{
+public:
+	virtual int addRef() = 0;
+	virtual int release() = 0;
+	virtual int getCode() = 0;
+	virtual void setCode(int code) = 0;
+	virtual bool getIntValue(const char* pszName, int& value) = 0;
+	virtual void setIntValue(const char* pszName, const int value) = 0;
+	virtual bool getUintValue(const char* pszName, unsigned int& value) = 0;
+	virtual void setUintValue(const char* pszName, const unsigned int value) = 0;
+	virtual bool getInt64Value(const char* pszName, __int64& value) = 0;
+	virtual void setInt64Value(const char* pszName, const __int64 value) = 0;
+	virtual bool getUint64Value(const char* pszName, unsigned __int64& value) = 0;
+	virtual void setUint64Value(const char* pszName, const unsigned __int64 value) = 0;
+	virtual bool getDoubleValue(const char* pszName, double& value) = 0;
+	virtual void setDoubleValue(const char* pszName, const double value) = 0;
+	virtual bool getFloatValue(const char* pszName, float& value) = 0;
+	virtual void setFloatValue(const char* pszName, const float value) = 0;
+	virtual bool getBoolValue(const char* pszName, bool& value) = 0;
+	virtual void setBoolValue(const char* pszName, const bool value) = 0;
+	virtual bool getPtrValue(const char* pszName, void*& value) = 0;
+	virtual void setPtrValue(const char* pszName, const void* value) = 0;
+	virtual bool getObject(const char* pszName, IRxObject*& value) = 0;
+	virtual void setObject(const char* pszName, const IRxObject* value) = 0;
+	virtual bool getStringValue(const char* pszName, const char*& pszValue) = 0;
+	virtual void setStringValue(const char* pszName, const char* pszValue) = 0;
+	virtual void allRxObjectAddRef() = 0;
+	virtual void allRxObjectRelease() = 0;
+};
\ No newline at end of file
diff --git a/SourceCode/Bond/RxWindows1.0/include/IObservable.h b/SourceCode/Bond/RxWindows1.0/include/IObservable.h
new file mode 100644
index 0000000..bd665f7
--- /dev/null
+++ b/SourceCode/Bond/RxWindows1.0/include/IObservable.h
@@ -0,0 +1,9 @@
+#pragma once
+
+class IObservable
+{
+public:
+	virtual IObservable * observeOn(DWORD dwThreadId) = 0;
+	virtual IObservable * subscribe(IObserver *pObserver) = 0;
+	virtual IObservable * unsubscribe() = 0;
+};
\ No newline at end of file
diff --git a/SourceCode/Bond/RxWindows1.0/include/IObservableEmitter.h b/SourceCode/Bond/RxWindows1.0/include/IObservableEmitter.h
new file mode 100644
index 0000000..c2576a4
--- /dev/null
+++ b/SourceCode/Bond/RxWindows1.0/include/IObservableEmitter.h
@@ -0,0 +1,8 @@
+#pragma once
+#include "IAny.h"
+
+class IObservableEmitter
+{
+public:
+	virtual void onNext(IAny *pAny) = 0;
+};
\ No newline at end of file
diff --git a/SourceCode/Bond/RxWindows1.0/include/IObserver.h b/SourceCode/Bond/RxWindows1.0/include/IObserver.h
new file mode 100644
index 0000000..76e7294
--- /dev/null
+++ b/SourceCode/Bond/RxWindows1.0/include/IObserver.h
@@ -0,0 +1,9 @@
+#pragma once
+
+class IObserver
+{
+public:
+	virtual void setPriority(int nPriority) = 0;
+	virtual void subscribe() = 0;
+	virtual void unsubscribe() = 0;
+};
diff --git a/SourceCode/Bond/RxWindows1.0/include/IRxObject.h b/SourceCode/Bond/RxWindows1.0/include/IRxObject.h
new file mode 100644
index 0000000..47bf54d
--- /dev/null
+++ b/SourceCode/Bond/RxWindows1.0/include/IRxObject.h
@@ -0,0 +1,11 @@
+#pragma once
+#include <functional>
+
+typedef std::function<void(void *)> ONRELEASECALLBACK;
+class IRxObject
+{
+public:
+	virtual int addRef() = 0;
+	virtual int release() = 0;
+};
+
diff --git a/SourceCode/Bond/RxWindows1.0/include/IRxWindows.h b/SourceCode/Bond/RxWindows1.0/include/IRxWindows.h
new file mode 100644
index 0000000..5f8839e
--- /dev/null
+++ b/SourceCode/Bond/RxWindows1.0/include/IRxWindows.h
@@ -0,0 +1,34 @@
+// RxWindows.h
+#pragma once
+#include <functional>
+#include "IRxObject.h"
+#include "IObserver.h"
+#include "IAny.h"
+#include "IThrowable.h"
+#include "IObservable.h"
+#include "IObservableEmitter.h"
+
+typedef std::function<void(IAny *pAny)> ONNEXT;
+typedef std::function<void()> ONCOMPLETE;
+typedef std::function<void(IThrowable *pThrowable)> ONERROR;
+typedef std::function<void(IObservableEmitter *e)> SUBSCRIBE;
+
+class IRxWindows
+{
+public:
+	virtual IObserver *allocObserver(ONNEXT pfOnNext, ONCOMPLETE pfOnComplete, ONERROR pfOnError) = 0;
+	virtual void freeObserver(IObserver *pObserver) = 0;
+	virtual unsigned long getMainThreadId() = 0;
+	virtual unsigned long mainThread() = 0;
+	virtual unsigned long newThread() = 0;
+	virtual int termThread(unsigned long nThread) = 0;
+	virtual void enableLog(int level) = 0;
+};
+
+
+extern "C" _declspec(dllexport) int RX_Init();
+extern "C" _declspec(dllexport) int RX_Term();
+extern "C" _declspec(dllexport) IRxWindows *RX_GetRxWindows();
+extern "C" _declspec(dllexport) IObservable *RX_AllocaObservable(SUBSCRIBE pfSubscribe);
+extern "C" _declspec(dllexport) void RX_FreeObservable(IObservable *pObservable);
+extern "C" _declspec(dllexport) IAny *RX_AllocaAny();
\ No newline at end of file
diff --git a/SourceCode/Bond/RxWindows1.0/include/IThrowable.h b/SourceCode/Bond/RxWindows1.0/include/IThrowable.h
new file mode 100644
index 0000000..0aa87a8
--- /dev/null
+++ b/SourceCode/Bond/RxWindows1.0/include/IThrowable.h
@@ -0,0 +1,9 @@
+#pragma once
+#include <string>
+
+class IThrowable
+{
+public:
+	virtual void printf() = 0;
+	virtual std::string & getMessage() = 0;
+};
diff --git a/SourceCode/Bond/RxWindows1.0/include/RxWindowsLib.h b/SourceCode/Bond/RxWindows1.0/include/RxWindowsLib.h
new file mode 100644
index 0000000..a2f9d21
--- /dev/null
+++ b/SourceCode/Bond/RxWindows1.0/include/RxWindowsLib.h
@@ -0,0 +1,22 @@
+#include "IRxWindows.h"
+#include "IObservable.h"
+#include "IObservableEmitter.h"
+
+#ifdef _COMPILE_AS_LIB
+#warning "compiling as lib!"
+#else
+#ifdef _DEBUG
+#ifndef _WIN64
+#pragma comment(lib, "..\\RxWindows1.0\\lib\\Win32\\Debug\\RxWindows.lib")
+#else 
+#pragma comment(lib, "..\\RxWindows1.0\\lib\\x64\\Debug\\RxWindows.lib")
+
+#endif
+#else 
+#ifndef _WIN64
+#pragma comment(lib, "..\\RxWindows1.0\\lib\\Win32\\Release\\RxWindows.lib")
+#else 
+#pragma comment(lib, "..\\RxWindows1.0\\lib\\x64\\Release\\RxWindows.lib")
+#endif
+#endif
+#endif // !BUILD_AS_LIB
\ No newline at end of file
diff --git a/SourceCode/Bond/x64/Debug/AlarmList.txt b/SourceCode/Bond/x64/Debug/AlarmList.txt
new file mode 100644
index 0000000..34ad3a9
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/AlarmList.txt
@@ -0,0 +1,227 @@
+1,A单元_急停_01
+2,A单元_急停_02
+3,A单元_急停_03
+4,A单元_MEO
+
+10,B单元_急停_01
+11,B单元_急停_02
+12,B单元_急停_03
+13,B单元_MEO
+
+201,A单元-上腔体压合Z轴1异常
+202,A单元-上腔体压合Z轴2异常
+203,A单元-上腔体压合Z轴3异常
+204,A单元-上腔体压合Z轴4异常
+205,A单元-上腔体压合Z轴5异常
+206,A单元-上腔体Z轴1异常
+207,A单元-上腔体Z轴2异常
+208,A单元-分离胶辊Z轴1异常
+209,A单元-分离胶辊Z轴2异常
+210,A单元-左侧分离胶辊X轴1异常
+211,A单元-左侧分离胶辊X轴2异常
+212,A单元-分离胶辊调节Z轴异常
+213,A单元-下腔体Z轴异常
+214,A单元-收膜旋转轴异常
+215,A单元-放膜旋转轴异常
+
+217,B单元-上腔体压合Z轴1异常
+218,B单元-上腔体压合Z轴2异常
+219,B单元-上腔体压合Z轴3异常
+220,B单元-上腔体压合Z轴4异常
+221,B单元-上腔体压合Z轴5异常
+222,B单元-上腔体Z轴1异常
+223,B单元-上腔体Z轴2异常
+224,B单元-分离胶辊Z轴1异常
+225,B单元-分离胶辊Z轴2异常
+226,B单元-左侧分离胶辊X轴1异常
+227,B单元-左侧分离胶辊X轴2异常
+228,B单元-分离胶辊调节Z轴异常
+229,B单元-下腔体Z轴异常
+230,B单元-收膜旋转轴异常
+231,B单元-放膜旋转轴异常
+
+260,QD77MS16(U60)异常
+261,QD77MS16(U62)异常
+
+501,A单元-分离膜收膜压紧气缸异常
+502,A单元-分离膜放膜压紧气缸异常
+503,A单元-粘膜上升气缸异常
+504,A单元-粘膜下降气缸异常
+505,A单元-高粘上压紧气缸异常
+506,A单元-高粘下压紧气缸异常
+507,A单元-干泵气阀异常
+508,A单元-腔体干泵与分子泵组合气阀异常
+509,A单元-腔体分子泵气阀异常
+510,A单元-腔体总破真空气阀异常
+
+520,B单元-分离膜收膜压紧气缸异常
+521,B单元-分离膜放膜压紧气缸异常
+522,B单元-粘膜上升气缸异常
+523,B单元-粘膜下降气缸异常
+524,B单元-高粘上压紧气缸异常
+525,B单元-高粘下压紧气缸异常
+526,B单元-干泵气阀异常
+527,B单元-腔体干泵与分子泵组合气阀异常
+528,B单元-腔体分子泵气阀异常
+529,B单元-腔体总破真空气阀异常
+
+541,A单元-上腔体破真空异常
+542,A单元-下腔体破真空异常
+543,A单元-腔体干泵破真空异常
+544,A单元-腔体分离泵破真空异常
+
+556,B单元-上腔体破真空异常
+557,B单元-下腔体破真空异常
+558,B单元-腔体干泵破真空异常
+559,B单元-腔体分离泵破真空异常
+
+571,A单元-上腔体吸真空异常
+572,A单元-下腔体吸真空异常
+573,A单元-腔体干泵吸真空异常
+574,A单元-腔体分离泵吸真空异常
+
+586,B单元-上腔体吸真空异常
+587,B单元-下腔体吸真空异常
+588,B单元-腔体干泵吸真空异常
+589,B单元-腔体分离泵吸真空异常
+
+601,A单元-下腔体在籍异常
+
+610,B单元-下腔体在籍异常
+
+621,A单元-离心膜断料
+622,A单元-离心膜转动异常
+
+626,B单元-离心膜断料
+627,B单元-离心膜转动异常
+
+631,A单元-上腔体压合Z轴1绝对位置丢失
+632,A单元-上腔体压合Z轴2绝对位置丢失
+633,A单元-上腔体压合Z轴3绝对位置丢失
+634,A单元-上腔体压合Z轴4绝对位置丢失
+635,A单元-上腔体压合Z轴5绝对位置丢失
+636,A单元-上腔体Z轴1绝对位置丢失
+637,A单元-上腔体Z轴2绝对位置丢失
+
+641,B单元-上腔体压合Z轴1绝对位置丢失
+642,B单元-上腔体压合Z轴2绝对位置丢失
+643,B单元-上腔体压合Z轴3绝对位置丢失
+644,B单元-上腔体压合Z轴4绝对位置丢失
+645,B单元-上腔体压合Z轴5绝对位置丢失
+646,B单元-上腔体Z轴1绝对位置丢失
+647,B单元-上腔体Z轴2绝对位置丢失
+
+651,A单元-安全门异常
+
+653,B单元-安全门异常
+
+656,A单元-设备正压异常
+657,A单元-离子风正压异常
+
+661,B单元-设备正压异常
+662,B单元-离子风正压异常
+
+666,A单元-上腔体压合Z轴同步异常
+667,A单元-上腔体Z轴同步异常
+668,A单元-分离胶辊Z轴同步异常
+669,A单元-分离胶辊X轴同步异常
+
+671,B单元-上腔体压合Z轴同步异常
+672,B单元-上腔体Z轴同步异常
+673,B单元-分离胶辊Z轴同步异常
+674,B单元-分离胶辊X轴同步异常
+
+676,A单元-干泵处于非远程模式
+677,A单元-干泵DVP未运行
+678,A单元-干泵MBP未运行
+679,A单元-干泵异常
+680,A单元-干泵面板急停触发
+
+683,B单元-干泵处于非远程模式
+684,B单元-干泵DVP未运行
+685,B单元-干泵MBP未运行
+686,B单元-干泵异常
+687,B单元-干泵面板急停触发
+
+690,A单元-上腔体压合Z轴1过载报警
+691,A单元-上腔体压合Z轴2过载报警
+692,A单元-上腔体压合Z轴3过载报警
+693,A单元-上腔体压合Z轴4过载报警
+694,A单元-上腔体压合Z轴5过载报警
+695,A单元-上腔体Z轴1过载报警
+696,A单元-上腔体Z轴2过载报警
+697,A单元-分离胶辊Z轴1过载报警
+698,A单元-分离胶辊Z轴2过载报警
+699,A单元-分离胶辊X轴1过载报警
+700,A单元-分离胶辊X轴2过载报警
+
+701,B单元-上腔体压合Z轴1过载报警
+702,B单元-上腔体压合Z轴2过载报警
+703,B单元-上腔体压合Z轴3过载报警
+704,B单元-上腔体压合Z轴4过载报警
+705,B单元-上腔体压合Z轴5过载报警
+706,B单元-上腔体Z轴1过载报警
+707,B单元-上腔体Z轴2过载报警
+708,B单元-分离胶辊Z轴1过载报警
+709,B单元-分离胶辊Z轴2过载报警
+710,B单元-分离胶辊X轴1过载报警
+711,B单元-分离胶辊X轴2过载报警
+
+712,A单元-上腔体压合Z轴5轴间误差过大
+713,A单元-上腔体Z轴2轴间误差过大
+714,A单元-上腔体Z轴与上腔压合Z轴误差过大
+
+717,B单元-上腔体压合Z轴5轴间误差过大
+718,B单元-上腔体Z轴2轴间误差过大
+719,B单元-上腔体Z轴与上腔压合Z轴误差过大
+
+722,A单元-分子泵处于非远程模式
+723,A单元-分子泵异常
+724,B单元-分子泵处于非远程模式
+725,B单元-分子泵异常
+726,A单元-干泵抽真空异常
+727,B单元-干泵抽真空异常
+
+729,A单元-上腔体加热主控仪表异常
+730,A单元-上腔体加热腔体温度异常
+
+732,A单元-下腔体加热主控仪表异常
+733,A单元-下腔体加热腔体温度异常
+
+739,B单元-上腔体加热主控仪表异常
+740,B单元-上腔体加热腔体温度异常
+
+742,B单元-下腔体加热主控仪表异常
+743,B单元-下腔体加热腔体温度异常
+
+801,上游连接中断
+802,下游连接中断
+
+806,上游交握超时
+807,下游交握超时
+
+811,A单元-离子风异常
+
+814,B单元-离子风异常
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SourceCode/Bond/x64/Debug/Config/BondServo.db b/SourceCode/Bond/x64/Debug/Config/BondServo.db
new file mode 100644
index 0000000..fc40e23
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Config/BondServo.db
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/Operator_Gray_32.ico b/SourceCode/Bond/x64/Debug/Res/Operator_Gray_32.ico
new file mode 100644
index 0000000..b5a51f7
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/Operator_Gray_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/Operator_High_32.ico b/SourceCode/Bond/x64/Debug/Res/Operator_High_32.ico
new file mode 100644
index 0000000..f57d0f0
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/Operator_High_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/Run_Gray_32.ico b/SourceCode/Bond/x64/Debug/Res/Run_Gray_32.ico
new file mode 100644
index 0000000..8828b45
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/Run_Gray_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/Run_High_32.ico b/SourceCode/Bond/x64/Debug/Res/Run_High_32.ico
new file mode 100644
index 0000000..9d03444
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/Run_High_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/Settings_Gray_32.ico b/SourceCode/Bond/x64/Debug/Res/Settings_Gray_32.ico
new file mode 100644
index 0000000..4b6512c
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/Settings_Gray_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/Settings_High_32.ico b/SourceCode/Bond/x64/Debug/Res/Settings_High_32.ico
new file mode 100644
index 0000000..3ce66d2
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/Settings_High_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/Stop_Gray_32.ico b/SourceCode/Bond/x64/Debug/Res/Stop_Gray_32.ico
new file mode 100644
index 0000000..f75f013
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/Stop_Gray_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/Stop_High_32.ico b/SourceCode/Bond/x64/Debug/Res/Stop_High_32.ico
new file mode 100644
index 0000000..cecc328
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/Stop_High_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/arrow_down.ico b/SourceCode/Bond/x64/Debug/Res/arrow_down.ico
new file mode 100644
index 0000000..de11f70
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/arrow_down.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/arrow_right.ico b/SourceCode/Bond/x64/Debug/Res/arrow_right.ico
new file mode 100644
index 0000000..7d10bab
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/arrow_right.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/indicator_check_24.ico b/SourceCode/Bond/x64/Debug/Res/indicator_check_24.ico
new file mode 100644
index 0000000..bf23244
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/indicator_check_24.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/indicator_check_28.ico b/SourceCode/Bond/x64/Debug/Res/indicator_check_28.ico
new file mode 100644
index 0000000..aad864e
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/indicator_check_28.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/indicator_check_32.ico b/SourceCode/Bond/x64/Debug/Res/indicator_check_32.ico
new file mode 100644
index 0000000..c89def4
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/indicator_check_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/indicator_check_32_dark.ico b/SourceCode/Bond/x64/Debug/Res/indicator_check_32_dark.ico
new file mode 100644
index 0000000..4123e0b
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/indicator_check_32_dark.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/indicator_check_32_dark2.ico b/SourceCode/Bond/x64/Debug/Res/indicator_check_32_dark2.ico
new file mode 100644
index 0000000..444c5fb
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/indicator_check_32_dark2.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/logcat_include.ico b/SourceCode/Bond/x64/Debug/Res/logcat_include.ico
new file mode 100644
index 0000000..275a472
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/logcat_include.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/remote_eq_dark_32.ico b/SourceCode/Bond/x64/Debug/Res/remote_eq_dark_32.ico
new file mode 100644
index 0000000..0e690ba
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/remote_eq_dark_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/remote_eq_light_32.ico b/SourceCode/Bond/x64/Debug/Res/remote_eq_light_32.ico
new file mode 100644
index 0000000..a017f7f
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/remote_eq_light_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/small_close0.ico b/SourceCode/Bond/x64/Debug/Res/small_close0.ico
new file mode 100644
index 0000000..84682fb
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/small_close0.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/small_close1.ico b/SourceCode/Bond/x64/Debug/Res/small_close1.ico
new file mode 100644
index 0000000..f8723ee
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/small_close1.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/small_close2.ico b/SourceCode/Bond/x64/Debug/Res/small_close2.ico
new file mode 100644
index 0000000..0debeac
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/small_close2.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/small_close3.ico b/SourceCode/Bond/x64/Debug/Res/small_close3.ico
new file mode 100644
index 0000000..ff2405e
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/small_close3.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Release/AlarmList.txt b/SourceCode/Bond/x64/Release/AlarmList.txt
new file mode 100644
index 0000000..34ad3a9
--- /dev/null
+++ b/SourceCode/Bond/x64/Release/AlarmList.txt
@@ -0,0 +1,227 @@
+1,A单元_急停_01
+2,A单元_急停_02
+3,A单元_急停_03
+4,A单元_MEO
+
+10,B单元_急停_01
+11,B单元_急停_02
+12,B单元_急停_03
+13,B单元_MEO
+
+201,A单元-上腔体压合Z轴1异常
+202,A单元-上腔体压合Z轴2异常
+203,A单元-上腔体压合Z轴3异常
+204,A单元-上腔体压合Z轴4异常
+205,A单元-上腔体压合Z轴5异常
+206,A单元-上腔体Z轴1异常
+207,A单元-上腔体Z轴2异常
+208,A单元-分离胶辊Z轴1异常
+209,A单元-分离胶辊Z轴2异常
+210,A单元-左侧分离胶辊X轴1异常
+211,A单元-左侧分离胶辊X轴2异常
+212,A单元-分离胶辊调节Z轴异常
+213,A单元-下腔体Z轴异常
+214,A单元-收膜旋转轴异常
+215,A单元-放膜旋转轴异常
+
+217,B单元-上腔体压合Z轴1异常
+218,B单元-上腔体压合Z轴2异常
+219,B单元-上腔体压合Z轴3异常
+220,B单元-上腔体压合Z轴4异常
+221,B单元-上腔体压合Z轴5异常
+222,B单元-上腔体Z轴1异常
+223,B单元-上腔体Z轴2异常
+224,B单元-分离胶辊Z轴1异常
+225,B单元-分离胶辊Z轴2异常
+226,B单元-左侧分离胶辊X轴1异常
+227,B单元-左侧分离胶辊X轴2异常
+228,B单元-分离胶辊调节Z轴异常
+229,B单元-下腔体Z轴异常
+230,B单元-收膜旋转轴异常
+231,B单元-放膜旋转轴异常
+
+260,QD77MS16(U60)异常
+261,QD77MS16(U62)异常
+
+501,A单元-分离膜收膜压紧气缸异常
+502,A单元-分离膜放膜压紧气缸异常
+503,A单元-粘膜上升气缸异常
+504,A单元-粘膜下降气缸异常
+505,A单元-高粘上压紧气缸异常
+506,A单元-高粘下压紧气缸异常
+507,A单元-干泵气阀异常
+508,A单元-腔体干泵与分子泵组合气阀异常
+509,A单元-腔体分子泵气阀异常
+510,A单元-腔体总破真空气阀异常
+
+520,B单元-分离膜收膜压紧气缸异常
+521,B单元-分离膜放膜压紧气缸异常
+522,B单元-粘膜上升气缸异常
+523,B单元-粘膜下降气缸异常
+524,B单元-高粘上压紧气缸异常
+525,B单元-高粘下压紧气缸异常
+526,B单元-干泵气阀异常
+527,B单元-腔体干泵与分子泵组合气阀异常
+528,B单元-腔体分子泵气阀异常
+529,B单元-腔体总破真空气阀异常
+
+541,A单元-上腔体破真空异常
+542,A单元-下腔体破真空异常
+543,A单元-腔体干泵破真空异常
+544,A单元-腔体分离泵破真空异常
+
+556,B单元-上腔体破真空异常
+557,B单元-下腔体破真空异常
+558,B单元-腔体干泵破真空异常
+559,B单元-腔体分离泵破真空异常
+
+571,A单元-上腔体吸真空异常
+572,A单元-下腔体吸真空异常
+573,A单元-腔体干泵吸真空异常
+574,A单元-腔体分离泵吸真空异常
+
+586,B单元-上腔体吸真空异常
+587,B单元-下腔体吸真空异常
+588,B单元-腔体干泵吸真空异常
+589,B单元-腔体分离泵吸真空异常
+
+601,A单元-下腔体在籍异常
+
+610,B单元-下腔体在籍异常
+
+621,A单元-离心膜断料
+622,A单元-离心膜转动异常
+
+626,B单元-离心膜断料
+627,B单元-离心膜转动异常
+
+631,A单元-上腔体压合Z轴1绝对位置丢失
+632,A单元-上腔体压合Z轴2绝对位置丢失
+633,A单元-上腔体压合Z轴3绝对位置丢失
+634,A单元-上腔体压合Z轴4绝对位置丢失
+635,A单元-上腔体压合Z轴5绝对位置丢失
+636,A单元-上腔体Z轴1绝对位置丢失
+637,A单元-上腔体Z轴2绝对位置丢失
+
+641,B单元-上腔体压合Z轴1绝对位置丢失
+642,B单元-上腔体压合Z轴2绝对位置丢失
+643,B单元-上腔体压合Z轴3绝对位置丢失
+644,B单元-上腔体压合Z轴4绝对位置丢失
+645,B单元-上腔体压合Z轴5绝对位置丢失
+646,B单元-上腔体Z轴1绝对位置丢失
+647,B单元-上腔体Z轴2绝对位置丢失
+
+651,A单元-安全门异常
+
+653,B单元-安全门异常
+
+656,A单元-设备正压异常
+657,A单元-离子风正压异常
+
+661,B单元-设备正压异常
+662,B单元-离子风正压异常
+
+666,A单元-上腔体压合Z轴同步异常
+667,A单元-上腔体Z轴同步异常
+668,A单元-分离胶辊Z轴同步异常
+669,A单元-分离胶辊X轴同步异常
+
+671,B单元-上腔体压合Z轴同步异常
+672,B单元-上腔体Z轴同步异常
+673,B单元-分离胶辊Z轴同步异常
+674,B单元-分离胶辊X轴同步异常
+
+676,A单元-干泵处于非远程模式
+677,A单元-干泵DVP未运行
+678,A单元-干泵MBP未运行
+679,A单元-干泵异常
+680,A单元-干泵面板急停触发
+
+683,B单元-干泵处于非远程模式
+684,B单元-干泵DVP未运行
+685,B单元-干泵MBP未运行
+686,B单元-干泵异常
+687,B单元-干泵面板急停触发
+
+690,A单元-上腔体压合Z轴1过载报警
+691,A单元-上腔体压合Z轴2过载报警
+692,A单元-上腔体压合Z轴3过载报警
+693,A单元-上腔体压合Z轴4过载报警
+694,A单元-上腔体压合Z轴5过载报警
+695,A单元-上腔体Z轴1过载报警
+696,A单元-上腔体Z轴2过载报警
+697,A单元-分离胶辊Z轴1过载报警
+698,A单元-分离胶辊Z轴2过载报警
+699,A单元-分离胶辊X轴1过载报警
+700,A单元-分离胶辊X轴2过载报警
+
+701,B单元-上腔体压合Z轴1过载报警
+702,B单元-上腔体压合Z轴2过载报警
+703,B单元-上腔体压合Z轴3过载报警
+704,B单元-上腔体压合Z轴4过载报警
+705,B单元-上腔体压合Z轴5过载报警
+706,B单元-上腔体Z轴1过载报警
+707,B单元-上腔体Z轴2过载报警
+708,B单元-分离胶辊Z轴1过载报警
+709,B单元-分离胶辊Z轴2过载报警
+710,B单元-分离胶辊X轴1过载报警
+711,B单元-分离胶辊X轴2过载报警
+
+712,A单元-上腔体压合Z轴5轴间误差过大
+713,A单元-上腔体Z轴2轴间误差过大
+714,A单元-上腔体Z轴与上腔压合Z轴误差过大
+
+717,B单元-上腔体压合Z轴5轴间误差过大
+718,B单元-上腔体Z轴2轴间误差过大
+719,B单元-上腔体Z轴与上腔压合Z轴误差过大
+
+722,A单元-分子泵处于非远程模式
+723,A单元-分子泵异常
+724,B单元-分子泵处于非远程模式
+725,B单元-分子泵异常
+726,A单元-干泵抽真空异常
+727,B单元-干泵抽真空异常
+
+729,A单元-上腔体加热主控仪表异常
+730,A单元-上腔体加热腔体温度异常
+
+732,A单元-下腔体加热主控仪表异常
+733,A单元-下腔体加热腔体温度异常
+
+739,B单元-上腔体加热主控仪表异常
+740,B单元-上腔体加热腔体温度异常
+
+742,B单元-下腔体加热主控仪表异常
+743,B单元-下腔体加热腔体温度异常
+
+801,上游连接中断
+802,下游连接中断
+
+806,上游交握超时
+807,下游交握超时
+
+811,A单元-离子风异常
+
+814,B单元-离子风异常
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SourceCode/Bond/x64/Release/Res/arrow_down.ico b/SourceCode/Bond/x64/Release/Res/arrow_down.ico
new file mode 100644
index 0000000..de11f70
--- /dev/null
+++ b/SourceCode/Bond/x64/Release/Res/arrow_down.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Release/Res/arrow_right.ico b/SourceCode/Bond/x64/Release/Res/arrow_right.ico
new file mode 100644
index 0000000..7d10bab
--- /dev/null
+++ b/SourceCode/Bond/x64/Release/Res/arrow_right.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Release/Res/small_close0.ico b/SourceCode/Bond/x64/Release/Res/small_close0.ico
new file mode 100644
index 0000000..84682fb
--- /dev/null
+++ b/SourceCode/Bond/x64/Release/Res/small_close0.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Release/Res/small_close1.ico b/SourceCode/Bond/x64/Release/Res/small_close1.ico
new file mode 100644
index 0000000..f8723ee
--- /dev/null
+++ b/SourceCode/Bond/x64/Release/Res/small_close1.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Release/Res/small_close2.ico b/SourceCode/Bond/x64/Release/Res/small_close2.ico
new file mode 100644
index 0000000..0debeac
--- /dev/null
+++ b/SourceCode/Bond/x64/Release/Res/small_close2.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Release/Res/small_close3.ico b/SourceCode/Bond/x64/Release/Res/small_close3.ico
new file mode 100644
index 0000000..ff2405e
--- /dev/null
+++ b/SourceCode/Bond/x64/Release/Res/small_close3.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Release/configuration.ini b/SourceCode/Bond/x64/Release/configuration.ini
new file mode 100644
index 0000000..1d3f0e0
--- /dev/null
+++ b/SourceCode/Bond/x64/Release/configuration.ini
@@ -0,0 +1,122 @@
+[PLC1]
+IP=192.168.100.150
+Port=9601
+
+[Equipment]
+UNITID=GANGBOND2860
+ModelType=2860
+AutoSendData=1
+
+[App]
+PanelEquipmentWidth=349
+DataDir=D:\123\GangBondData
+
+[REPORT1]
+Col_0_Width=0
+Col_1_Width=80
+Col_2_Width=180
+Col_3_Width=80
+Col_4_Width=135
+Col_5_Width=126
+Col_6_Width=348
+Col_7_Width=89
+Col_8_Width=96
+Col_9_Width=94
+Col_10_Width=165
+Col_11_Width=158
+Col_12_Width=147
+Col_13_Width=158
+Col_14_Width=140
+Col_15_Width=140
+Col_16_Width=154
+Col_17_Width=144
+Col_18_Width=180
+Col_19_Width=149
+Col_20_Width=147
+Col_21_Width=158
+Col_22_Width=151
+Col_23_Width=150
+Col_24_Width=151
+Col_25_Width=147
+Col_26_Width=147
+Col_27_Width=157
+Col_28_Width=148
+Col_29_Width=175
+Col_30_Width=165
+Col_31_Width=173
+Col_32_Width=152
+Col_33_Width=172
+Col_34_Width=153
+Col_35_Width=165
+Col_36_Width=172
+Col_37_Width=162
+Col_38_Width=163
+Col_39_Width=154
+Col_40_Width=155
+Col_41_Width=143
+Col_42_Width=98
+Col_43_Width=98
+Col_44_Width=98
+Col_45_Width=98
+Col_46_Width=98
+Col_47_Width=98
+Col_48_Width=180
+Col_49_Width=180
+Col_50_Width=180
+Col_51_Width=180
+Col_52_Width=180
+Col_53_Width=180
+Col_54_Width=180
+Col_55_Width=180
+Col_56_Width=180
+Col_57_Width=180
+Col_58_Width=180
+Col_59_Width=180
+
+[PanelDetailDlg]
+Col_0_Width=0
+Col_1_Width=166
+Col_2_Width=170
+
+[PanelDetailPage1]
+Col_0_Width=0
+Col_1_Width=182
+Col_2_Width=113
+Col_3_Width=120
+Col_4_Width=128
+Col_5_Width=121
+Col_6_Width=132
+Col_7_Width=124
+Col_8_Width=122
+Col_9_Width=127
+Col_10_Width=132
+Col_11_Width=120
+Col_12_Width=120
+Col_13_Width=120
+Col_14_Width=120
+Col_15_Width=136
+Col_16_Width=136
+Col_17_Width=136
+Col_18_Width=136
+Col_19_Width=136
+
+[HSMS]
+T3=46
+T5=11
+T6=6
+T7=11
+T8=6
+[ComponentAlarmDlg]
+Col_0_Width=0
+Col_1_Width=194
+Col_2_Width=88
+Col_3_Width=113
+Col_4_Width=139
+Col_5_Width=711
+[GraphZDlg]
+Width=1477
+Height=613
+[ComponentEQStateDlg]
+Col_0_Width=0
+Col_1_Width=222
+Col_2_Width=1137

--
Gitblit v1.9.3