Procházet zdrojové kódy

继续优化虚拟键盘

张洋 před 1 dnem
rodič
revize
5c5855365e

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1094 - 784
DuiLib/Core/UIManager.cpp


binární
bin/Win32/Debug/zhipuzi_pos_windows/DuiLib_d.dll


+ 95 - 57
bin/Win32/Debug/zhipuzi_pos_windows/skin/virtual_keyboard.xml

@@ -1,64 +1,102 @@
-<?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"/>
+<?xml version="1.0" encoding="UTF-8"?>
+<Window size="955,275" caption="0,0,0,20" roundcorner="4,4">
+     <Font id="0" name="微软雅黑" size="20" default="true" />
+     <VerticalLayout bkcolor="#FF000000">
+          <HorizontalLayout height="20" bkcolor="#FF000000">
+               <Control />
+      <Button name="closebtn" text="X" width="30" height="18" bkcolor="#FF000000" 
+           textcolor="#FFFFFFFF" align="center"/>
     </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 height="60" childpadding="8" padding="3,3,3,3">
+      <Button name="btn_q" text="q" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_w" text="w" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_e" text="e" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_r" text="r" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_t" text="t" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_y" text="y" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_u" text="u" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_i" text="i" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_o" text="o" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_p" text="p" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_backspace" text="Backspace" width="150" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
     </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 height="60" childpadding="8" padding="3,3,3,3">
+      <Control width="40" height="55" bkcolor="#FF000000"/>
+      <Button name="btn_a" text="a" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_s" text="s" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_d" text="d" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_f" text="f" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_g" text="g" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_h" text="h" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_j" text="j" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_k" text="k" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_l" text="l" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+     <Button name="btn_apos" text="&apos;" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_enter" text="Enter" width="130" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
     </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 height="60" childpadding="8" padding="3,3,3,3">
+      <Button name="btn_shift_l" text="Shift" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_z" text="z" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_x" text="x" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_c" text="c" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_v" text="v" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_b" text="b" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_n" text="n" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_m" text="m" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_comma" text="," width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_dot" text="." width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_question" text="?" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_shift_r" text="Shift" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
     </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 height="60" childpadding="8" padding="3,3,3,3">
+      <Button name="btn_num_symbol" text="&amp;123" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_ctrl" text="Ctrl" width="65" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_handwriting" text="手写板" width="120" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_space" text="空格" width="460" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
+      <Button name="btn_switch_ime" text="切换输入法" width="120" height="55" bkcolor="#FF302F37" 
+           textcolor="#FFFFFFFF" align="center"/>
     </HorizontalLayout>
   </VerticalLayout>
 </Window>

binární
dll/debug/DuiLib_d.dll


+ 9 - 3
zhipuzi_pos_windows/wnd/CMainWnd.cpp

@@ -1085,15 +1085,21 @@ void CMainWnd::ShowToast(std::wstring toast_value)
 
 void CMainWnd::ShowVK(bool is_show)
 {
+    if (!is_show)
+	{
+		return;
+	}
+
 	CVirtualKeyboardWnd* pVKDlg = new CVirtualKeyboardWnd();
 
 	if (pVKDlg != NULL)
 	{
-		pVKDlg->Create(m_pm.GetPaintWindow(), _T(""), UI_WNDSTYLE_DIALOG, WS_EX_WINDOWEDGE);
+       pVKDlg->Create(m_hWnd, _T("虚拟键盘"),
+			WS_POPUP,
+			WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE);
 		pVKDlg->SetIcon(IDI_ICON_DUILIB);
 		pVKDlg->CenterWindow();
-
-		pVKDlg->ShowWindow();
+		pVKDlg->ShowWindow(true, false);
 	}
 }
 

+ 295 - 123
zhipuzi_pos_windows/wnd/CVirtualKeyboardWnd.cpp

@@ -1,210 +1,382 @@
 #include "CVirtualKeyboardWnd.h"
 
