Feature: Add remote_keyboard MCP tool (key_down / key_up / key_press / type)
Implement milestone M2b of the MCP remote-control design: inject keyboard events through an existing screen sub-connection. - Extract the MSG64 keyboard construction from WebService::HandleKey into a shared inline BuildKeyMsg64 helper in WebService.h, and have HandleKey use it (behaviour-preserving) so the Web and MCP paths cannot drift. - Add BuildRemoteKeyboard with four actions: key_down / key_up / key_press (key name -> VK via MapKeyNameToVk, plus CTRL/ALT/SHIFT/WIN modifiers) and type (per-character VkKeyScanA mapping, ASCII only, newline/tab -> Enter/Tab). The batch is sent as one [COMMAND_SCREEN_CONTROL][MSG64*N] packet over the screen sub-connection under the existing Begin/EndScreenCtrlAction busy discipline, then audited via WM_SHOWERRORMSG. Non-ASCII text is rejected (-32602) and must go through remote_clipboard + Ctrl+V (milestone M4), matching the design's clipboard path for CJK input. Co-Authored-By: deepseek-v4-pro
This commit is contained in:
@@ -13,11 +13,41 @@
|
||||
#include <random>
|
||||
#include <ctime>
|
||||
|
||||
#include "common/commands.h" // MSG64 / COMMAND_SCREEN_CONTROL:共享键盘注入 helper(BuildKeyMsg64)
|
||||
|
||||
// Forward declarations
|
||||
class context;
|
||||
class CMy2015RemoteDlg;
|
||||
class CONTEXT_OBJECT;
|
||||
|
||||
// 构造单个键盘注入 MSG64(复用 WebService::HandleKey 的 lParam 逻辑,抽取为共享 helper,
|
||||
// 供 Web 与 MCP 远程控制两处使用,避免漂移,见 docs/Mcp_RemoteControl_Design.md §6.2)。
|
||||
// keyCode:虚拟键码;isDown:按下/抬起;isSysKey:true 用 WM_SYSKEYDOWN/UP 并置 Alt 上下文位。
|
||||
inline MSG64 BuildKeyMsg64(int keyCode, bool isDown, bool isSysKey) {
|
||||
MSG64 msg64;
|
||||
memset(&msg64, 0, sizeof(MSG64));
|
||||
|
||||
if (isSysKey) msg64.message = isDown ? WM_SYSKEYDOWN : WM_SYSKEYUP;
|
||||
else msg64.message = isDown ? WM_KEYDOWN : WM_KEYUP;
|
||||
msg64.wParam = (uint64_t)keyCode;
|
||||
msg64.time = GetTickCount();
|
||||
|
||||
UINT scanCode = MapVirtualKey(keyCode, MAPVK_VK_TO_VSC);
|
||||
bool isExtended = (keyCode >= VK_PRIOR && keyCode <= VK_DOWN) ||
|
||||
keyCode == VK_INSERT || keyCode == VK_DELETE ||
|
||||
keyCode == VK_NUMLOCK || keyCode == VK_RCONTROL || keyCode == VK_RMENU ||
|
||||
keyCode == VK_APPS;
|
||||
|
||||
LPARAM lParam = 1; // repeat count = 1
|
||||
lParam |= (scanCode & 0xFF) << 16;
|
||||
if (isExtended) lParam |= (1 << 24);
|
||||
if (isSysKey) lParam |= (1 << 29); // context code for Alt
|
||||
if (!isDown) lParam |= (3UL << 30); // bit 30/31 for key up
|
||||
|
||||
msg64.lParam = (uint64_t)lParam;
|
||||
return msg64;
|
||||
}
|
||||
|
||||
// Web client state
|
||||
struct WebClient {
|
||||
std::string token;
|
||||
|
||||
Reference in New Issue
Block a user