Преглед изворни кода

称重的优化,也改造完了

张洋 пре 4 година
родитељ
комит
cc03a66525

+ 1 - 2
bin/Win32/Debug/zhipuzi_pos_windows/skin/chengzhong_wnd.xml

@@ -17,8 +17,7 @@
 				<HorizontalLayout height="50" padding="0,30,0,0">
 					<Edit name="content" width="250" height="50" padding="30,0,0,0" textcolor="0xFF3CB371" bkcolor="#FFF2F2F2" nativebkcolor="#FFF2F2F2" font="1"/>
 					<Label name="name" text="公斤" height="50" width="50" padding="30,0,0,0" align="left"/>
-				</HorizontalLayout>
-				
+				</HorizontalLayout>				
 				
 				<Label name="errinfo" text=""  height="60" width="250" float="true" pos="30,150,280,290" align="left" textcolor="#FFFF0000" visible="false"/>
 				

+ 4 - 4
zhipuzi_pos_windows/helper/CSerialPort.cpp

@@ -78,7 +78,7 @@ bool CSerialPort::openComm()
         {
             TCHAR szBuf[1024] = { 0 };
             wsprintf(szBuf, L"串口设置失败,错误代码: %d", GetLastError());
-            MessageBox(NULL, szBuf, TEXT("ERROR"), MB_OK);
+            //MessageBox(NULL, szBuf, TEXT("ERROR"), MB_OK);
             return false;
         }
 
@@ -90,7 +90,7 @@ bool CSerialPort::openComm()
 	{
 		TCHAR szBuf[1024] = { 0 };
 		wsprintf(szBuf, _T("清空缓冲区失败,错误代码: %d"), GetLastError());
-		MessageBox(NULL, szBuf, L"ERROR", MB_OK);
+		//MessageBox(NULL, szBuf, L"ERROR", MB_OK);
 	}
 
     m_bOpen = true;
@@ -133,7 +133,7 @@ bool CSerialPort::writeToComm(BYTE data[], DWORD dwLength)
     {
         TCHAR szBuf[1024] = { 0 };
         wsprintf(szBuf, _T("读取数据失败,错误代码: %d"), GetLastError());
-        MessageBox(NULL, szBuf, L"ERROR", MB_OK);
+        //MessageBox(NULL, szBuf, L"ERROR", MB_OK);
 
         return false;
     }
@@ -173,7 +173,7 @@ bool CSerialPort::readFromComm(char buffer[], DWORD dwLength, DWORD* nReaded)
     {
 		TCHAR szBuf[1024] = { 0 };
 		wsprintf(szBuf, _T("读取数据失败,错误代码: %d"), GetLastError());
-		MessageBox(NULL, szBuf, L"ERROR", MB_OK);
+		//MessageBox(NULL, szBuf, L"ERROR", MB_OK);
 
         return false;
     }

+ 1 - 0
zhipuzi_pos_windows/helper/define.h

@@ -29,4 +29,5 @@
 
 //称重相关消息
 #define WM_CHENGZHONG_SUCCESS 10301
+#define WM_CHENGZHONG_FAIL 10302
 

+ 7 - 0
zhipuzi_pos_windows/page/CSettingPageUI.cpp

@@ -5,6 +5,7 @@
 
 #include "../print/CPosPrinter.h"
 #include "../helper/CComHelper.h"