+namespace
+{
+	struct KeyButtonDef
+	{
+		LPCTSTR name;
+		TCHAR alphaLower;
+		TCHAR alphaUpper;
+		TCHAR symbol;
+		TCHAR symbolShift;
+	};
+
+	const KeyButtonDef g_keyButtons[] =
+	{
+		{ _T("btn_q"), _T('q'), _T('Q'), _T('1'), _T('[') },
+		{ _T("btn_w"), _T('w'), _T('W'), _T('2'), _T(']') },
+		{ _T("btn_e"), _T('e'), _T('E'), _T('3'), _T('{') },
+		{ _T("btn_r"), _T('r'), _T('R'), _T('4'), _T('}') },
+		{ _T("btn_t"), _T('t'), _T('T'), _T('5'), _T('#') },
+		{ _T("btn_y"), _T('y'), _T('Y'), _T('6'), _T('%') },
+		{ _T("btn_u"), _T('u'), _T('U'), _T('7'), _T('^') },
+		{ _T("btn_i"), _T('i'), _T('I'), _T('8'), _T('*') },
+		{ _T("btn_o"), _T('o'), _T('O'), _T('9'), _T('+') },
+		{ _T("btn_p"), _T('p'), _T('P'), _T('0'), _T('=') },
+		{ _T("btn_a"), _T('a'), _T('A'), _T('-'), _T('_') },
+		{ _T("btn_s"), _T('s'), _T('S'), _T('/'), _T('\\') },
+		{ _T("btn_d"), _T('d'), _T('D'), _T(':'), _T('|') },
+		{ _T("btn_f"), _T('f'), _T('F'), _T(';'), _T('~') },
+		{ _T("btn_g"), _T('g'), _T('G'), _T('('), _T('<') },
+		{ _T("btn_h"), _T('h'), _T('H'), _T(')'), _T('>') },
+		{ _T("btn_j"), _T('j'), _T('J'), _T('$'), _T('$') },
+		{ _T("btn_k"), _T('k'), _T('K'), _T('&'), _T('&') },
+		{ _T("btn_l"), _T('l'), _T('L'), _T('@'), _T('@') },
+		{ _T("btn_apos"), _T('\''), _T('"'), _T('`'), _T('"') },
+		{ _T("btn_z"), _T('z'), _T('Z'), _T('.'), _T('.') },
+		{ _T("btn_x"), _T('x'), _T('X'), _T(','), _T(',') },
+		{ _T("btn_c"), _T('c'), _T('C'), _T('?'), _T('?') },
+		{ _T("btn_v"), _T('v'), _T('V'), _T('!'), _T('!') },
+		{ _T("btn_b"), _T('b'), _T('B'), _T('\''), _T('\'') },
+		{ _T("btn_n"), _T('n'), _T('N'), _T('#'), _T('"') },
+		{ _T("btn_m"), _T('m'), _T('M'), _T('%'), _T(';') },
+		{ _T("btn_comma"), _T(','), _T('<'), _T('+'), _T(':') },
+		{ _T("btn_dot"), _T('.'), _T('>'), _T('='), _T('-') },
+		{ _T("btn_question"), _T('/'), _T('?'), _T('_'), _T('/') },
+	};
+
+	const KeyButtonDef* FindKeyButton(LPCTSTR name)
+	{
+		for (const auto& key : g_keyButtons)
+		{
+			if (_tcscmp(key.name, name) == 0)
+			{
+				return &key;
+			}
+		}
+
+		return nullptr;
+	}
+
+	void SetButtonText(DuiLib::CPaintManagerUI& pm, LPCTSTR name, TCHAR ch)
+	{
+		TCHAR text[2] = { ch, 0 };
+		auto* button = static_cast<DuiLib::CButtonUI*>(pm.FindControl(name));
+		if (button != nullptr)
+		{
+			button->SetText(text);
+		}
+	}
+
+	void SetButtonText(DuiLib::CPaintManagerUI& pm, LPCTSTR name, LPCTSTR text)
+	{
+		auto* button = static_cast<DuiLib::CButtonUI*>(pm.FindControl(name));
+		if (button != nullptr)
+		{
+			button->SetText(text);
+		}
+	}
+}
+
 CVirtualKeyboardWnd::CVirtualKeyboardWnd()
 	: m_bIsShiftDown(false)
