From 5cf5e464a5891c8eb62aafadfce0d204fdc79b02 Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期四, 22 五月 2025 13:50:02 +0800
Subject: [PATCH] 1. 添加机械臂快速测试界面

---
 SourceCode/Bond/Servo/CPageGraph2.cpp       |   19 +
 SourceCode/Bond/Servo/Servo.vcxproj         |    2 
 SourceCode/Bond/Servo/Servo.vcxproj.filters |    2 
 SourceCode/Bond/Servo/resource.h            |    0 
 SourceCode/Bond/Servo/CRobotCmdTestDlg.cpp  |  353 ++++++++++++++++++++++++++++++++++++++++++++
 SourceCode/Bond/Servo/Servo.cpp             |    6 
 SourceCode/Bond/Servo/Servo.rc              |    0 
 SourceCode/Bond/Servo/CRobotCmdTestDlg.h    |   62 +++++++
 8 files changed, 436 insertions(+), 8 deletions(-)

diff --git a/SourceCode/Bond/Servo/CPageGraph2.cpp b/SourceCode/Bond/Servo/CPageGraph2.cpp
index cbce17f..3e161a7 100644
--- a/SourceCode/Bond/Servo/CPageGraph2.cpp
+++ b/SourceCode/Bond/Servo/CPageGraph2.cpp
@@ -13,6 +13,7 @@
 #include "CPageCassetteCtrlCmd.h"
 #include "CJobDataB.h"
 #include "CRobotCmdContainerDlg.h"
+#include "CRobotCmdTestDlg.h"
 
 
 // CPageGraph2 瀵硅瘽妗�
@@ -271,13 +272,17 @@
 				//cmds[1].subCmd = 10;
 				//pEFEM->robotCmds(cmds, 2);
 
-				CRobotCmdContainerDlg dlg;
-				if (dlg.DoModal() == IDOK) {
-					std::vector<SERVO::ROBOT_CMD_PARAM>& cmds = dlg.GetResultCmds();
-					if (!cmds.empty()) {
-						pEFEM->robotCmds(cmds.data(), (int)cmds.size());
-					}
-				}
+				//CRobotCmdContainerDlg dlg;
+				//if (dlg.DoModal() == IDOK) {
+				//	std::vector<SERVO::ROBOT_CMD_PARAM>& cmds = dlg.GetResultCmds();
+				//	if (!cmds.empty()) {
+				//		pEFEM->robotCmds(cmds.data(), (int)cmds.size());
+				//	}
+				//}
+
+				CRobotCmdTestDlg dlg;
+				dlg.SetEFEM(pEFEM);
+				dlg.DoModal();
 			}
 
 
