张洋 4 роки тому
батько
коміт
c0ea5c352b

BIN
bin/Win32/Debug/zhipuzi_pos_windows/dump/2021-11-22-19-14-08.dmp


+ 26 - 0
bin/Win32/Debug/zhipuzi_pos_windows/skin/chengzhong_wnd.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Window size="700,369" caption="0,0,0,36" roundcorner="4,4" >
+	<Font id="0" name="微软雅黑" size="26" />
+	<Font id="1" name="微软雅黑" size="32" />
+	
+	<VerticalLayout bkcolor="#FFFFFFFF">
+		<HorizontalLayout height="50" inset="10,2,10,0">
+			<Label name="memo_dlg_title" text="" align="center" valign="center" padding="0,20,0,0" font="0"/>
+		</HorizontalLayout>
+		
+		<Label name="price" text=""  height="30" width="250" padding="30,50,0,0" align="left"/>
+	
+		<HorizontalLayout padding="0,30,0,0">
+			<Label text="重量:"  height="30" width="60" padding="30,0,0,0" align="left"/>
+			<Edit name="content" enabled="false" text="" width="250" height="50" padding="30,0,0,0" textcolor="0xFF3CB371" bkcolor="#FFF2F2F2" nativebkcolor="#FFF2F2F2" font="1"/>
+			<Label text="公斤"  height="30" width="60" padding="30,0,0,0" align="left"/>
+		</HorizontalLayout>
+		
+		<Label name="errinfo" text=""  height="60" width="250" float="true" pos="30,230,280,290" align="left" textcolor="#FFFF0000" visible="false"/>
+		
+		<HorizontalLayout height="56" valign="center" padding="30,80,0,20">
+			<Button name="quit" align="center" width="100" height="45" padding="0,20,0,0" text="取消" normalimage="file='Btn_White.png' corner='5,5,5,5'" hotimage="file='Btn_White_Hover.png' corner='5,5,5,5'" pushedimage="file='Btn_White_Click.png' corner='5,5,5,5'" />
+			<Button name="save" align="center" width="100" height="45" padding="20,20,90,0" text="确认" normalimage="file='Btn_White.png' corner='5,5,5,5'" hotimage="file='Btn_White_Hover.png' corner='5,5,5,5'" pushedimage="file='Btn_White_Click.png' corner='5,5,5,5'" />
+		</HorizontalLayout>
+	</VerticalLayout>
+</Window>

+ 3 - 0
zhipuzi_pos_windows/helper/define.h

@@ -27,3 +27,6 @@
 #define WM_MEMBER_CHECK_FAIL 10200
 #define WM_MEMBER_CHECK_SUCCESS 10201
 
+//称重相关消息
+#define WM_CHENGZHONG_SUCCESS 10301
+

+ 59 - 25
zhipuzi_pos_windows/page/CDiandanPageUI.cpp

@@ -22,6 +22,7 @@
 #include "../wnd/CXianjinShoukuanWnd.h"
 #include "../wnd/CFulikaShoukuanWnd.h"
 #include "../wnd/CZidingyiShoukuanWnd.h"
+#include "../wnd/CChengzhongWnd.h"
 
 CDiandanPageUI::CDiandanPageUI()
 {
@@ -1462,51 +1463,84 @@ void CDiandanPageUI::ClickFoodAction()
 			clickItem.m_member_price.push_back(newPirce);
 		}
 
-		if (foodinfo.is_weight == "1")
-		{
-			clickItem.is_weight = true;
-		}
-		else
-		{
-			clickItem.is_weight = false;
-		}
-
 		//把当前点击商品的信息,保存到orderitem里面,方便后面修改规格的时候使用
 		clickItem.SetFoodInfo(m_cur_click_food_item->GetFoodInfo());
 		clickItem.SetIsTaocan(false);
 