+	, m_bIsCtrlDown(false)
 	, m_bIsNumSymbol(false)
+	, m_hTargetWnd(NULL)
 {
 }
 
 CVirtualKeyboardWnd::~CVirtualKeyboardWnd()
 {
-	// 确保Shift抬起,避免系统键盘卡住
-	if (m_bIsShiftDown)
-	{
-		SimulateShiftPress(false);
-	}
 }
 
 void CVirtualKeyboardWnd::InitWindow()
 {
+	m_pm.SetNoActivate(true);
+	UpdateTargetWindow();
 	UpdateLetterButtonsText();
+	UpdateModifierButtonsState();
 }
 
 void CVirtualKeyboardWnd::Notify(TNotifyUI& msg)
 {
 	if (msg.sType == _T("click"))
 	{
+		UpdateTargetWindow();
 		CDuiString sName = msg.pSender->GetName();
 
-		// 关闭按钮
-		if (sName == _T("key_close"))
+		if (sName == _T("closebtn"))
 		{
-			CloseWindow(m_hWnd);
+			Close();
 			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); // 切换输入法
+		if (sName == _T("btn_shift_l") || sName == _T("btn_shift_r"))
+		{
+			ToggleShift();
+			return;
+		}
+
+		if (sName == _T("btn_ctrl"))
+		{
+			ToggleCtrl();
+			return;
+		}
+
+		if (sName == _T("btn_num_symbol"))
+		{
+			SwitchNumSymbolLayout();
+			return;
+		}
+
+		if (sName == _T("btn_backspace"))
+		{
+			SimulateSpecialKey(VK_BACK);
+			return;
+		}
+
+		if (sName == _T("btn_enter"))
+		{
+			SimulateSpecialKey(VK_RETURN);
+			return;
+		}
+
+		if (sName == _T("btn_space"))
+		{
+			SimulateSpecialKey(VK_SPACE);
+			return;
+		}
+
+		if (sName == _T("btn_left"))
+		{
+			SimulateSpecialKey(VK_LEFT);
+			return;
+		}
+
+		if (sName == _T("btn_right"))
+		{
+			SimulateSpecialKey(VK_RIGHT);
+			return;
+		}
+
+		if (sName == _T("btn_switch_ime"))
+		{
+			SimulateSpecialKey(VK_CONTROL | VK_SHIFT);
+			return;
+		}
+
+		if (sName == _T("btn_handwriting"))
+		{
+			OpenHandwritingPanel();
+			return;
+		}
+
+		if (const auto* key = FindKeyButton(sName))
+		{
+			const TCHAR ch = m_bIsNumSymbol
+				? (m_bIsShiftDown ? key->symbolShift : key->symbol)
+				: (m_bIsShiftDown ? key->alphaUpper : key->alphaLower);
+
+			SimulateKeyPress(ch);
+			return;
+		}
 	}
 
 	__super::Notify(msg);
 }
 