+#include "../tool/CChengzhongWorker.h"
 
 CSettingPageUI::CSettingPageUI()
 {
@@ -1456,6 +1457,8 @@ void CSettingPageUI::HandleItemSelectMsg(TNotifyUI& msg)
 		{
 			CSetting::SetParam("setting_dianzicheng_xinghao", "dahua_acs");
 		}
+
+		CChengzhongWorker::GetInstance()->RestartWork();
 	}
 	else if (name == _T("setting_dianzicheng_chuankou"))
 	{
@@ -1463,6 +1466,8 @@ void CSettingPageUI::HandleItemSelectMsg(TNotifyUI& msg)
 		wstring com_device = com->GetText();
 
 		CSetting::SetParam("setting_dianzicheng_com", CLewaimaiString::UnicodeToUTF8(com_device));
+
+		CChengzhongWorker::GetInstance()->RestartWork();
 	}
 	else if (name == _T("setting_dianzicheng_botelv"))
 	{
@@ -1470,6 +1475,8 @@ void CSettingPageUI::HandleItemSelectMsg(TNotifyUI& msg)
 		wstring com_device = com->GetText();
 
 		CSetting::SetParam("setting_dianzicheng_botelv", CLewaimaiString::UnicodeToUTF8(com_device));
+
+		CChengzhongWorker::GetInstance()->RestartWork();
 	}
 	else if (name == _T("setting_biaoqian_printer_usb"))
 	{

+ 154 - 0
zhipuzi_pos_windows/tool/CChengzhongWorker.cpp

@@ -0,0 +1,154 @@
+#include "../pch/pch.h"
+#include "CChengzhongWorker.h"
+
+CChengzhongWorker::CChengzhongWorker()
+{
+}
+
+//启动工作线程
+void CChengzhongWorker::StartWork()
+{
+	m_is_work = true;
+
+	std::thread(&CChengzhongWorker::HandleWork, this).detach();
+}
+
+//结束工作线程
+void CChengzhongWorker::StopWork()
+{
+	m_worker_mutex.lock();
+
+	m_is_work = false;
+
+	m_worker_mutex.unlock();
+
+	m_serial.closeComm();
+
+	m_weight = "";
+	m_hwnd = NULL;
+}
+
+void CChengzhongWorker::RestartWork()
+{
+	StopWork();
+
+	StartWork();
+}
+
+void CChengzhongWorker::HandleWork()
+{
+	std::string setting_dianzicheng_xinghao = CSetting::GetParam("setting_dianzicheng_xinghao");
+	std::string dianzicheng_com = CSetting::GetParam("setting_dianzicheng_com");
+	std::string setting_dianzicheng_botelv = CSetting::GetParam("setting_dianzicheng_botelv");
+
+	m_serial.setPortNum(CLewaimaiString::UTF8ToUnicode(dianzicheng_com));
+	m_serial.setBaudRate(atoi(setting_dianzicheng_botelv.c_str()));
+
+	bool ret = m_serial.openComm();
+	if (!ret)
+	{
+		//连接电子秤失败了
+		m_is_work = false;
+
+		return;
+	}
+
+	std::string m_chuankou_string = "";
+
+	char a[100] = { 0 };
+
+	//检查监控模式和波特率,如果变了就关闭掉
+	while (m_is_work)
+	{
+		memset(a, 0, 100);
+
+		//开始读取串口的数据
+		DWORD nReaded = 0;
+
+		m_serial.readFromComm(a, 100, &nReaded);
+
+		if (nReaded > 0)
+		{
+			//不同型号的电子秤,数据格式可能不一样,处理方式不一样
+
+			if (setting_dianzicheng_xinghao == "dahua_acs")
+			{
+				//把所有读到的内容,拼接到m_chuankou_string后面,避免有的数据中间截断导致格式混乱
+				m_chuankou_string += a;
+
+				std::string show_command = "\n\r";
+
+				size_t nPos = m_chuankou_string.find(show_command);
+				if (nPos == m_chuankou_string.npos)
+				{
+					//没有读到足够的长度,继续读
+					continue;
+				}
+
+				std::string weight;
+
+				//如果前2个不是标志符,那么就判断标志符后面的数字长度够不够5个
+				if (m_chuankou_string.length() >= nPos + 7)
+				{
+					//这个情况是,标志符后面有5个数字
+					weight = m_chuankou_string.substr(nPos + 2, 5);
+
+					//然后把前面的字符都删掉
+					m_chuankou_string = m_chuankou_string.substr(nPos + 7);
+				}
+				else if (nPos >= 20)
+				{
+					//说明前面有20个字符,首先肯定不是稳定模式而是极速模式,另外在极速模式下可以直接得到重量了
+					weight = m_chuankou_string.substr(nPos - 20, 5);
+
+					m_chuankou_string = m_chuankou_string.substr(nPos + 2);
+				}
+				else
+				{
+					//标志符后面前面都不够读取重量,继续读取串口
+					continue;
+				}
+
+				if (weight.at(0) == ' ')
+				{
+					weight = weight.substr(1);
+				}
+
+				std::string zhengshu;
+				std::string xiaoshu;
+				if (weight.length() == 4)
+				{
+					//重量小于10公斤,第一个数字为空
+					zhengshu = weight.substr(0, 1);
+					xiaoshu = weight.substr(1, 3);
+				}
+				else if (weight.length() == 5)
+				{
+					//重量大于10公斤,第一个数字为空
+					zhengshu = weight.substr(0, 2);
+					xiaoshu = weight.substr(2, 3);
+				}
+				else
+				{
+					continue;
+				}
+
+				m_weight = zhengshu + "." + xiaoshu;
+
+				if (m_hwnd != NULL)
+				{
+					::SendMessage(m_hwnd, WM_CHENGZHONG_SUCCESS, 0, 0);
+				}
+			}
+			else
+			{
+				//暂时不支持的其他型号
+				Sleep(100);
+			}
+		}
+		else
+		{
+			Sleep(100);
+		}
+	}
+}

+ 57 - 0
zhipuzi_pos_windows/tool/CChengzhongWorker.h

@@ -0,0 +1,57 @@
+#pragma once
+
+#include "../pch/pch.h"
+
+#include "../helper/CSerialPort.h"
+
+class CChengzhongWorker
+{
+public:
+	static CChengzhongWorker* GetInstance()
+	{
+		static CChengzhongWorker instance;
+
+		return &instance;
+	}
+
+	void SetHWND(HWND hwnd)
+	{
+		m_hwnd = hwnd;
+	}
+
+	//启动工作线程
+	void StartWork();
+
+	//结束工作线程
+	void StopWork();
+
+	//重启工作
+	void RestartWork();
+
+	void HandleWork();
+
+	std::string GetWeight()
+	{
+		return m_weight;
+	}
+
+	bool GetIsWork()
+	{
+		return m_is_work;
+	}
+
+private:
+	CChengzhongWorker();
+
+private:
+	bool m_is_work;
+
+	std::mutex m_worker_mutex;
+
+	//当前得到的重量
+	std::string m_weight;
+
+	HWND m_hwnd = NULL;
+
+	CSerialPort m_serial;
+};

+ 24 - 157
zhipuzi_pos_windows/wnd/CChengzhongWnd.cpp

@@ -1,6 +1,8 @@
 #include "../pch/pch.h"
 #include "CChengzhongWnd.h"
 
+#include "../tool/CChengzhongWorker.h"
+
 LRESULT CChengzhongWnd::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
 {
 	POINT pt;
@@ -310,14 +312,7 @@ void CChengzhongWnd::Notify(TNotifyUI& msg)
 
 LRESULT CChengzhongWnd::OnChengzhongSuccess(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
 {
-	CEditUI* pContent = static_cast<CEditUI*>(m_pm.FindControl(_T("content")));
-	pContent->SetText(CLewaimaiString::UTF8ToUnicode(m_weight).c_str());
-
-	wstring ws_Value = pContent->GetText();
-	string strValue = CLewaimaiString::UnicodeToUTF8(ws_Value);
-
-	pContent->SetSel(strValue.length(), strValue.length());//重设给光标设置位置
-	pContent->SetFocus();
+	UpdateWeightFromWorker();
 
 	bHandled = TRUE;
 	return 0;
@@ -326,7 +321,18 @@ LRESULT CChengzhongWnd::OnChengzhongSuccess(UINT uMsg, WPARAM wParam, LPARAM lPa
 void CChengzhongWnd::Init()
 {
 	//启动一个线程,开始串口监听
-	std::thread(&CChengzhongWnd::ReadChuankouValue, this).detach();
+	CChengzhongWorker::GetInstance()->SetHWND(this->m_hWnd);
+
+	if (CChengzhongWorker::GetInstance()->GetIsWork() == false)
+	{
+		//电子秤连接串口失败了
+		CLabelUI* pErrorInfo = static_cast<CLabelUI*>(m_pm.FindControl(_T("errinfo")));
+		pErrorInfo->SetText(L"连接电子秤失败,请检查电子秤设置");
+		pErrorInfo->SetVisible(true);
+	}
+
+	//先设置一次已经存取的最新weight
+	UpdateWeightFromWorker();
 }
 
 std::string CChengzhongWnd::getContent()
@@ -350,138 +356,27 @@ void CChengzhongWnd::SetPrice(std::string price)
 	pLabel->SetText((L"单价:" + ws_price + L"元/公斤").c_str());
 }
 
-void CChengzhongWnd::ReadChuankouValue()
+void CChengzhongWnd::UpdateWeightFromWorker()
 {
-	std::string setting_dianzicheng_xinghao = CSetting::GetParam("setting_dianzicheng_xinghao");
-	std::string dianzicheng_com = CSetting::GetParam("setting_dianzicheng_com");
-	std::string setting_dianzicheng_botelv = CSetting::GetParam("setting_dianzicheng_botelv");
-
-	m_serial.setPortNum(CLewaimaiString::UTF8ToUnicode(dianzicheng_com));
-	m_serial.setBaudRate(atoi(setting_dianzicheng_botelv.c_str()));
+	m_weight = CChengzhongWorker::GetInstance()->GetWeight();
 
-	bool ret = m_serial.openComm();
-	if (!ret)
+	if (m_weight.length() == 0)
 	{
-		//这里不设置后面没法退出了
-		m_is_watching = true;
-
-		CLabelUI* pErrorInfo = static_cast<CLabelUI*>(m_pm.FindControl(_T("errinfo")));
-		pErrorInfo->SetText(L"电子秤连接失败,请检查电子秤连接设置");
-		pErrorInfo->SetVisible(true);
-
 		return;
 	}
 
-	m_is_chuangkou_working = true;
-	m_is_watching = true;
-
-	m_chuankou_string = "";
-
-	char a[100] = { 0 };
-
-	//检查监控模式和波特率,如果变了就关闭掉
-	while (m_is_watching)
-	{
-		memset(a, 0, 100);
-
-		//开始读取串口的数据
-		DWORD nReaded = 0;
-
-		m_serial.readFromComm(a, 100, &nReaded);
-
-		if (nReaded > 0)
-		{
-			//不同型号的电子秤,数据格式可能不一样,处理方式不一样
-			
-			if (setting_dianzicheng_xinghao == "dahua_acs")
-			{
-				//把所有读到的内容,拼接到m_chuankou_string后面,避免有的数据中间截断导致格式混乱
-				m_chuankou_string += a;
-
-				std::string show_command = "\n\r";
-
-				size_t nPos = m_chuankou_string.find(show_command);
-				if (nPos == m_chuankou_string.npos)
-				{
-					//没有读到足够的长度,继续读
-					continue;
-				}
-
-				std::string weight;
-
-				//如果前2个不是标志符,那么就判断标志符后面的数字长度够不够5个
-				if (m_chuankou_string.length() >= nPos + 7)
-				{
-					//这个情况是,标志符后面有5个数字
-					weight = m_chuankou_string.substr(nPos + 2, 5);
-
-					//然后把前面的字符都删掉
-					m_chuankou_string = m_chuankou_string.substr(nPos + 7);
-				}
-				else if (nPos >= 20)
-				{
-					//说明前面有20个字符,首先肯定不是稳定模式而是极速模式,另外在极速模式下可以直接得到重量了
-					weight = m_chuankou_string.substr(nPos - 20, 5);
-
-					m_chuankou_string = m_chuankou_string.substr(nPos + 2);
-				}
-				else
-				{
-					//标志符后面前面都不够读取重量,继续读取串口
-					continue;
-				}
-
-				if (weight.at(0) == ' ')
-				{
-					weight = weight.substr(1);
-				}
-
-				std::string zhengshu;
-				std::string xiaoshu;
-				if (weight.length() == 4)
-				{
-					//重量小于10公斤,第一个数字为空
-					zhengshu = weight.substr(0, 1);
-					xiaoshu = weight.substr(1, 3);
-				}
-				else if (weight.length() == 5)
-				{
-					//重量大于10公斤,第一个数字为空
-					zhengshu = weight.substr(0, 2);
-					xiaoshu = weight.substr(2, 3);
-				}
-				else
-				{
-					continue;
-				}
-
-				m_weight = zhengshu + "." + xiaoshu;
+	CEditUI* pContent = static_cast<CEditUI*>(m_pm.FindControl(_T("content")));
+	pContent->SetText(CLewaimaiString::UTF8ToUnicode(m_weight).c_str());
 
-				SendMessage(WM_CHENGZHONG_SUCCESS, 0, 0);
-			}
-			else
-			{
-				//暂时不支持的其他型号
-				Sleep(200);
-			}
-		}
-		else
-		{
-			Sleep(200);
-		}
-	}
+	wstring ws_Value = pContent->GetText();
+	string strValue = CLewaimaiString::UnicodeToUTF8(ws_Value);
 
-	m_is_chuangkou_working = false;
+	pContent->SetFocus();
+	pContent->SetSel(strValue.length(), strValue.length());//重设给光标设置位置
 }
 
 void CChengzhongWnd::SaveWeight()
 {
-	if (m_is_watching == false)
-	{
-		//串口都还没打开,禁止退出
-		return;
-	}
-
 	CEditUI* pContent = static_cast<CEditUI*>(m_pm.FindControl(_T("content")));
 	wstring wsReason = pContent->GetText();
 
@@ -496,38 +391,10 @@ void CChengzhongWnd::SaveWeight()
 		return;
 	}
 
-	m_is_watching = false;
-
-	//关闭串口,关闭之后读取串口的工作线程会退出
-	m_serial.closeComm();
-
-	//等待工作线程退出
-	while (m_is_chuangkou_working)
-	{
-		Sleep(200);
-	}
-
 	Close(IDOK);
 }
 
 void CChengzhongWnd::Quit()
 {
-	if (m_is_watching == false)
-	{
-		//串口都还没打开,禁止退出
-		return;
-	}
-
-	m_is_watching = false;
-
-	//关闭串口,关闭之后读取串口的工作线程会退出
-	m_serial.closeComm();
-
-	//等待工作线程退出
-	while (m_is_chuangkou_working)
-	{
-		Sleep(200);
-	}
-
 	Close(IDCANCEL);
 }

+ 2 - 13
zhipuzi_pos_windows/wnd/CChengzhongWnd.h

@@ -69,8 +69,7 @@ public:
 
 	LRESULT OnChengzhongSuccess(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
 
-	//读取串口的值,用于电子秤读取数据
-	void ReadChuankouValue();
+	void UpdateWeightFromWorker();
 
 	void SaveWeight();
 
@@ -88,17 +87,7 @@ public:
 	//商品单价
 	std::string m_price;
 
-	//最终称出来的重量
+	//当前获取到的重量
 	std::string m_weight;
-
-	//临时读取到的串口数据
-	std::string m_chuankou_string;
-
-	//这个表示当前是否正在读取串口值
-	bool m_is_chuangkou_working = false;
-
-	bool m_is_watching = false;
-
-	CSerialPort m_serial;
 };
 

+ 9 - 0
zhipuzi_pos_windows/wnd/CMainWnd.cpp

@@ -12,6 +12,8 @@
 
 #include "../wnd/CToastWnd.h"
 
+#include "../tool/CChengzhongWorker.h"
+
 void CMainWnd::Init()
 {
 	//设置店铺名字
@@ -39,6 +41,9 @@ void CMainWnd::Init()
 	//启动打印队列
 	CPosPrinterQueue::GetInstance()->StartWork();
 
+	//启动称重任务
+	CChengzhongWorker::GetInstance()->StartWork();
+
 	//启动一个线程,开始同步商品图片
 	std::thread(&CMainWnd::UpdateFoodImage, this).detach();
 }
@@ -557,8 +562,12 @@ LRESULT CMainWnd::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHand
     //直接退出程序,或者退出登录都会执行这个
     m_push->Stop();
 
+	//停止打印任务
 	CPosPrinterQueue::GetInstance()->StopWork();
 
+	//停止称重任务
+	CChengzhongWorker::GetInstance()->StopWork();
+
     bHandled = FALSE;
     return 0;
 }

+ 2 - 0
zhipuzi_pos_windows/zhipuzi_pos_windows.vcxproj

@@ -227,6 +227,7 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
     </PostBuildEvent>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClInclude Include="tool\CChengzhongWorker.h" />
     <ClInclude Include="print\CPosPrinter.h" />
     <ClInclude Include="print\CPosPrinterQueue.h" />
     <ClInclude Include="wnd\CGuadanWnd.h" />
@@ -298,6 +299,7 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
     <ClInclude Include="helper\CSystem.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="tool\CChengzhongWorker.cpp" />
     <ClCompile Include="print\CPosPrinter.cpp" />
     <ClCompile Include="print\CPosPrinterQueue.cpp" />
     <ClCompile Include="wnd\CGuadanWnd.cpp" />

+ 6 - 0
zhipuzi_pos_windows/zhipuzi_pos_windows.vcxproj.filters

@@ -222,6 +222,9 @@
     <ClInclude Include="print\CPosPrinter.h">
       <Filter>头文件</Filter>
     </ClInclude>
+    <ClInclude Include="tool\CChengzhongWorker.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="pch\pch.cpp">
@@ -407,6 +410,9 @@
     <ClCompile Include="print\CPosPrinter.cpp">
       <Filter>源文件</Filter>
     </ClCompile>
+    <ClCompile Include="tool\CChengzhongWorker.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <Image Include="resource\zhipuzi.ico">