-		if (foodinfo.is_nature == "1")
+		if (foodinfo.is_weight == "1")
 		{
-			//商品有商品属性
-			clickItem.is_nature = true;
+			clickItem.is_weight = true;
 
-			//先弹框进行选择属性
-			CDiandanNatureWnd* pNatureFrame = new CDiandanNatureWnd(1);
-			pNatureFrame->SetFoodItemUI(m_cur_click_food_item);
+			//这里要弹出称重框,不弹属性框
+			CChengzhongWnd* pChengzhongFrame = new CChengzhongWnd();
 
-			if (pNatureFrame != NULL)
+			if (pChengzhongFrame != NULL)
 			{
-				pNatureFrame->Create(m_pManager->GetPaintWindow(), _T(""), UI_WNDSTYLE_DIALOG, WS_EX_WINDOWEDGE);
-				pNatureFrame->SetIcon(IDI_ICON_DUILIB);
-				pNatureFrame->CenterWindow();
-				UINT ret = pNatureFrame->ShowModal();
+				pChengzhongFrame->Create(m_pManager->GetPaintWindow(), _T(""), UI_WNDSTYLE_DIALOG, WS_EX_WINDOWEDGE);
+				pChengzhongFrame->SetIcon(IDI_ICON_DUILIB);
+				pChengzhongFrame->CenterWindow();
+
+				pChengzhongFrame->SetTitle(CLewaimaiString::UTF8ToUnicode(foodinfo.name));
+
+				UINT ret = pChengzhongFrame->ShowModal();
 
 				if (ret == IDOK)
 				{
-					//保存选择的属性
-					std::vector<FoodNatureSelectValue> natureSelectedArray = pNatureFrame->GetNatureSelectedArray();
-					clickItem.natureSelectedArray = natureSelectedArray;
+					std::string weight = pChengzhongFrame->m_weight;
+					if (atof(weight.c_str()) < 0.001)
+					{
+						return;
+					}
 
-					delete pNatureFrame;
+					clickItem.num = weight;
+
+					delete pChengzhongFrame;
 				}
 				else
 				{
-					delete pNatureFrame;
+					delete pChengzhongFrame;
 
 					return;
 				}
 			}
 		}
+		else
+		{
+			clickItem.is_weight = false;
+
+			if (foodinfo.is_nature == "1")
+			{
+				//商品有商品属性
+				clickItem.is_nature = true;
+
+				//先弹框进行选择属性
+				CDiandanNatureWnd* pNatureFrame = new CDiandanNatureWnd(1);
+				pNatureFrame->SetFoodItemUI(m_cur_click_food_item);
+
+				if (pNatureFrame != NULL)
+				{
+					pNatureFrame->Create(m_pManager->GetPaintWindow(), _T(""), UI_WNDSTYLE_DIALOG, WS_EX_WINDOWEDGE);
+					pNatureFrame->SetIcon(IDI_ICON_DUILIB);
+					pNatureFrame->CenterWindow();
+					UINT ret = pNatureFrame->ShowModal();
+
+					if (ret == IDOK)
+					{
+						//保存选择的属性
+						std::vector<FoodNatureSelectValue> natureSelectedArray = pNatureFrame->GetNatureSelectedArray();
+						clickItem.natureSelectedArray = natureSelectedArray;
+
+						delete pNatureFrame;
+					}
+					else
+					{
+						delete pNatureFrame;
+
+						return;
+					}
+				}
+			}
+		}
 		
 		//商品没有商品属性
 		bool is_add_new = false;

+ 149 - 0
zhipuzi_pos_windows/tool/CSerialPort.cpp