-// 模拟字符按键(核心:自动处理Shift和虚拟键码)
 void CVirtualKeyboardWnd::SimulateKeyPress(TCHAR ch)
 {
-	// 1. 获取字符对应的虚拟键码和Shift状态
-	UINT vkCode = VkKeyScan(ch);
-	bool needShift = (vkCode & 0x100) != 0; // 高位表示是否需要Shift
-	vkCode &= 0xFF; // 低位是实际虚拟键码
+   SHORT vkInfo = ::VkKeyScan(ch);
+	if (vkInfo == -1)
+	{
+		return;
+	}
 
-	// 2. 如果需要Shift且当前未按下,先按Shift
-	bool bShiftPressed = false;
-	if (needShift && !m_bIsShiftDown)
+	BYTE vkCode = LOBYTE(vkInfo);
+	BYTE shiftState = HIBYTE(vkInfo);
+	bool useCtrl = m_bIsCtrlDown;
+	bool useShift = (shiftState & 1) != 0;
+
+	if (useCtrl)
+	{
+		::keybd_event(VK_CONTROL, static_cast<BYTE>(::MapVirtualKey(VK_CONTROL, 0)), 0, 0);
+	}
+	if (useShift)
 	{
-		SimulateShiftPress(true);
-		bShiftPressed = true;
+		::keybd_event(VK_SHIFT, static_cast<BYTE>(::MapVirtualKey(VK_SHIFT, 0)), 0, 0);
 	}
 
-	// 3. 模拟按键按下+抬起
-	keybd_event((BYTE)vkCode, MapVirtualKey(vkCode, 0), 0, 0);
-	keybd_event((BYTE)vkCode, MapVirtualKey(vkCode, 0), KEYEVENTF_KEYUP, 0);
+	::keybd_event(vkCode, static_cast<BYTE>(::MapVirtualKey(vkCode, 0)), 0, 0);
+	::keybd_event(vkCode, static_cast<BYTE>(::MapVirtualKey(vkCode, 0)), KEYEVENTF_KEYUP, 0);
 
-	// 4. 如果是临时按下的Shift,用完后抬起
-	if (bShiftPressed)
+	if (useShift)
 	{
-		SimulateShiftPress(false);
+		::keybd_event(VK_SHIFT, static_cast<BYTE>(::MapVirtualKey(VK_SHIFT, 0)), KEYEVENTF_KEYUP, 0);
+	}
+	if (useCtrl)
+	{
+		::keybd_event(VK_CONTROL, static_cast<BYTE>(::MapVirtualKey(VK_CONTROL, 0)), KEYEVENTF_KEYUP, 0);
+		m_bIsCtrlDown = false;
 	}
 
-	// 5. 大写模式下,按完自动取消Shift(模拟真实键盘)
-	if (m_bIsShiftDown && isupper(ch))
+	if (m_bIsShiftDown)
 	{
 		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);
 	}
+
+	UpdateLetterButtonsText();
+	UpdateModifierButtonsState();
 }
 
-// 模拟特殊键(退格、回车、光标等)
 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);
