张洋 hai 2 días
pai
achega
8bc55a525b

+ 64 - 0
bin/Win32/Debug/zhipuzi_pos_windows/skin/virtual_keyboard.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="ANSI"?>
+<Window size="800,280" bkcolor="#FF000000">
+  <VerticalLayout width="800" height="280" bkcolor="#FF000000">
+    <!-- 顶部栏+关闭按钮 -->
+    <HorizontalLayout height="25">
+      <Button width="775" height="25" bkcolor="#FF000000" text="" disabled="1"/>
+      <Button name="key_close" width="25" height="25" bkcolor="#FF000000" text="X" textcolor="#FFFFFFFF"/>
+    </HorizontalLayout>
+    <!-- 第一行 -->
+    <HorizontalLayout height="60">
+      <Button name="key_q" width="55" height="55" bkcolor="#FF333333" text="q" textcolor="#FFFFFFFF" margin="3,3,3,3"/>
+      <Button name="key_w" width="55" height="55" bkcolor="#FF333333" text="w" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_e" width="55" height="55" bkcolor="#FF333333" text="e" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_r" width="55" height="55" bkcolor="#FF333333" text="r" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_t" width="55" height="55" bkcolor="#FF333333" text="t" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_y" width="55" height="55" bkcolor="#FF333333" text="y" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_u" width="55" height="55" bkcolor="#FF333333" text="u" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_i" width="55" height="55" bkcolor="#FF333333" text="i" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_o" width="55" height="55" bkcolor="#FF333333" text="o" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_p" width="55" height="55" bkcolor="#FF333333" text="p" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_backspace" width="130" height="55" bkcolor="#FF333333" text="Backspace" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+    </HorizontalLayout>
+    <!-- 第二行 -->
+    <HorizontalLayout height="60">
+      <Button width="40" height="55" bkcolor="#FF000000" text="" disabled="1" margin="3,3,3,3"/>
+      <Button name="key_a" width="55" height="55" bkcolor="#FF333333" text="a" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_s" width="55" height="55" bkcolor="#FF333333" text="s" textcolor="#FFFFFFFF" margin="3,3,3,3"/>
+      <Button name="key_d" width="55" height="55" bkcolor="#FF333333" text="d" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_f" width="55" height="55" bkcolor="#FF333333" text="f" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_g" width="55" height="55" bkcolor="#FF333333" text="g" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_h" width="55" height="55" bkcolor="#FF333333" text="h" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_j" width="55" height="55" bkcolor="#FF333333" text="j" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_k" width="55" height="55" bkcolor="#FF333333" text="k" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_l" width="55" height="55" bkcolor="#FF333333" text="l" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_apos" width="55" height="55" bkcolor="#FF333333" text="'" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_enter" width="130" height="55" bkcolor="#FF333333" text="Enter" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+    </HorizontalLayout>
+    <!-- 第三行 -->
+    <HorizontalLayout height="60">
+      <Button name="key_shift_left" width="55" height="55" bkcolor="#FF333333" text="Shift" textcolor="#FFFFFFFF" margin="3,3,3,3"/>
+      <Button name="key_z" width="55" height="55" bkcolor="#FF333333" text="z" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_x" width="55" height="55" bkcolor="#FF333333" text="x" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_c" width="55" height="55" bkcolor="#FF333333" text="c" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_v" width="55" height="55" bkcolor="#FF333333" text="v" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_b" width="55" height="55" bkcolor="#FF333333" text="b" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_n" width="55" height="55" bkcolor="#FF333333" text="n" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_m" width="55" height="55" bkcolor="#FF333333" text="m" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_comma" width="55" height="55" bkcolor="#FF333333" text="," textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_dot" width="55" height="55" bkcolor="#FF333333" text="." textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_question" width="55" height="55" bkcolor="#FF333333" text="?" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_shift_right" width="55" height="55" bkcolor="#FF333333" text="Shift" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+    </HorizontalLayout>
+    <!-- 第四行 -->
+    <HorizontalLayout height="60">
+      <Button name="key_num_symbol" width="55" height="55" bkcolor="#FF333333" text="ABC" textcolor="#FFFFFFFF" margin="3,3,3,3"/>
+      <Button name="key_ctrl" width="55" height="55" bkcolor="#FF333333" text="Ctrl" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_handwriting" width="100" height="55" bkcolor="#FF333333" text="手写板" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_space" width="300" height="55" bkcolor="#FF333333" text="空格" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_cursor_left" width="55" height="55" bkcolor="#FF333333" text="<-" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_cursor_right" width="55" height="55" bkcolor="#FF333333" text="->" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+      <Button name="key_switch_ime" width="110" height="55" bkcolor="#FF333333" text="切换输入法" textcolor="#FFFFFFFF" margin="0,3,3,3"/>
+    </HorizontalLayout>
+  </VerticalLayout>
+</Window>