@@ -0,0 +1,149 @@
+#include "../pch/pch.h"
+#include "CSerialPort.h"
+
+CSerialPort::CSerialPort(
+    const std::wstring portNum,
+    DWORD baudRate /* = 9600 */,
+    BYTE byteSize /* = 8 */,
+    BYTE parityBit /* = NOPARITY */,
+    BYTE stopBit /* = ONESTOPBIT */
+) : m_portNum(portNum),
+    m_dwBaudRate(baudRate),
+    m_byteSize(byteSize),
+    m_parityBit(parityBit),
+    m_stopBit(stopBit),
+    m_bOpen(false)
+{
+
+}
+
+CSerialPort::~CSerialPort()
+{
+
+}
+
+// 打开串口成功,返回 true
+
+bool CSerialPort::openComm()
+{
+    m_hComm = CreateFile(m_portNum.c_str(),
+                         GENERIC_READ | GENERIC_WRITE, //允许读和写
+                         0,		//独占方式
+                         NULL, OPEN_EXISTING,   //打开而不是创建
+                         0,   //同步方式
+                         NULL
+                        );
+
+    if(m_hComm == INVALID_HANDLE_VALUE)
+    {
+        int error = GetLastError();
+
+        return false;
+
+    }
+    else
+    {
+        DCB dcb;
+        SetupComm(m_hComm, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);	// 设置读写缓冲区大小
+        GetCommState(m_hComm, &dcb);
+        dcb.BaudRate = m_dwBaudRate;
+        dcb.ByteSize = m_byteSize;
+        dcb.Parity = m_parityBit;
+        dcb.StopBits = m_stopBit;
+
+        if(!SetCommState(m_hComm, &dcb))
+        {
+            TCHAR szBuf[1024] = { 0 };
+            wsprintf(szBuf, L"串口设置失败,错误代码: %d", GetLastError());
+            MessageBox(NULL, szBuf, TEXT("ERROR"), MB_OK);
+            return false;
+        }
+
+    }
+
+    //在读写串口前,用 PurgeComm 函数清空缓冲区
+    PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);
+
+    m_bOpen = true;
+
+    return true;
+
+}
+
+// 关闭串口
+
+void CSerialPort::closeComm()
+{
+    CloseHandle(m_hComm);
+}
+
+
+// 向串口发送数据
+bool CSerialPort::writeToComm(BYTE data[], DWORD dwLength)
+{
+#ifdef _DEBUG
+    assert(m_bOpen == true || dwLength > 0);
+    //return false;
+#endif // _DEBUG
+    DWORD dwError = 0;
+
+    if(ClearCommError(m_hComm, &dwError, NULL) && dwError > 0)
+    {
+        PurgeComm(m_hComm, PURGE_TXABORT | PURGE_TXCLEAR);
+    }
+
+    DWORD dwTx = 0;
+    BOOL ret = FALSE;
+    ret = WriteFile(m_hComm, data, dwLength, &dwTx, NULL);
+
+    if(ret == FALSE)
+    {
+        TCHAR szBuf[1024] = { 0 };
+        wsprintf(szBuf, _T("读取数据失败,错误代码: %d"), GetLastError());
+        MessageBox(NULL, szBuf, L"ERROR", MB_OK);
+
+        return false;
+    }
+
+    return true;
+
+
+}
+
+// 从串口中读取数据
+bool CSerialPort::readFromComm(char buffer[], DWORD dwLength, DWORD* nReaded)
+{
+#ifdef _DEBUG
+    assert(m_bOpen == true || dwLength > 0);
+    //return false;
+#endif // _DEBUG
+
+    COMSTAT comStat;
+    DWORD dwError = 0;
+
+    if(ClearCommError(m_hComm, &dwError, &comStat) && dwError > 0)
+    {
+        PurgeComm(m_hComm, PURGE_RXABORT | PURGE_RXCLEAR);
+    }
+
+    DWORD dwRx = 0;		// 读入的字节数
+    BOOL ret = FALSE;
+    ret = ReadFile(m_hComm, buffer, dwLength, &dwRx, NULL);	// 读入数据
+
+    if(ret == TRUE)
+    {
+		*nReaded = dwRx;
+
+        return true;
+    }
+    else
+    {
+        TCHAR szBuf[1024] = { 0 };
+        wsprintf(szBuf, _T("数据读取失败,错误代码: %d"), GetLastError());
+		LOG_INFO(szBuf);
+
+        return false;
+    }
+
+    return true;
+}

+ 98 - 0
zhipuzi_pos_windows/tool/CSerialPort.h