+     ::keybd_event(VK_CONTROL, static_cast<BYTE>(::MapVirtualKey(VK_CONTROL, 0)), 0, 0);
+		::keybd_event(VK_SHIFT, static_cast<BYTE>(::MapVirtualKey(VK_SHIFT, 0)), 0, 0);
+		::keybd_event(VK_SHIFT, static_cast<BYTE>(::MapVirtualKey(VK_SHIFT, 0)), KEYEVENTF_KEYUP, 0);
+		::keybd_event(VK_CONTROL, static_cast<BYTE>(::MapVirtualKey(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);
-}
+	bool useCtrl = m_bIsCtrlDown;
+	bool useShift = m_bIsShiftDown;
 
-// 模拟Shift键按下/抬起
-void CVirtualKeyboardWnd::SimulateShiftPress(bool bPress)
-{
-	BYTE vkShift = VK_SHIFT;
-	if (bPress)
+	if (useCtrl)
+	{
+      ::keybd_event(VK_CONTROL, static_cast<BYTE>(::MapVirtualKey(VK_CONTROL, 0)), 0, 0);
+	}
+	if (useShift)
 	{
-		keybd_event(vkShift, MapVirtualKey(vkShift, 0), 0, 0);
-		m_bIsShiftDown = true;
+        ::keybd_event(VK_SHIFT, static_cast<BYTE>(::MapVirtualKey(VK_SHIFT, 0)), 0, 0);
 	}
-	else
+
+ ::keybd_event(static_cast<BYTE>(vkCode), static_cast<BYTE>(::MapVirtualKey(vkCode, 0)), 0, 0);
+	::keybd_event(static_cast<BYTE>(vkCode), static_cast<BYTE>(::MapVirtualKey(vkCode, 0)), KEYEVENTF_KEYUP, 0);
+
+	if (useShift)
 	{
-		keybd_event(vkShift, MapVirtualKey(vkShift, 0), KEYEVENTF_KEYUP, 0);
+      ::keybd_event(VK_SHIFT, static_cast<BYTE>(::MapVirtualKey(VK_SHIFT, 0)), KEYEVENTF_KEYUP, 0);
 		m_bIsShiftDown = false;
 	}
+	if (useCtrl)
+	{
+        ::keybd_event(VK_CONTROL, static_cast<BYTE>(::MapVirtualKey(VK_CONTROL, 0)), KEYEVENTF_KEYUP, 0);
+		m_bIsCtrlDown = false;
+	}
+
+	UpdateLetterButtonsText();
+	UpdateModifierButtonsState();
 }
 
-// 切换Shift状态
-void CVirtualKeyboardWnd::ToggleShift()
+void CVirtualKeyboardWnd::SimulateShiftPress(bool bPress)
 {
-	m_bIsShiftDown = !m_bIsShiftDown;
-	SimulateShiftPress(m_bIsShiftDown); // 同步系统Shift状态
+	m_bIsShiftDown = bPress;
 	UpdateLetterButtonsText();
+	UpdateModifierButtonsState();
+}
+
+void CVirtualKeyboardWnd::ToggleShift()
+{
+	SimulateShiftPress(!m_bIsShiftDown);
+}
 
-	// 更新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::ToggleCtrl()
+{
+	m_bIsCtrlDown = !m_bIsCtrlDown;
+	UpdateModifierButtonsState();
 }
 
-// 切换数字/符号布局(可扩展完整符号面板)
 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"));
-
-	// 扩展:这里可以切换数字/符号布局的显隐(参考之前的双布局逻辑)
+	m_bIsShiftDown = false;
+	UpdateLetterButtonsText();
+	UpdateModifierButtonsState();
 }
 
-// 更新字母按键显示文本
 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 (const auto& key : g_keyButtons)
+	{
+		const TCHAR ch = m_bIsNumSymbol
+			? (m_bIsShiftDown ? key.symbolShift : key.symbol)
+			: (m_bIsShiftDown ? key.alphaUpper : key.alphaLower);
+		SetButtonText(m_pm, key.name, ch);
+	}
+
+	SetButtonText(m_pm, _T("btn_num_symbol"), m_bIsNumSymbol ? _T("ABC") : _T("&123"));
+}
+
+void CVirtualKeyboardWnd::UpdateModifierButtonsState()
+{
+	const DWORD normalColor = 0xFF302F37;
+	const DWORD activeColor = 0xFF555555;
+
+	auto* leftShift = static_cast<CButtonUI*>(m_pm.FindControl(_T("btn_shift_l")));
+	if (leftShift != nullptr)
+	{
+		leftShift->SetBkColor(m_bIsShiftDown ? activeColor : normalColor);
+	}
 
-	for (int i = 0; i < 26; ++i)
+	auto* rightShift = static_cast<CButtonUI*>(m_pm.FindControl(_T("btn_shift_r")));
+	if (rightShift != nullptr)
+	{
+		rightShift->SetBkColor(m_bIsShiftDown ? activeColor : normalColor);
+	}
+
+	auto* ctrl = static_cast<CButtonUI*>(m_pm.FindControl(_T("btn_ctrl")));
+	if (ctrl != nullptr)
+	{
+		ctrl->SetBkColor(m_bIsCtrlDown ? activeColor : normalColor);
+	}
+}
+
+void CVirtualKeyboardWnd::UpdateTargetWindow()
+{
+	HWND hFocus = ::GetFocus();
+	if (hFocus != NULL && hFocus != m_hWnd && !::IsChild(m_hWnd, hFocus))
+	{
+		m_hTargetWnd = hFocus;
+	}
+}
+
+HWND CVirtualKeyboardWnd::GetTargetWindow()
+{
+	UpdateTargetWindow();
+	if (m_hTargetWnd != NULL && ::IsWindow(m_hTargetWnd))
+	{
+		return m_hTargetWnd;
+	}
+
+	return NULL;
+}
+
+void CVirtualKeyboardWnd::RestoreTargetWindow()
+{
+	HWND hTarget = GetTargetWindow();
+	if (hTarget != NULL && ::GetFocus() != hTarget)
+	{
+		::SetFocus(hTarget);
+	}
+}
+
+void CVirtualKeyboardWnd::OpenHandwritingPanel()
+{
+	if ((INT_PTR)::ShellExecute(m_hWnd, _T("open"), _T("TabTip.exe"), NULL, NULL, SW_SHOWNORMAL) <= 32)
 	{
-		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]);
+		::ShellExecute(m_hWnd, _T("open"), _T("InputPanel.exe"), NULL, NULL, SW_SHOWNORMAL);
 	}