+ 13 - 0
zhipuzi_pos_windows/tool/debuglog.h

@@ -39,4 +39,17 @@ public:
 
         DEBUG_LOG(buffer);
     }
+
+	// 辅助日志函数(方便打印路径)
+	static void log_messagebox(LPCTSTR lpFormat, ...)
+	{
+		TCHAR szBuffer[1024] = { 0 };
+		va_list argList;
+		va_start(argList, lpFormat);
+		_vstprintf_s(szBuffer, _countof(szBuffer), lpFormat, argList);
+		va_end(argList);
+
+		// 方式1:弹出消息框(直观)
+		::MessageBox(nullptr, szBuffer, _T("日志信息"), MB_OK);
+	}
 };

+ 4 - 2
zhipuzi_pos_windows/wnd/CMainWnd.cpp

@@ -11,7 +11,7 @@
 #include <urlmon.h>
 
 #include "../wnd/CToastWnd.h"
-#include "../wnd/CVKWnd.h"
+#include "../wnd/CVirtualKeyboardWnd.h"
 
 #include "../worker/CMqttClientWorker.h"
 
@@ -60,6 +60,8 @@ void CMainWnd::Init()
 
 	//启动一个线程,开始同步商品图片
 	std::thread(&CMainWnd::UpdateFoodImage, this).detach();
+
+	this->ShowVK(true);
 }
 
 void CMainWnd::End()