diff --git a/SourceCode/Bond/Servo/CRobotCmdTestDlg.cpp b/SourceCode/Bond/Servo/CRobotCmdTestDlg.cpp
new file mode 100644
index 0000000..28a62e6
--- /dev/null
+++ b/SourceCode/Bond/Servo/CRobotCmdTestDlg.cpp
@@ -0,0 +1,353 @@
+锘�// CRobotCmdTestDlg.cpp: 瀹炵幇鏂囦欢
+//
+
+#include "stdafx.h"
+#include "Servo.h"
+#include "afxdialogex.h"
+#include "CRobotCmdTestDlg.h"
+
+// 鏃ュ織棰滆壊瀹忓畾涔�
+#define LOG_COLOR_NORMAL   RGB(0, 0, 0)         // 鏅�氾細榛戣壊
+#define LOG_COLOR_SUCCESS  RGB(0, 128, 0)       // 鎴愬姛锛氱豢鑹�
+#define LOG_COLOR_ERROR    RGB(255, 0, 0)       // 閿欒锛氱孩鑹�
+#define LOG_COLOR_WARNING  RGB(255, 165, 0)     // 璀﹀憡锛氭鑹�
+#define LOG_COLOR_TIME     RGB(0, 0, 255)       // 鏃堕棿鎴筹細钃濊壊
+
+// 蹇嵎鍛戒护鏄犲皠琛�
+std::map<CString, QuickCmdFieldMask> g_quickCmdMap = {
+	{_T("SendHome"),             {false, false, false, false, false}},
+	{_T("SendTransfer"),         {true,  true,  true,  true,  true }},
+	{_T("SendMoveToGet"),        {true,  true,  true,  false, false}},
+	{_T("SendMoveToPut"),        {true,  false, false, true,  true }},
+	{_T("SendGet"),              {true,  true,  true,  false, false}},
+	{_T("SendPut"),              {true,  false, false, true,  true }},
+	{_T("SendExchange"),         {true,  true,  true,  true,  true }},
+	{_T("SendCommandClear"),     {false, false, false, false, false}},
+	{_T("SendBatchGet"),         {true,  true,  true,  false, false}},
+	{_T("SendBatchPut"),         {true,  false, false, true,  true }},
+	{_T("SendMoveToGetAndHome"), {true,  true,  true,  false, false}},
+	{_T("SendMoveToPutAndHome"), {true,  false, false, true,  true }},
+	{_T("SendTransferAndHome"),  {true,  true,  true,  true,  true }},
+	{_T("SendGetAndPut"),        {true,  true,  true,  true,  true }},
+	{_T("SendPutAndHome"),       {true,  false, false, true,  true }}
+};
+
+// CRobotCmdTestDlg 瀵硅瘽妗�
+
+IMPLEMENT_DYNAMIC(CRobotCmdTestDlg, CDialogEx)
+
+CRobotCmdTestDlg::CRobotCmdTestDlg(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_DIALOG_ROBOT_CMD_TEST, pParent)
+{
+	m_pEFEM = nullptr;
+}
+
+CRobotCmdTestDlg::~CRobotCmdTestDlg()
+{
+}
+
+void CRobotCmdTestDlg::SetEFEM(SERVO::CEFEM* pEFEM)
+{
+	m_pEFEM = pEFEM;
+}
+
+void CRobotCmdTestDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_COMBO_CMD_TYPE, m_comboCmdType);
+	DDX_Control(pDX, IDC_COMBO_ARM_NO, m_comboArmNo);
+	DDX_Control(pDX, IDC_COMBO_GET_POS, m_comboGetPos);
+	DDX_Control(pDX, IDC_COMBO_GET_SLOT, m_comboGetSlot);
+	DDX_Control(pDX, IDC_COMBO_PUT_POS, m_comboPutPos);
+	DDX_Control(pDX, IDC_COMBO_PUT_SLOT, m_comboPutSlot);
+	DDX_Control(pDX, IDC_RICHEDIT_LOG, m_editLog);
+}
+
+BEGIN_MESSAGE_MAP(CRobotCmdTestDlg, CDialogEx)
+	ON_CBN_SELCHANGE(IDC_COMBO_CMD_TYPE, &CRobotCmdTestDlg::OnCbnSelchangeComboCmdType)
+	ON_BN_CLICKED(IDC_BUTTON_EXECUTE, &CRobotCmdTestDlg::OnBnClickedButtonExecute)
+END_MESSAGE_MAP()
+
+// CRobotCmdTestDlg 娑堟伅澶勭悊绋嬪簭
+
+BOOL CRobotCmdTestDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// TODO:  鍦ㄦ娣诲姞棰濆鐨勫垵濮嬪寲
+	// 鍒濆鍖栧懡浠ょ粍鍚堝垪琛�
+	for (const auto& pair : g_quickCmdMap) {
+		m_comboCmdType.AddString(pair.first);
+	}
+	m_comboCmdType.SetCurSel(0);
+
+	// 鍒濆鍖栧懡浠よ緭鍏ユ帶浠�
+	if (!g_quickCmdMap.empty()) {
+		UpdateCommandInputUI(g_quickCmdMap.begin()->first);
+	}
+
+	// 鍒濆鍖� Arm No锛�1锛欰rm#1锛�2锛欰rm#2锛�
+	m_comboArmNo.AddString(_T("1"));
+	m_comboArmNo.AddString(_T("2"));
+	m_comboArmNo.SetCurSel(0);
+
+	// 绀轰緥璁惧鍚嶇О鍒楄〃
+	CStringList eqNameList;
+	eqNameList.AddTail(_T("PORT 1"));				// 1 1 UNIT
+	eqNameList.AddTail(_T("PORT 2"));				// 2 1 UNIT
+	eqNameList.AddTail(_T("PORT 3"));				// 3 1 UNIT
+	eqNameList.AddTail(_T("PORT 4"));				// 4 1 UNIT
+	eqNameList.AddTail(_T("RB1"));					// 5 1 UNIT
+	eqNameList.AddTail(_T("RB2"));					// 6 1 UNIT
+	eqNameList.AddTail(_T("ALIGN"));				// 7 1 UNIT
+	eqNameList.AddTail(_T("FLIP"));					// 8 1 UNIT
+	eqNameList.AddTail(_T("VAC BAKE"));				// 9 2 UNIT
+	eqNameList.AddTail(_T("BONDER1"));				// 10 2 UNIT
+	eqNameList.AddTail(_T("BONDER2"));				// 11 2 UNIT
+	eqNameList.AddTail(_T("POST BAKE(COOLING)"));	// 12 4 UNIT
+	eqNameList.AddTail(_T("MEASUREMENT"));			// 13 1 UNIT
+
+	for (POSITION pos = eqNameList.GetHeadPosition(); pos != NULL;) {
+		CString item = eqNameList.GetNext(pos);
+		m_comboGetPos.AddString(item);
+		m_comboPutPos.AddString(item);
+	}
+	m_comboGetPos.SetCurSel(0);
+	m_comboPutPos.SetCurSel(0);
+
+	// 鍒濆鍖� Slot锛堥粯璁や粠 1 鍒� 25锛�
+	for (int i = 1; i < 26; ++i) {
+		CString str;
+		str.Format(_T("%d"), i);
+		m_comboGetSlot.AddString(str);
+		m_comboPutSlot.AddString(str);
+	}
+	m_comboGetSlot.SetCurSel(0);
+	m_comboPutSlot.SetCurSel(0);
+
+	// 蹇嵎鍛戒护鎵ц鏄犲皠琛�
+	m_mapCmdExec = {
+		{_T("SendHome"), [this](int seq, int, int, int, int, int) {
+			return m_pEFEM->SendHome(seq);
+		}},
+
+		{_T("SendTransfer"), [this](int seq, int armNo, int getPos, int putPos, int getSlot, int putSlot) {
+			return m_pEFEM->SendTransfer(seq, armNo, getPos, putPos, getSlot, putSlot);
+		}},
+
+		{_T("SendMoveToGet"), [this](int seq, int armNo, int pos, int, int slot, int) {
+			return m_pEFEM->SendMoveToGet(seq, armNo, pos, slot);
+		}},
+
+		{_T("SendMoveToPut"), [this](int seq, int armNo, int, int pos, int, int slot) {
+			return m_pEFEM->SendMoveToPut(seq, armNo, pos, slot);
+		}},
+
+		{_T("SendGet"), [this](int seq, int armNo, int pos, int, int slot, int) {
+			return m_pEFEM->SendGet(seq, armNo, pos, slot);
+		}},
+
+		{_T("SendPut"), [this](int seq, int armNo, int, int pos, int, int slot) {
+			return m_pEFEM->SendPut(seq, armNo, pos, slot);
+		}},
+
+		{_T("SendExchange"), [this](int seq, int armNo, int pos, int, int getSlot, int putSlot) {
+			return m_pEFEM->SendExchange(seq, armNo, pos, getSlot, putSlot);
+		}},
+
+		{_T("SendCommandClear"), [this](int seq, int, int, int, int, int) {
+			return m_pEFEM->SendCommandClear(seq);
+		}},
+
+		{_T("SendBatchGet"), [this](int seq, int armNo, int pos, int, int slot, int) {
+			return m_pEFEM->SendBatchGet(seq, pos, slot);
+		}},
+
+		{_T("SendBatchPut"), [this](int seq, int armNo, int, int pos, int, int slot) {
+			return m_pEFEM->SendBatchPut(seq, pos, slot);
+		}},
+
+		{_T("SendMoveToGetAndHome"), [this](int seq, int armNo, int pos, int, int slot, int) {
+			return m_pEFEM->SendMoveToGetAndHome(seq, armNo, pos, slot);
+		}},
+
+		{_T("SendMoveToPutAndHome"), [this](int seq, int armNo, int, int pos, int, int slot) {
+			return m_pEFEM->SendMoveToPutAndHome(seq, armNo, pos, slot);
+		}},
+
+		{_T("SendTransferAndHome"), [this](int seq, int armNo, int getPos, int putPos, int getSlot, int putSlot) {
+			return m_pEFEM->SendTransferAndHome(seq, armNo, getPos, putPos, getSlot, putSlot);
+		}},
+
+		{_T("SendGetAndPut"), [this](int seq, int armNo, int getPos, int putPos, int getSlot, int putSlot) {
+			return m_pEFEM->SendGetAndPut(seq, armNo, getPos, putPos, getSlot, putSlot);
+		}},
+
+		{_T("SendPutAndHome"), [this](int seq, int armNo, int, int pos, int, int slot) {
+			return m_pEFEM->SendPutAndHome(seq, armNo, pos, slot);
+		}}
+	};
+
+	// 鍒濆鍖栨棩蹇楁
+	AppendLogLineRichStyled(_T("鍑嗗灏辩华..."), LOG_COLOR_SUCCESS);
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+	// 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
+}
+
+void CRobotCmdTestDlg::UpdateCommandInputUI(const CString& cmdName)
+{
+	auto it = g_quickCmdMap.find(cmdName);
+	if (it == g_quickCmdMap.end()) { 
+		return;
+	}
+
+	const QuickCmdFieldMask& mask = it->second;
+	GetDlgItem(IDC_COMBO_ARM_NO)->EnableWindow(mask.useArm);
+	GetDlgItem(IDC_COMBO_GET_POS)->EnableWindow(mask.useGetPos);
+	GetDlgItem(IDC_COMBO_GET_SLOT)->EnableWindow(mask.useGetSlot);
+	GetDlgItem(IDC_COMBO_PUT_POS)->EnableWindow(mask.usePutPos);
+	GetDlgItem(IDC_COMBO_PUT_SLOT)->EnableWindow(mask.usePutSlot);
+}
+
+void CRobotCmdTestDlg::AppendLogLineBatchBegin()
+{
+	m_editLog.SetRedraw(FALSE);
+	m_editLog.SetEventMask(0); // 闃叉瑙﹀彂涓嶅繀瑕佺殑閫氱煡
+}
+
+void CRobotCmdTestDlg::AppendLogLineBatchEnd()
+{
+	m_editLog.SetRedraw(TRUE);
+	m_editLog.Invalidate();  // 寮哄埗閲嶇粯
+	m_editLog.SetEventMask(ENM_CHANGE | ENM_SELCHANGE);
+}
+
+void CRobotCmdTestDlg::TrimRichEditLineLimit(int maxLines)
+{
+	int lineCount = m_editLog.GetLineCount();
+	if (lineCount <= maxLines) {
+		return;
+	}
+
+	// 鑾峰彇澶氫綑琛岀殑瀛楃鏁拌寖鍥�
+	int charIndex = m_editLog.LineIndex(maxLines);
+	m_editLog.SetSel(0, charIndex); // 閫変腑澶氫綑鍐呭
+	m_editLog.ReplaceSel(_T(""));   // 鍒犻櫎
+}
+
+void CRobotCmdTestDlg::AppendLogLineRichStyled(const CString& content, COLORREF color /*= RGB(0, 0, 0)*/)
+{
+	// 鏃堕棿鎴�
+	CString timestamp;
+	CTime now = CTime::GetCurrentTime();
+	timestamp.Format(_T("[%02d:%02d:%02d] "), now.GetHour(), now.GetMinute(), now.GetSecond());
+
+	// 鎻掑叆鐐圭Щ鍒版渶鍚庯紙涔熷彲浠ヨ涓� 0 琛ㄧず椤堕儴锛�
+	m_editLog.SetSel(-1, -1);
+
+	// 鎻掑叆鏃堕棿锛堣摑鑹诧級
+	CHARFORMAT2 cfTime = {};
+	cfTime.cbSize = sizeof(cfTime);
+	cfTime.dwMask = CFM_COLOR;
+	cfTime.crTextColor = LOG_COLOR_TIME;
+	m_editLog.SetSelectionCharFormat(cfTime);
+	m_editLog.ReplaceSel(timestamp);
+
+	// 鎻掑叆鏃ュ織姝f枃锛堜紶鍏ラ鑹诧級
+	CHARFORMAT2 cfMsg = {};
+	cfMsg.cbSize = sizeof(cfMsg);
+	cfMsg.dwMask = CFM_COLOR;
+	cfMsg.crTextColor = color;
+	m_editLog.SetSelectionCharFormat(cfMsg);
+	m_editLog.ReplaceSel(content + _T("\r\n"));
+
+	// 闄愬埗鏈�澶ц鏁�
+	TrimRichEditLineLimit(100);
+}
+
+void CRobotCmdTestDlg::HighlightAllMatches(const CString& strSearch, COLORREF clrHighlight)
+{
+	if (strSearch.IsEmpty()) {
+		return;
+	}
+
+	long nStart = 0;
+	long nEnd = m_editLog.GetTextLength();
+	CHARRANGE cr;
+	FINDTEXTEX ft = { 0 };
+	ft.chrg.cpMin = 0;
+	ft.chrg.cpMax = nEnd;
+	ft.lpstrText = strSearch.GetString();
+
+	// 楂樹寒鍓嶄笉娓呴櫎鍏ㄦ枃棰滆壊锛岄伩鍏嶅巻鍙插鑹叉贩娣�
+	while (m_editLog.FindText(FR_DOWN, &ft) != -1) {
+		m_editLog.SetSel(ft.chrgText.cpMin, ft.chrgText.cpMax);
+
+		CHARFORMAT2 cf = {};
+		cf.cbSize = sizeof(cf);
+		cf.dwMask = CFM_COLOR;
+		cf.crTextColor = clrHighlight;
+		m_editLog.SetSelectionCharFormat(cf);
+
+		// 涓嬫鎼滅储浠庡悗闈㈠紑濮�
+		ft.chrg.cpMin = ft.chrgText.cpMax;
+	}
+	m_editLog.SetSel(-1, 0);
+}
+
+void CRobotCmdTestDlg::OnCbnSelchangeComboCmdType()
+{
+	int nSel = m_comboCmdType.GetCurSel();
+	if (nSel < 0) {
+		return;
+	}
+
+	CString str;
+	m_comboCmdType.GetLBText(nSel, str);
+	UpdateCommandInputUI(str);
+
+	str.Format(_T("鍒囨崲褰撳墠鍛戒护绫诲瀷锛�%s"), str);
+	AppendLogLineRichStyled(str, LOG_COLOR_NORMAL);
+}
+
+void CRobotCmdTestDlg::OnBnClickedButtonExecute()
+{
+	// TODO: 鍦ㄦ娣诲姞鎺т欢閫氱煡澶勭悊绋嬪簭浠g爜
+	int sel = m_comboCmdType.GetCurSel();
+	if (sel == CB_ERR) {
+		AppendLogLineRichStyled(_T("鏈�夋嫨鍛戒护绫诲瀷"), LOG_COLOR_ERROR);
+		return;
+	}
+
+	CString cmdName;
+	m_comboCmdType.GetLBText(sel, cmdName);
+
+	// 鍙傛暟鏀堕泦
+	int armNo = m_comboArmNo.GetCurSel() + 1;
+	int getPos = m_comboGetPos.GetCurSel() + 1;
+	int getSlot = m_comboGetSlot.GetCurSel() + 1;
+	int putPos = m_comboPutPos.GetCurSel() + 1;
+	int putSlot = m_comboPutSlot.GetCurSel() + 1;
+
+	// 鏌ユ壘鍑芥暟骞舵墽琛�
+	auto it = m_mapCmdExec.find(cmdName);
+	if (it != m_mapCmdExec.end() && nullptr != m_pEFEM) {
+		int ret = it->second(1, armNo, getPos, getSlot, putPos, putSlot);
+
+		CString log;
+		if (ret == 0) {
+			log.Format(_T("鎵ц鍛戒护 %s 鎴愬姛"), cmdName.GetString());
+			AppendLogLineRichStyled(log, LOG_COLOR_SUCCESS);
+		}
+		else {
+			log.Format(_T("鎵ц鍛戒护 %s 鍙傛暟閿欒"), cmdName.GetString());
+			AppendLogLineRichStyled(log, LOG_COLOR_ERROR);
+		}
+	}
+	else {
+		CString log;
+		log.Format(_T("鍛戒护 %s 涓嶅瓨鍦ㄦ垨 EFEM 鏈垵濮嬪寲"), cmdName.GetString());
+		AppendLogLineRichStyled(log, LOG_COLOR_ERROR);
+	}
+}
diff --git a/SourceCode/Bond/Servo/CRobotCmdTestDlg.h b/SourceCode/Bond/Servo/CRobotCmdTestDlg.h
new file mode 100644
index 0000000..065ee0a
--- /dev/null
+++ b/SourceCode/Bond/Servo/CRobotCmdTestDlg.h
@@ -0,0 +1,62 @@
+锘�#pragma once
+#include "afxdialogex.h"
+#include <afxrich.h>
+
+// 瀹氫箟鍛戒护鍑芥暟鎸囬拡绫诲瀷锛坰eq, armNo, getPos, getSlot, putPos, putSlot锛�
+using CmdFunc = std::function<int(int, int, int, int, int, int)>;
+
+// 杈撳叆鎺т欢鐘舵��
+struct QuickCmdFieldMask {
+	bool useArm = false;
+	bool useGetPos = false;
+	bool useGetSlot = false;
+	bool usePutPos = false;
+	bool usePutSlot = false;
+};
+
+// CRobotCmdTestDlg 瀵硅瘽妗�
+
+class CRobotCmdTestDlg : public CDialogEx
+{
+	DECLARE_DYNAMIC(CRobotCmdTestDlg)
+
+public:
+	CRobotCmdTestDlg(CWnd* pParent = nullptr);   // 鏍囧噯鏋勯�犲嚱鏁�
+	virtual ~CRobotCmdTestDlg();
+
+	// 璁剧疆 EFEM 鎸囬拡
+	void SetEFEM(SERVO::CEFEM* pEFEM);
+
+// 瀵硅瘽妗嗘暟鎹�
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_DIALOG_ROBOT_CMD_TEST };
+#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 鏀寔
+	virtual BOOL OnInitDialog();
+	afx_msg void OnCbnSelchangeComboCmdType();
+	afx_msg void OnBnClickedButtonExecute();
+	DECLARE_MESSAGE_MAP()
+
+private:
+	void UpdateCommandInputUI(const CString& cmdName);
+	void AppendLogLineBatchBegin();
+	void AppendLogLineBatchEnd();
+	void TrimRichEditLineLimit(int maxLines = 100);
+	void AppendLogLineRichStyled(const CString& content, COLORREF color = RGB(0, 0, 0));
+	void HighlightAllMatches(const CString& strSearch, COLORREF clrHighlight = RGB(255, 165, 0));
+
+	// 鎺т欢
+	CComboBox m_comboCmdType;
+	CComboBox m_comboArmNo;
+	CComboBox m_comboGetPos;
+	CComboBox m_comboGetSlot;
+	CComboBox m_comboPutPos;
+	CComboBox m_comboPutSlot;
+	CRichEditCtrl m_editLog;
+
+	// 蹇嵎鍛戒护鏄犲皠琛�
+	SERVO::CEFEM* m_pEFEM;
+	std::map<CString, CmdFunc> m_mapCmdExec;
+};
diff --git a/SourceCode/Bond/Servo/Servo.cpp b/SourceCode/Bond/Servo/Servo.cpp
index e6eb33a..3b5e1c5 100644
--- a/SourceCode/Bond/Servo/Servo.cpp
+++ b/SourceCode/Bond/Servo/Servo.cpp
@@ -52,7 +52,7 @@
 
 BOOL CServoApp::InitInstance()
 {
-	// 如果一个运行在 Windows XP 上的应用程序清单指定要
+	// TODO: 调用 AfxInitRichEdit2() 以初始化 richedit2 库。\n"	// 如果一个运行在 Windows XP 上的应用程序清单指定要
 	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
 	//则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
 	INITCOMMONCONTROLSEX InitCtrls;
@@ -113,6 +113,10 @@
 	InitGDIPlus();
 
 
+	// 初始化 MFC RichEdit 控件
+	AfxInitRichEdit2();
+
+
 	// 初始化报警管理器
 	try {
 		if (!AlarmManager::getInstance().initAlarmTable()) {
diff --git a/SourceCode/Bond/Servo/Servo.rc b/SourceCode/Bond/Servo/Servo.rc
index af6260c..b5e2fdf 100644
--- a/SourceCode/Bond/Servo/Servo.rc
+++ b/SourceCode/Bond/Servo/Servo.rc
Binary files differ
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj b/SourceCode/Bond/Servo/Servo.vcxproj
index 18abe4c..d39cf16 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj
+++ b/SourceCode/Bond/Servo/Servo.vcxproj
@@ -201,6 +201,7 @@
     <ClInclude Include="CEquipmentPage3.h" />
     <ClInclude Include="CGlassPool.h" />
     <ClInclude Include="CRobotCmdContainerDlg.h" />
+    <ClInclude Include="CRobotCmdTestDlg.h" />
     <ClInclude Include="PageRecipe.h" />
     <ClInclude Include="CDoubleGlass.h" />
     <ClInclude Include="CProcessData.h" />
@@ -302,6 +303,7 @@
     <ClCompile Include="CEquipmentPage3.cpp" />
     <ClCompile Include="CGlassPool.cpp" />
     <ClCompile Include="CRobotCmdContainerDlg.cpp" />
+    <ClCompile Include="CRobotCmdTestDlg.cpp" />
     <ClCompile Include="PageRecipe.cpp" />
     <ClCompile Include="CDoubleGlass.cpp" />
     <ClCompile Include="CProcessData.cpp" />
diff --git a/SourceCode/Bond/Servo/Servo.vcxproj.filters b/SourceCode/Bond/Servo/Servo.vcxproj.filters
index f79e425..76d5897 100644
--- a/SourceCode/Bond/Servo/Servo.vcxproj.filters
+++ b/SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -107,6 +107,7 @@
     <ClCompile Include="CEquipmentPage3.cpp" />
     <ClCompile Include="PageRobotCmd.cpp" />
     <ClCompile Include="CRobotCmdContainerDlg.cpp" />
+    <ClCompile Include="CRobotCmdTestDlg.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="AlarmManager.h" />
@@ -212,6 +213,7 @@
     <ClInclude Include="CEquipmentPage3.h" />
     <ClInclude Include="PageRobotCmd.h" />
     <ClInclude Include="CRobotCmdContainerDlg.h" />
+    <ClInclude Include="CRobotCmdTestDlg.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Servo.rc" />
diff --git a/SourceCode/Bond/Servo/resource.h b/SourceCode/Bond/Servo/resource.h
index 9b64524..1aa8644 100644
--- a/SourceCode/Bond/Servo/resource.h
+++ b/SourceCode/Bond/Servo/resource.h
Binary files differ

--
Gitblit v1.9.3