|
|
@@ -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;
|
|
|
}
|