@@ -1083,7 +1085,7 @@ void CMainWnd::ShowToast(std::wstring toast_value)
 
 void CMainWnd::ShowVK(bool is_show)
 {
-	CVKWnd* pVKDlg = new CVKWnd();
+	CVirtualKeyboardWnd* pVKDlg = new CVirtualKeyboardWnd();
 
 	if (pVKDlg != NULL)
 	{

+ 0 - 342
zhipuzi_pos_windows/wnd/CVKWnd.cpp

@@ -1,342 +0,0 @@
-#include "CVKWnd.h"
-#include "shellapi.h"
-#pragma comment(lib, "shell32.lib")
-
-CVKWnd::CVKWnd()
-{
-	m_pMinBtn = NULL;
-	m_pCloseBtn = NULL;
-	m_pTabLayout = NULL;
-	m_pSymbolTab = NULL;
-	m_pLShift = NULL;
-	m_pRShift = NULL;
-	m_pNum = NULL;
-	m_pCtrl = NULL;
-	m_pLSymbol = NULL;
-	m_pRSymbol = NULL;
-	m_pInputBtn = NULL;
-	m_bShiftDown = false;
-	m_bCtrlDown = false;
-}
-CVKWnd::~CVKWnd(void)
-{
-}
-
-void CVKWnd::LoadCom()
-{
-}
-void CVKWnd::OnPrepare()
-{
-}
-void CVKWnd::Init()
-{
-	m_pMinBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("minbtn")));
-	m_pCloseBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("closebtn")));
-
-	m_pTabLayout = static_cast<CTabLayoutUI*>(m_pm.FindControl(_T("switch")));
-
-	m_pLShift = static_cast<COptionUI*>(m_pm.FindControl(_T("opt_shiftl")));
-	m_pRShift = static_cast<COptionUI*>(m_pm.FindControl(_T("opt_shiftr")));
-	m_pNum = static_cast<COptionUI*>(m_pm.FindControl(_T("opt_num")));
-	m_pCtrl = static_cast<COptionUI*>(m_pm.FindControl(_T("opt_ctrl")));
-	m_pSymbolTab = static_cast<CTabLayoutUI*>(m_pm.FindControl(_T("sswitch")));
-	m_pLSymbol = static_cast<CButtonUI*>(m_pm.FindControl(_T("lsymbol")));
-	m_pRSymbol = static_cast<CButtonUI*>(m_pm.FindControl(_T("rsymbol")));
-	m_pInputBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("inputtype")));
-
-	for (int i = 65; i < 91; i++)
-	{
-		CDuiString strTemp;
-		strTemp.Format(_T("btn_%d"), i);
-		CButtonUI* pBtn = static_cast<CButtonUI*>(m_pm.FindControl(strTemp.GetData()));
-		if (pBtn)
-		{
-			CDuiString str = pBtn->GetText();
-			m_pVecBtn.push_back(pBtn);
-		}
-	}
-}
-void CVKWnd::Notify(TNotifyUI& msg)
-{
-	if (msg.sType == _T("windowinit")) OnPrepare();
-	else if (msg.sType == _T("click"))
-	{
-		if (msg.pSender == m_pCloseBtn)
-		{
-			PostQuitMessage(0);
-			return;
-		}
-		else if (msg.pSender == m_pMinBtn)
-		{
-			SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, 0);
-			return;
-		}
-		else if (msg.pSender->GetName() == _T("handinput"))
-		{
-			CDuiString strapp = CPaintManagerUI::GetInstancePath() + _T("..\\app\\handinput\\handinput.exe");
-			ShellExecute(NULL, _T("open"), strapp.GetData(), NULL, NULL, SW_SHOWDEFAULT);
-			//	PostQuitMessage(0);
-		}
-		else if (msg.pSender == m_pCtrl)  //ctrl键
-		{
-			if (m_pCtrl->IsSelected())
-			{
-				m_bCtrlDown = false;
-				m_pLShift->SetEnabled();
-				m_pRShift->SetEnabled();
-			}
-			else
-			{
-				m_bCtrlDown = true;
-				m_pLShift->Selected(false);
-				m_pRShift->Selected(false);
-				m_pLShift->SetEnabled(false);
-				m_pRShift->SetEnabled(false);
-			}
-		}
-
-		else if (msg.pSender == m_pLSymbol) //符号左方向按钮
-		{
-			if (m_pSymbolTab)
-				m_pSymbolTab->SelectItem(0);
-			if (m_pLSymbol && m_pRSymbol)
-			{
-				m_pLSymbol->SetEnabled(false);
-				m_pRSymbol->SetEnabled();
-			}
-		}
-		else if (msg.pSender == m_pRSymbol) //符号右方向按钮
-		{
-			if (m_pSymbolTab)
-				m_pSymbolTab->SelectItem(1);
-			if (m_pLSymbol && m_pRSymbol)
-			{
-				m_pLSymbol->SetEnabled();
-				m_pRSymbol->SetEnabled(false);
-			}
-		}
-		else if (msg.pSender->GetName().Find(_T("btn_")) == 0) //普通按键
-		{
-			CDuiString strTemp = msg.pSender->GetName();
-			strTemp = strTemp.Right(strTemp.GetLength() - 4);
-			int iKey = _wtoi(strTemp.GetData());
-			OnClickVK(iKey);
-		}
-		else if (msg.pSender->GetName().Find(_T("lbtn_")) == 0 || msg.pSender->GetName().Find(_T("rbtn_")) == 0) //左右都有的按键
-		{
-			CDuiString strTemp = msg.pSender->GetName();
-			strTemp = strTemp.Right(strTemp.GetLength() - 5);
-			int iKey = _wtoi(strTemp.GetData());
-			OnClickVK(iKey);
-		}
-		else if (msg.pSender->GetName().Find(_T("opt_shift")) == 0) //shift键
-		{
-			if (msg.pSender == m_pLShift)
-			{
-				if (m_pLShift->IsSelected())
-				{
-					m_pRShift->Selected(false);
-					SwitchLetter(false);
-					m_bShiftDown = false;
-				}
-				else
-				{
-					m_pRShift->Selected(true);
-					SwitchLetter(true);
-					m_bShiftDown = true;
-				}
-			}
-			else
-			{
-				if (m_pRShift->IsSelected())
-				{
-					m_pLShift->Selected(false);
-					SwitchLetter(false);
-					m_bShiftDown = false;
-				}
-				else
-				{
-					m_pLShift->Selected(true);
-					SwitchLetter(true);
-					m_bShiftDown = true;
-				}
-			}
-		}
-		else if (msg.pSender == m_pNum) //数字键
-		{
-			if (m_pNum->IsSelected())
-			{
-				m_pTabLayout->SelectItem(0);
-				m_pCtrl->SetEnabled(true);
-
-				m_pLShift->Selected(false);
-				m_pRShift->Selected(false);
-				SwitchLetter(false);
-				m_bShiftDown = false;
-			}
-			else
-			{
-				m_bShiftDown = false;
-				m_pTabLayout->SelectItem(1);
-				m_pLShift->Selected(true);
-				m_pRShift->Selected(true);
-				m_pLShift->SetEnabled(true);
-				m_pRShift->SetEnabled(true);
-				m_pCtrl->Selected(false);
-				m_pCtrl->SetEnabled(false);
-			}
-		}
-		else if (msg.pSender->GetName().Find(_T("symbol_")) == 0) //符号键
-		{
-			CDuiString strTemp = msg.pSender->GetName();
-			strTemp = strTemp.Right(strTemp.GetLength() - 7);
-			int iKey = _wtoi(strTemp.GetData());
-			keybd_event(VK_SHIFT, 0, 0, 0);
-			keybd_event(iKey, 0, 0, 0);
-			keybd_event(iKey, 0, KEYEVENTF_KEYUP, 0);
-			keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
-		}
-	}
-}
-
-LRESULT CVKWnd::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
-	LONG styleValue = ::GetWindowLong(*this, GWL_EXSTYLE);
-	styleValue &= ~WS_CAPTION;
-	::SetWindowLong(*this, GWL_EXSTYLE, styleValue | WS_EX_NOACTIVATE);
-
-	SetWindowPos(*this, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
-
-	m_pm.Init(m_hWnd);
-	CDialogBuilder builder;
-	CControlUI* pRoot = builder.Create(_T("virtual_keyboard.xml"), (UINT)0, NULL, &m_pm);
-	ASSERT(pRoot && "Failed to parse XML");
-	m_pm.AttachDialog(pRoot);
-	m_pm.AddNotifier(this);
-
-	Init();
-
-	return 0;
-}
-
-LRESULT CVKWnd::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
-	::PostQuitMessage(0L);
-
-	bHandled = FALSE;
-	return 0;
-}
-
-LRESULT CVKWnd::OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
-	if (::IsIconic(*this)) bHandled = FALSE;
-	return (wParam == 0) ? TRUE : FALSE;
-}
-LRESULT CVKWnd::OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
-	return 0;
-}
-LRESULT CVKWnd::OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
-	return 0;
-}
-LRESULT CVKWnd::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(), _T("ButtonUI")) != 0)
-			return HTCAPTION;
-	}
-
-	return HTCLIENT;
-}
-
-LRESULT CVKWnd::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
-	if (!IsIconic(*this))
-	{
-		RECT rcClient;
-		GetClientRect(*this, &rcClient);
-		HRGN hRgn = ::CreateRoundRectRgn(rcClient.left, rcClient.top, rcClient.right, rcClient.bottom, 3, 3);
-		SetWindowRgn(*this, hRgn, TRUE);
-		DeleteObject(hRgn);
-	}
-	bHandled = FALSE;
-	return 0;
-}
-
-LRESULT CVKWnd::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-{
-	bHandled = FALSE;
-	return 0;
-}
-LRESULT CVKWnd::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_DESTROY:       lRes = OnDestroy(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;
-		default:
-			bHandled = FALSE;
-	}
-	SetCursor(LoadCursor(NULL, IDC_ARROW));
-	if (bHandled)
-		return lRes;
-	if (m_pm.MessageHandler(uMsg, wParam, lParam, lRes))
-		return lRes;
-	return CWindowWnd::HandleMessage(uMsg, wParam, lParam);
-}
-
-LRESULT CVKWnd::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)
-{
-	if (uMsg == WM_KEYDOWN)
-	{
-		if (wParam == VK_RETURN)
-		{
-			return true;
-		}
-		else if (wParam == VK_ESCAPE)
-		{
-			return true;
-		}
-	}
-
-	return false;
-}
-
-void CVKWnd::OnClickVK(int iKeyValue)
-{
-	if (m_bCtrlDown && (iKeyValue == 65 || iKeyValue == 67 || iKeyValue == 86 || iKeyValue == 88 || iKeyValue == 90))
-	{
-		keybd_event(VK_CONTROL, 0, 0, 0);
-	}
-	if (m_bShiftDown)
-		keybd_event(VK_SHIFT, 0, 0, 0);
-	keybd_event(iKeyValue, 0, 0, 0);
-	Sleep(50);
-
-	keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
-
-	m_pCtrl->Selected(false);
-	m_bCtrlDown = false;
-}
-void CVKWnd::SwitchLetter(bool bUpper)
-{
-
-}