@@ -0,0 +1,98 @@
+#pragma once
+
+#include <cassert>
+
+typedef unsigned long ulong;
+typedef unsigned char uchar;
+
+
+class CSerialPort
+{
+public:
+    CSerialPort(
+        std::wstring portNum,		// 串口号
+        DWORD baudRate = 9600,			// 波特率
+        BYTE  byteSize = 8,				// 数据位
+        BYTE  parityBit = NOPARITY,		// 检验位
+        BYTE  stopBit = ONESTOPBIT		// 停止位
+    );
+
+    ~CSerialPort();
+
+public:
+
+    bool openComm();										// 打开串口
+    void closeComm();										// 关闭串口
+    bool writeToComm(BYTE data[], DWORD dwLegnth);			// 发送数据
+    bool readFromComm(char buffer[], DWORD dwLength, DWORD* nReaded);		// 读取数据
+
+private:
+
+    HANDLE m_hComm;		// 通信设备
+    std::wstring m_portNum; // 串口号
+    DWORD m_dwBaudRate; // 波特率
+    BYTE  m_byteSize;	// 数据位
+    BYTE  m_parityBit;  // 校验位
+    BYTE  m_stopBit;	// 停止位
+    bool  m_bOpen;		// 串口开关标志
+private:
+
+    enum BufferSize
+    {
+        MIN_BUFFER_SIZE = 256,
+        BUFFER_SIZE = 512,
+        MAX_BUFFER_SIZE = 1024
+    };
+
+    // 设置串口号
+    void setPortNum(const std::wstring &portNum)
+    {
+        this->m_portNum = portNum;
+    }
+    // 设置波特率
+    void setBaudRate(const ulong baudRate)
+    {
+        this->m_dwBaudRate = baudRate;
+    }
+    // 设置数据位
+    void setByteSize(const uchar byteSize)
+    {
+        this->m_byteSize = byteSize;
+    }
+    // 设置检验位
+    void setParityBit(const uchar parityBit)
+    {
+        this->m_parityBit = parityBit;
+    }
+    // 设置停止位
+    void setStopBit(const uchar stopBit)
+    {
+        this->m_stopBit = stopBit;
+    }
+
+    // 获取串口号
+    std::wstring getPortNum()
+    {
+        return m_portNum;
+    }
+    // 获取波特率
+    ulong getBaudRate()
+    {
+        return m_dwBaudRate;
+    }
+    // 获取数据位
+    uchar getByteSize()
+    {
+        return m_byteSize;
+    }
+    // 获取检验位
+    uchar getParityBit()
+    {
+        return m_parityBit;
+    }
+    // 获取停止位
+    uchar getStopBit()
+    {
+        return m_stopBit;
+    }
+};

+ 389 - 0
zhipuzi_pos_windows/wnd/CChengzhongWnd.cpp