+	RestoreTargetWindow();
 }
 
-// 外部创建接口
 HWND CreateVirtualKeyboard()
 {
 	CVirtualKeyboardWnd* pKeyboard = new CVirtualKeyboardWnd();
 	if (pKeyboard)
 	{
-		// 窗口样式:置顶+无边框(模拟悬浮键盘)
-		return pKeyboard->Create(nullptr, _T("虚拟键盘"), WS_POPUP | WS_VISIBLE | WS_EX_TOPMOST, 0);
+      return pKeyboard->Create(nullptr, _T("虚拟键盘"), WS_POPUP, WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE);
 	}
 	return nullptr;
 }

+ 25 - 3
zhipuzi_pos_windows/wnd/CVirtualKeyboardWnd.h

@@ -22,6 +22,20 @@ public:
 	{
 		delete this;
 	}
+	virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override
+	{
+		if (uMsg == WM_MOUSEACTIVATE)
+		{
+			// 鼠标点击键盘时不激活窗口,返回 MA_NOACTIVATE
+			return MA_NOACTIVATE;
+		}
+		if (uMsg == WM_ACTIVATE)
+		{
+			// 拦截激活消息,不执行默认逻辑
+			return 0;
+		}
+		return __super::HandleMessage(uMsg, wParam, lParam);
+	}
 	virtual CDuiString GetSkinFile() override
 	{
 		return _T("virtual_keyboard.xml");
@@ -36,18 +50,26 @@ public:
 
 private:
 	// 核心:模拟键盘按键
-	void SimulateKeyPress(TCHAR ch);          // 模拟字符输入(自动处理大小写/Shift)
-	void SimulateSpecialKey(int vkCode);       // 模拟特殊键(退格、回车、空格等)
-	void SimulateShiftPress(bool bPress);     // 模拟Shift按下/抬起
+	void SimulateKeyPress(TCHAR ch);
+	void SimulateSpecialKey(int vkCode);
+	void SimulateShiftPress(bool bPress);
 
 	// 辅助功能
 	void ToggleShift();
+	void ToggleCtrl();
 	void SwitchNumSymbolLayout();
 	void UpdateLetterButtonsText();
+	void UpdateModifierButtonsState();
+	void UpdateTargetWindow();
+	HWND GetTargetWindow();
+	void RestoreTargetWindow();
+	void OpenHandwritingPanel();
 
 private:
 	bool m_bIsShiftDown;       // Shift是否按下
+	bool m_bIsCtrlDown;        // Ctrl是否按下
 	bool m_bIsNumSymbol;       // 数字/符号布局状态
+	HWND m_hTargetWnd;         // 当前输入目标
 };
 
 // 外部创建接口