+ 0 - 83
zhipuzi_pos_windows/wnd/CVKWnd.h

@@ -1,83 +0,0 @@
-#pragma once
-
-#include "../pch/pch.h"
-#include "CMainWnd.h"
-
-class CVKWnd : public CWindowWnd, public INotifyUI, public IMessageFilterUI
-{
-public:
-	CVKWnd();
-	~CVKWnd(void);
-
-	LPCTSTR GetWindowClassName() const
-	{
-		return _T("CVKWnd");
-	};
-
-	UINT GetClassStyle() const
-	{
-		return UI_CLASSSTYLE_DIALOG;
-	};
-
-	void OnFinalMessage(HWND /*hWnd*/)
-	{
-		//WindowImplBase::OnFinalMessage(hWnd);
-		m_pm.RemovePreMessageFilter(this);
-
-		delete this;
-	};
-
-	void Init();
-
-	void Notify(TNotifyUI& msg);
-
-	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
-
-	LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
-
-	LRESULT OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
-
-	LRESULT OnNcCalcSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
-
-	LRESULT OnNcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
-
-	LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
-
-	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
-
-	LRESULT OnMouseMove(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);
-
-	void LoadCom();
-	void OnPrepare();
-	void OnClickVK(int iKeyValue);
-	void SwitchLetter(bool bUpper);
-
-public:
-	CPaintManagerUI m_pm;
-
-private:
-	CButtonUI* m_pMinBtn = NULL;
-	CButtonUI* m_pCloseBtn = NULL;
-
-	CTabLayoutUI* m_pTabLayout = NULL;
-
-	COptionUI* m_pLShift = NULL;
-	COptionUI* m_pRShift = NULL;
-	COptionUI* m_pNum = NULL;
-	COptionUI* m_pCtrl = NULL;
-
-	CTabLayoutUI* m_pSymbolTab = NULL;
-	
-	CButtonUI* m_pLSymbol = NULL;
-	CButtonUI* m_pRSymbol = NULL;
-	CButtonUI* m_pInputBtn = NULL;
-
-	std::vector<CButtonUI*> m_pVecBtn;
-
-	bool m_bShiftDown = false;
-	bool m_bCtrlDown = false;
-};