@@ -0,0 +1,389 @@
+#include "../pch/pch.h"
+#include "CChengzhongWnd.h"
+#include "../tool/CSerialPort.h"
+
+LRESULT CChengzhongWnd::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+	POINT pt;
+	pt.x = GET_X_LPARAM(lParam);
+	pt.y = GET_Y_LPARAM(lParam);
+	::ScreenToClient(*this, &pt);
+
+	RECT rcClient;
+	::GetClientRect(*this, &rcClient);
+
+	RECT rcCaption = m_pm.GetCaptionRect();
+	if (pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \
+		&& pt.y >= rcCaption.top && pt.y < rcCaption.bottom)
+	{
+		CControlUI* pControl = static_cast<CControlUI*>(m_pm.FindControl(pt));
+		if (pControl && _tcscmp(pControl->GetClass(), DUI_CTR_BUTTON) != 0)
+		{
+			return HTCAPTION;
+		}
+	}
+
+	return HTCLIENT;
+}
+
+LRESULT CChengzhongWnd::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+	SIZE szRoundCorner = m_pm.GetRoundCorner();
+	if (!::IsIconic(*this) && (szRoundCorner.cx != 0 || szRoundCorner.cy != 0))
+	{
+		CDuiRect rcWnd;
+		::GetWindowRect(*this, &rcWnd);
+		rcWnd.Offset(-rcWnd.left, -rcWnd.top);
+		rcWnd.right++;
+		rcWnd.bottom++;
+		HRGN hRgn = ::CreateRoundRectRgn(rcWnd.left, rcWnd.top, rcWnd.right, rcWnd.bottom, szRoundCorner.cx, szRoundCorner.cy);
+		::SetWindowRgn(*this, hRgn, TRUE);
+		::DeleteObject(hRgn);
+	}
+
+	bHandled = FALSE;
+	return 0;
+}
+
+LRESULT CChengzhongWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+	LRESULT lRes = 0;
+	BOOL bHandled = TRUE;
+	switch (uMsg)
+	{
+	case WM_CREATE:
+		lRes = OnCreate(uMsg, wParam, lParam, bHandled);
+		break;
+	case WM_CLOSE:
+		lRes = OnClose(uMsg, wParam, lParam, bHandled);
+		break;
+	case WM_NCACTIVATE:
+		lRes = OnNcActivate(uMsg, wParam, lParam, bHandled);
+		break;
+	case WM_NCCALCSIZE:
+		lRes = OnNcCalcSize(uMsg, wParam, lParam, bHandled);
+		break;
+	case WM_NCPAINT:
+		lRes = OnNcPaint(uMsg, wParam, lParam, bHandled);
+		break;
+	case WM_NCHITTEST:
+		lRes = OnNcHitTest(uMsg, wParam, lParam, bHandled);
+		break;
+	case WM_SIZE:
+		lRes = OnSize(uMsg, wParam, lParam, bHandled);
+		break;
+	case WM_CHENGZHONG_SUCCESS:
+		lRes = OnChengzhongSuccess(uMsg, wParam, lParam, bHandled);
+		break;
+	default:
+		bHandled = FALSE;
+	}
+	if (bHandled)
+	{
+		return lRes;
+	}
+	if (m_pm.MessageHandler(uMsg, wParam, lParam, lRes))
+	{
+		return lRes;
+	}
+	return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
+}
+
+LRESULT CChengzhongWnd::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)
+{
+	if (uMsg == WM_KEYDOWN)
+	{
+		if (wParam == VK_RETURN)
+		{
+			this->SaveWeight();
+		}
+		else if (wParam == VK_ESCAPE)
+		{
+			Quit();
+		}
+	}
+
+	return false;
+}
+
+LRESULT CChengzhongWnd::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+	LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
+	styleValue &= ~WS_CAPTION;
+	::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
+
+	// 把自己的窗口句柄与窗口绘制管理器挂接在一起
+	m_pm.Init(m_hWnd);
+
+	m_pm.AddPreMessageFilter(this);
+
+	CDialogBuilder builder;
+
+	CControlUI* pRoot = builder.Create(_T("chengzhong_wnd.xml"), (UINT)0, NULL, &m_pm);
+	ASSERT(pRoot && "Failed to parse XML");
+
+	// 把这些控件绘制到本窗口上
+	m_pm.AttachDialog(pRoot);
+
+	// 把自己加入到CPaintManagerUI的m_aNotifiers数组中,用于处理Notify函数
+	m_pm.AddNotifier(this);
+
+	Init();
+
+	return 0;
+}
+
+LRESULT CChengzhongWnd::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+{
+	bHandled = FALSE;
+	return 0;
+}
+
+void CChengzhongWnd::Notify(TNotifyUI& msg)
+{
+	if (msg.sType == _T("click"))
+	{
+		DuiLib::CDuiString senderName = msg.pSender->GetName();
+
+		if (senderName == _T("quit"))
+		{
+			Quit();
+			return;
+		}
+		else if (senderName == _T("save"))
+		{
+			this->SaveWeight();
+		}
+	}
+	else if (msg.sType == _T("textchanged"))
+	{
+		//只能输入数字,其他的全部删除
+		CEditUI* m_pEdit = static_cast<CEditUI*>(m_pm.FindControl(_T("content")));
+		if (!m_pEdit->GetText().IsEmpty())
+		{
+			wstring ws_Value = m_pEdit->GetText();
+			string strValue = CLewaimaiString::UnicodeToUTF8(ws_Value);
+
+			for (size_t nIndex = 0; nIndex < strValue.length(); nIndex++)
+			{
+				unsigned char tmp = strValue.at(nIndex);
+				if ((tmp > 57 || tmp < 48) && tmp != 46)
+				{
+					//ASCII码不是数字的都过滤掉
+					strValue = strValue.substr(0, nIndex);
+
+					m_pEdit->SetText(CLewaimaiString::UTF8ToUnicode(strValue).c_str());
+					m_pEdit->SetSel(strValue.length(), strValue.length());//重设给光标设置位置
+
+					break;
+				}
+			}
+		}
+	}
+}
+
+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());
+
+	bHandled = TRUE;
+	return 0;
+}
+
+void CChengzhongWnd::Init()
+{
+	//启动一个线程,开始串口监听
+	std::thread(&CChengzhongWnd::ReadChuankouValue, this).detach();
+}
+
+void CChengzhongWnd::SetTitle(std::wstring title)
+{
+	CLabelUI* pLabel = static_cast<CLabelUI*>(m_pm.FindControl(_T("memo_dlg_title")));
+	pLabel->SetText(title.c_str());
+}
+
+void CChengzhongWnd::SetPrice(std::string price)
+{
+	m_price = price;
+
+	std::wstring ws_price = CLewaimaiString::UTF8ToUnicode(m_price);
+
+	CLabelUI* pLabel = static_cast<CLabelUI*>(m_pm.FindControl(_T("price")));
+	pLabel->SetText((L"单价:" + ws_price + L"元/公斤").c_str());
+}
+
+void CChengzhongWnd::ReadChuankouValue()
+{
+	//std::string system_setting_jinezhuaqu_setting_xunichuankou_num_2 = CSetting::GetParam("system_setting_jinezhuaqu_setting_xunichuankou_num_2");
+	//std::string system_setting_jinezhuaqu_setting_xunichuankou_botelv = CSetting::GetParam("system_setting_jinezhuaqu_setting_xunichuankou_botelv");
+
+	//CSerialPort serial(CLewaimaiString::UTF8ToUnicode(system_setting_jinezhuaqu_setting_xunichuankou_num_2), atoi(system_setting_jinezhuaqu_setting_xunichuankou_botelv.c_str()));
+
+	CSerialPort serial(L"COM3", 9600);
+
+	bool ret = serial.openComm();
+
+	if (!ret)
+	{
+		LOG_INFO("open com failed!");
+		return;
+	}
+
+	m_is_chuangkou_working = true;
+	m_is_watching = true;
+
+	m_chuankou_string = "";
+
+	char a[1024] = { 0 };
+
+	//检查监控模式和波特率,如果变了就关闭掉
+	while (m_is_watching)
+	{
+		memset(a, 0, 1024);
+
+		//开始读取串口的数据
+		DWORD nReaded = 0;
+
+		serial.readFromComm(a, 1024, &nReaded);
+
+		if (nReaded > 0)
+		{
+			//把所有读到的内容,拼接到m_chuankou_string后面,避免有的数据中间截断导致格式混乱
+			m_chuankou_string += a;
+
+			std::string show_command = "\n\r";
+
+			int nPos = m_chuankou_string.find(show_command);
+			if (nPos == m_chuankou_string.npos)
+			{
+				//没有读到足够的长度,继续读
+				continue;
+			}
+
+			if (nPos == 0)
+			{
+				//稳定模式
+				if (m_chuankou_string.length() < 7)
+				{
+					//没有读到足够的长度,继续读
+					continue;
+				}
+
+				std::string weight;
+				weight = m_chuankou_string.substr(nPos + 2, 5);
+				m_chuankou_string = m_chuankou_string.substr(7);
+
+				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;
+			}
+			else
+			{
+				//稳定模式
+				if (m_chuankou_string.length() < 22)
+				{
+					//没有读到足够的长度,继续读
+					continue;
+				}
+
+				std::string weight;
+				weight = m_chuankou_string.substr(0, 5);
+				m_chuankou_string = m_chuankou_string.substr(22);
+
+				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;
+			}
+
+			SendMessage(WM_CHENGZHONG_SUCCESS, 0, 0);
+		}
+
+		Sleep(100);
+	}
+
+	serial.closeComm();
+
+	m_is_chuangkou_working = false;
+}
+
+void CChengzhongWnd::SaveWeight()
+{
+	CEditUI* pContent = static_cast<CEditUI*>(m_pm.FindControl(_T("content")));
+	wstring wsReason = pContent->GetText();
+
+	m_weight = CLewaimaiString::UnicodeToUTF8(wsReason);
+
+	if (m_weight == "" || atof(m_weight.c_str()) < 0.001)
+	{
+		CLabelUI* pErrorInfo = static_cast<CLabelUI*>(m_pm.FindControl(_T("errinfo")));
+		pErrorInfo->SetText(L"商品重量未获取,请重新称重");
+		pErrorInfo->SetVisible(true);
+
+		return;
+	}
+
+	Close(IDOK);
+}
+
+void CChengzhongWnd::Quit()
+{
+	if (m_is_watching == false || m_is_chuangkou_working == false)
+	{
+		return;
+	}
+
+	m_is_watching = false;
+
+	//等待串口关闭
+	while (m_is_chuangkou_working)
+	{
+		Sleep(100);
+	}
+
+	Close(IDCANCEL);
+}