+ 210 - 0
zhipuzi_pos_windows/wnd/CVirtualKeyboardWnd.cpp

@@ -0,0 +1,210 @@
+#include "CVirtualKeyboardWnd.h"
+
+CVirtualKeyboardWnd::CVirtualKeyboardWnd()
+	: m_bIsShiftDown(false)
+	, m_bIsNumSymbol(false)
+{
+}
+
+CVirtualKeyboardWnd::~CVirtualKeyboardWnd()
+{
+	// 确保Shift抬起,避免系统键盘卡住
+	if (m_bIsShiftDown)
+	{
+		SimulateShiftPress(false);
+	}
+}
+
+void CVirtualKeyboardWnd::InitWindow()
+{
+	UpdateLetterButtonsText();
+}
+
+void CVirtualKeyboardWnd::Notify(TNotifyUI& msg)
+{
+	if (msg.sType == _T("click"))
+	{
+		CDuiString sName = msg.pSender->GetName();
+
+		// 关闭按钮
+		if (sName == _T("key_close"))
+		{
+			CloseWindow(m_hWnd);
+			return;
+		}
+
+		// ========== 字母按键 ==========
+		if (sName == _T("key_q")) SimulateKeyPress(m_bIsShiftDown ? _T('Q') : _T('q'));
+		else if (sName == _T("key_w")) SimulateKeyPress(m_bIsShiftDown ? _T('W') : _T('w'));
+		else if (sName == _T("key_e")) SimulateKeyPress(m_bIsShiftDown ? _T('E') : _T('e'));
+		else if (sName == _T("key_r")) SimulateKeyPress(m_bIsShiftDown ? _T('R') : _T('r'));
+		else if (sName == _T("key_t")) SimulateKeyPress(m_bIsShiftDown ? _T('T') : _T('t'));
+		else if (sName == _T("key_y")) SimulateKeyPress(m_bIsShiftDown ? _T('Y') : _T('y'));
+		else if (sName == _T("key_u")) SimulateKeyPress(m_bIsShiftDown ? _T('U') : _T('u'));
+		else if (sName == _T("key_i")) SimulateKeyPress(m_bIsShiftDown ? _T('I') : _T('i'));
+		else if (sName == _T("key_o")) SimulateKeyPress(m_bIsShiftDown ? _T('O') : _T('o'));
+		else if (sName == _T("key_p")) SimulateKeyPress(m_bIsShiftDown ? _T('P') : _T('p'));
+		else if (sName == _T("key_a")) SimulateKeyPress(m_bIsShiftDown ? _T('A') : _T('a'));
+		else if (sName == _T("key_s")) SimulateKeyPress(m_bIsShiftDown ? _T('S') : _T('s'));
+		else if (sName == _T("key_d")) SimulateKeyPress(m_bIsShiftDown ? _T('D') : _T('d'));
+		else if (sName == _T("key_f")) SimulateKeyPress(m_bIsShiftDown ? _T('F') : _T('f'));
+		else if (sName == _T("key_g")) SimulateKeyPress(m_bIsShiftDown ? _T('G') : _T('g'));
+		else if (sName == _T("key_h")) SimulateKeyPress(m_bIsShiftDown ? _T('H') : _T('h'));
+		else if (sName == _T("key_j")) SimulateKeyPress(m_bIsShiftDown ? _T('J') : _T('j'));
+		else if (sName == _T("key_k")) SimulateKeyPress(m_bIsShiftDown ? _T('K') : _T('k'));
+		else if (sName == _T("key_l")) SimulateKeyPress(m_bIsShiftDown ? _T('L') : _T('l'));
+		else if (sName == _T("key_z")) SimulateKeyPress(m_bIsShiftDown ? _T('Z') : _T('z'));
+		else if (sName == _T("key_x")) SimulateKeyPress(m_bIsShiftDown ? _T('X') : _T('x'));
+		else if (sName == _T("key_c")) SimulateKeyPress(m_bIsShiftDown ? _T('C') : _T('c'));
+		else if (sName == _T("key_v")) SimulateKeyPress(m_bIsShiftDown ? _T('V') : _T('v'));
+		else if (sName == _T("key_b")) SimulateKeyPress(m_bIsShiftDown ? _T('B') : _T('b'));
+		else if (sName == _T("key_n")) SimulateKeyPress(m_bIsShiftDown ? _T('N') : _T('n'));
+		else if (sName == _T("key_m")) SimulateKeyPress(m_bIsShiftDown ? _T('M') : _T('m'));
+
+		// ========== 符号按键 ==========
+		else if (sName == _T("key_apos")) SimulateKeyPress(_T('\''));
+		else if (sName == _T("key_comma")) SimulateKeyPress(_T(','));
+		else if (sName == _T("key_dot")) SimulateKeyPress(_T('.'));
+		else if (sName == _T("key_question")) SimulateKeyPress(m_bIsShiftDown ? _T('?') : _T('/'));
+
+		// ========== 功能按键 ==========
+		else if (sName == _T("key_backspace")) SimulateSpecialKey(VK_BACK);       // 退格
+		else if (sName == _T("key_enter")) SimulateSpecialKey(VK_RETURN);        // 回车
+		else if (sName == _T("key_shift_left") || sName == _T("key_shift_right")) ToggleShift(); // Shift切换
+		else if (sName == _T("key_space")) SimulateSpecialKey(VK_SPACE);          // 空格
+		else if (sName == _T("key_num_symbol")) SwitchNumSymbolLayout();          // 数字/符号布局
+		else if (sName == _T("key_cursor_left")) SimulateSpecialKey(VK_LEFT);     // 左光标
+		else if (sName == _T("key_cursor_right")) SimulateSpecialKey(VK_RIGHT);   // 右光标
+		else if (sName == _T("key_switch_ime")) SimulateSpecialKey(VK_CONTROL | VK_SHIFT); // 切换输入法
+	}
+
+	__super::Notify(msg);
+}
+
+// 模拟字符按键(核心:自动处理Shift和虚拟键码)
+void CVirtualKeyboardWnd::SimulateKeyPress(TCHAR ch)
+{
+	// 1. 获取字符对应的虚拟键码和Shift状态
+	UINT vkCode = VkKeyScan(ch);
+	bool needShift = (vkCode & 0x100) != 0; // 高位表示是否需要Shift
+	vkCode &= 0xFF; // 低位是实际虚拟键码
+
+	// 2. 如果需要Shift且当前未按下,先按Shift
+	bool bShiftPressed = false;
+	if (needShift && !m_bIsShiftDown)
+	{
+		SimulateShiftPress(true);
+		bShiftPressed = true;
+	}
+
+	// 3. 模拟按键按下+抬起
+	keybd_event((BYTE)vkCode, MapVirtualKey(vkCode, 0), 0, 0);
+	keybd_event((BYTE)vkCode, MapVirtualKey(vkCode, 0), KEYEVENTF_KEYUP, 0);
+
+	// 4. 如果是临时按下的Shift,用完后抬起
+	if (bShiftPressed)
+	{
+		SimulateShiftPress(false);
+	}
+
+	// 5. 大写模式下,按完自动取消Shift(模拟真实键盘)
+	if (m_bIsShiftDown && isupper(ch))
+	{
+		m_bIsShiftDown = false;
+		UpdateLetterButtonsText();
+		// 更新Shift按钮样式
+		CButtonUI* pShiftBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("key_shift_left")));
+		if (pShiftBtn) pShiftBtn->SetBkColor(0xFF333333);
+		pShiftBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("key_shift_right")));
+		if (pShiftBtn) pShiftBtn->SetBkColor(0xFF333333);
+	}
+}
+
+// 模拟特殊键(退格、回车、光标等)
+void CVirtualKeyboardWnd::SimulateSpecialKey(int vkCode)
+{
+	if (vkCode == (VK_CONTROL | VK_SHIFT))
+	{
+		// 切换输入法:Ctrl+Shift
+		keybd_event(VK_CONTROL, 0, 0, 0);
+		keybd_event(VK_SHIFT, 0, 0, 0);
+		keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
+		keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
+		return;
+	}
+
+	// 普通特殊键:按下+抬起
+	keybd_event((BYTE)vkCode, MapVirtualKey(vkCode, 0), 0, 0);
+	keybd_event((BYTE)vkCode, MapVirtualKey(vkCode, 0), KEYEVENTF_KEYUP, 0);
+}
+
+// 模拟Shift键按下/抬起
+void CVirtualKeyboardWnd::SimulateShiftPress(bool bPress)
+{
+	BYTE vkShift = VK_SHIFT;
+	if (bPress)
+	{
+		keybd_event(vkShift, MapVirtualKey(vkShift, 0), 0, 0);
+		m_bIsShiftDown = true;
+	}
+	else
+	{
+		keybd_event(vkShift, MapVirtualKey(vkShift, 0), KEYEVENTF_KEYUP, 0);
+		m_bIsShiftDown = false;
+	}
+}
+
+// 切换Shift状态
+void CVirtualKeyboardWnd::ToggleShift()
+{
+	m_bIsShiftDown = !m_bIsShiftDown;
+	SimulateShiftPress(m_bIsShiftDown); // 同步系统Shift状态
+	UpdateLetterButtonsText();
+
+	// 更新Shift按钮样式
+	CButtonUI* pShiftBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("key_shift_left")));
+	if (pShiftBtn) pShiftBtn->SetBkColor(m_bIsShiftDown ? 0xFF555555 : 0xFF333333);
+	pShiftBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("key_shift_right")));
+	if (pShiftBtn) pShiftBtn->SetBkColor(m_bIsShiftDown ? 0xFF555555 : 0xFF333333);
+}
+
+// 切换数字/符号布局(可扩展完整符号面板)
+void CVirtualKeyboardWnd::SwitchNumSymbolLayout()
+{
+	m_bIsNumSymbol = !m_bIsNumSymbol;
+	CButtonUI* pNumBtn = static_cast<CButtonUI*>(m_pm.FindControl(_T("key_num_symbol")));
+	if (pNumBtn) pNumBtn->SetText(m_bIsNumSymbol ? _T("ABC") : _T("&123"));
+
+	// 扩展:这里可以切换数字/符号布局的显隐(参考之前的双布局逻辑)
+}
+
+// 更新字母按键显示文本
+void CVirtualKeyboardWnd::UpdateLetterButtonsText()
+{
+	const TCHAR* szLowerLetters[] = { _T("q"), _T("w"), _T("e"), _T("r"), _T("t"), _T("y"), _T("u"), _T("i"), _T("o"), _T("p"),
+									  _T("a"), _T("s"), _T("d"), _T("f"), _T("g"), _T("h"), _T("j"), _T("k"), _T("l"),
+									  _T("z"), _T("x"), _T("c"), _T("v"), _T("b"), _T("n"), _T("m") };
+	const TCHAR* szUpperLetters[] = { _T("Q"), _T("W"), _T("E"), _T("R"), _T("T"), _T("Y"), _T("U"), _T("I"), _T("O"), _T("P"),
+									  _T("A"), _T("S"), _T("D"), _T("F"), _T("G"), _T("H"), _T("J"), _T("K"), _T("L"),
+									  _T("Z"), _T("X"), _T("C"), _T("V"), _T("B"), _T("N"), _T("M") };
+
+	for (int i = 0; i < 26; ++i)
+	{
+		CDuiString sBtnName = _T("key_");
+		sBtnName += szLowerLetters[i];
+		CButtonUI* pBtn = static_cast<CButtonUI*>(m_pm.FindControl(sBtnName));
+		if (pBtn) pBtn->SetText(m_bIsShiftDown ? szUpperLetters[i] : szLowerLetters[i]);
+	}
+}
+
+// 外部创建接口
+HWND CreateVirtualKeyboard()
+{
+	CVirtualKeyboardWnd* pKeyboard = new CVirtualKeyboardWnd();
+	if (pKeyboard)
+	{
+		// 窗口样式:置顶+无边框(模拟悬浮键盘)
+		return pKeyboard->Create(nullptr, _T("虚拟键盘"), WS_POPUP | WS_VISIBLE | WS_EX_TOPMOST, 0);
+	}
+	return nullptr;
+}

+ 54 - 0
zhipuzi_pos_windows/wnd/CVirtualKeyboardWnd.h

@@ -0,0 +1,54 @@
+#pragma once
+
+#include "../pch/pch.h"
+#include "CMainWnd.h"
+
+class CVirtualKeyboardWnd : public WindowImplBase
+{
+public:
+	CVirtualKeyboardWnd();
+	~CVirtualKeyboardWnd() override;
+
+	// 基类虚函数
+	virtual LPCTSTR GetWindowClassName() const override
+	{
+		return _T("VirtualKeyboardWnd");
+	}
+	virtual UINT GetClassStyle() const override
+	{
+		return CS_DBLCLKS;
+	}
+	virtual void OnFinalMessage(HWND hWnd) override
+	{
+		delete this;
+	}
+	virtual CDuiString GetSkinFile() override
+	{
+		return _T("virtual_keyboard.xml");
+	}
+	CDuiString GetSkinFolder()
+	{
+		return _T("");
+	}
+
+	virtual void InitWindow() override;
+	virtual void Notify(TNotifyUI& msg) override;
+
+private:
+	// 核心:模拟键盘按键
+	void SimulateKeyPress(TCHAR ch);          // 模拟字符输入(自动处理大小写/Shift)
+	void SimulateSpecialKey(int vkCode);       // 模拟特殊键(退格、回车、空格等)
+	void SimulateShiftPress(bool bPress);     // 模拟Shift按下/抬起
+
+	// 辅助功能
+	void ToggleShift();
+	void SwitchNumSymbolLayout();
+	void UpdateLetterButtonsText();
+
+private:
+	bool m_bIsShiftDown;       // Shift是否按下
+	bool m_bIsNumSymbol;       // 数字/符号布局状态
+};
+
+// 外部创建接口
+HWND CreateVirtualKeyboard();