+ 91 - 0
zhipuzi_pos_windows/wnd/CChengzhongWnd.h

@@ -0,0 +1,91 @@
+#pragma once
+
+#include "../pch/pch.h"
+#include "CMainWnd.h"
+
+class CChengzhongWnd : public CWindowWnd, public INotifyUI, public IMessageFilterUI
+{
+public:
+	LPCTSTR GetWindowClassName() const
+	{
+		return _T("UIMemoWndFrame");
+	};
+
+	UINT GetClassStyle() const
+	{
+		return UI_CLASSSTYLE_DIALOG;
+	};
+
+	void OnFinalMessage(HWND /*hWnd*/)
+	{
+		//WindowImplBase::OnFinalMessage(hWnd);
+		m_pm.RemovePreMessageFilter(this);
+
+		//delete this;
+	};
+
+	void Init();
+
+	void SetTitle(std::wstring title);
+
+	void SetPrice(std::string price);
+
+	void Notify(TNotifyUI& msg);
+
+	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+
+	LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+
+	LRESULT OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+	{
+		if (::IsIconic(*this))
+		{
+			bHandled = FALSE;
+		}
+		return (wParam == 0) ? TRUE : FALSE;
+	}
+
+	LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+	{
+		return 0;
+	}
+
+	LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
+	{
+		return 0;
+	}
+
+	LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+
+	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+
+	LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+	LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled);
+
+	LRESULT OnChengzhongSuccess(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+
+	//读取串口的值,用于电子秤读取数据
+	void ReadChuankouValue();
+
+	void SaveWeight();
+
+	void Quit();
+
+public:
+	CPaintManagerUI m_pm;
+
+	//商品单价
+	std::string m_price;
+
+	//最终称出来的重量
+	std::string m_weight;
+
+	std::string m_chuankou_string;
+
+	//这个表示当前是否正在读取串口值
+	bool m_is_chuangkou_working = false;
+
+	bool m_is_watching = false;
+};
+

+ 1 - 1
zhipuzi_pos_windows/zhipuzi/CDiandanOrder.cpp

@@ -63,7 +63,7 @@ int CDiandanOrder::AddItem(CDiandanOrderItem newitem, bool& is_add_new)
 		std::string old_num = m_items[index].num;
 
 		double d_old_num = std::stod(old_num);
-		double d_new_num = d_old_num + 1;
+		double d_new_num = d_old_num + std::stod(newitem.num);
 
 		//如果新的数量是一个整数,那么展示的时候就把小数去掉
 		if (d_new_num - (int)d_new_num < 0.0001)

+ 4 - 0
zhipuzi_pos_windows/zhipuzi_pos_windows.vcxproj

@@ -225,6 +225,8 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
     </PostBuildEvent>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClInclude Include="wnd\CChengzhongWnd.h" />
+    <ClInclude Include="tool\CSerialPort.h" />
     <ClInclude Include="wnd\CZidingyiShoukuanWnd.h" />
     <ClInclude Include="wnd\CToastWnd.h" />
     <ClInclude Include="wnd\CFulikaShoukuanWnd.h" />
@@ -290,6 +292,8 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
     <ClInclude Include="helper\CSystem.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="wnd\CChengzhongWnd.cpp" />
+    <ClCompile Include="tool\CSerialPort.cpp" />
     <ClCompile Include="wnd\CZidingyiShoukuanWnd.cpp" />
     <ClCompile Include="wnd\CToastWnd.cpp" />
     <ClCompile Include="wnd\CFulikaShoukuanWnd.cpp" />

+ 12 - 0
zhipuzi_pos_windows/zhipuzi_pos_windows.vcxproj.filters

@@ -204,6 +204,12 @@
     <ClInclude Include="wnd\CZidingyiShoukuanWnd.h">
       <Filter>头文件</Filter>
     </ClInclude>
+    <ClInclude Include="tool\CSerialPort.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
+    <ClInclude Include="wnd\CChengzhongWnd.h">
+      <Filter>头文件</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="pch\pch.cpp">
@@ -371,6 +377,12 @@
     <ClCompile Include="wnd\CZidingyiShoukuanWnd.cpp">
       <Filter>源文件</Filter>
     </ClCompile>
+    <ClCompile Include="tool\CSerialPort.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="wnd\CChengzhongWnd.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <Image Include="resource\zhipuzi.ico">