+ 2 - 2
zhipuzi_pos_windows/zhipuzi_pos_windows.vcxproj

@@ -244,7 +244,7 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
     <ClInclude Include="ai\SQLiteVecManager.h" />
     <ClInclude Include="ai\YoloClassName.h" />
     <ClInclude Include="ai\YoloFeatureManager.h" />
-    <ClInclude Include="wnd\CVKWnd.h" />
+    <ClInclude Include="wnd\CVirtualKeyboardWnd.h" />
     <ClInclude Include="page\CAIxuexiPageUI.h" />
     <ClInclude Include="ui\TouchWindowBase.h" />
     <ClInclude Include="worker\CDiandanAIShibieWorker.h" />
@@ -377,7 +377,7 @@ copy $(ProjectDir)conf\ $(SolutionDir)bin\$(Platform)\$(Configuration)\conf\</Co
     <ClCompile Include="ai\test.cpp" />
     <ClCompile Include="ai\test.h" />
     <ClCompile Include="ai\YoloFeatureManager.cpp" />
-    <ClCompile Include="wnd\CVKWnd.cpp" />
+    <ClCompile Include="wnd\CVirtualKeyboardWnd.cpp" />
     <ClCompile Include="page\CAIxuexiPageUI.cpp" />
     <ClCompile Include="ui\TouchWindowBase.cpp" />
     <ClCompile Include="worker\CDiandanAIShibieWorker.cpp" />

+ 2 - 2
zhipuzi_pos_windows/zhipuzi_pos_windows.vcxproj.filters

@@ -402,7 +402,7 @@
     <ClInclude Include="ui\TouchWindowBase.h">
       <Filter>头文件</Filter>
     </ClInclude>
-    <ClInclude Include="wnd\CVKWnd.h">
+    <ClInclude Include="wnd\CVirtualKeyboardWnd.h">
       <Filter>头文件</Filter>
     </ClInclude>
   </ItemGroup>
@@ -767,7 +767,7 @@
     <ClCompile Include="ui\TouchWindowBase.cpp">
       <Filter>源文件</Filter>
     </ClCompile>
-    <ClCompile Include="wnd\CVKWnd.cpp">
+    <ClCompile Include="wnd\CVirtualKeyboardWnd.cpp">
       <Filter>源文件</Filter>
     </ClCompile>
   </ItemGroup>