Fix: Mouse double click can't select the wanted text

This commit is contained in:
yuanyuanxiang
2026-01-22 13:08:12 +01:00
parent 3d0492b882
commit b4c47ba553
2 changed files with 119 additions and 45 deletions

View File

@@ -150,6 +150,13 @@ public:
int m_nScreenCount; // 屏幕数量
BOOL m_bEnableMultiScreen;// 多显示器支持
protected:
int m_nVScreenLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
int m_nVScreenTop = GetSystemMetrics(SM_YVIRTUALSCREEN);
int m_nVScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int m_nVScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
public:
ScreenCapture(int n = 32, BYTE algo = ALGORITHM_DIFF, BOOL all = FALSE) :
m_ThreadPool(nullptr), m_FirstBuffer(nullptr), m_RectBuffer(nullptr),
m_BitmapInfor_Full(nullptr), m_bAlgorithm(algo), m_SendQuality(100),
@@ -162,7 +169,7 @@ public:
m_BmpZoomFirst = nullptr;
m_BlockNum = 8;
m_ThreadPool = new ThreadPool(m_BlockNum);
static auto monitors = GetAllMonitors();
auto monitors = GetAllMonitors();
static int index = 0;
m_nScreenCount = monitors.size();
m_bEnableMultiScreen = all;
@@ -235,6 +242,36 @@ public:
return m_nScreenCount;
}
virtual int GetScreenWidth() const
{
return m_ulFullWidth;
}
virtual int GetScreenHeight() const
{
return m_ulFullHeight;
}
virtual int GetScreenLeft() const {
return m_iScreenX;
}
virtual int GetScreenTop() const {
return m_iScreenY;
}
inline int GetVScreenWidth() const
{
return m_nVScreenWidth;
}
inline int GetVScreenHeight() const
{
return m_nVScreenHeight;
}
inline int GetVScreenLeft() const {
return m_nVScreenLeft;
}
inline int GetVScreenTop() const {
return m_nVScreenTop;
}
virtual bool IsOriginalSize() const
{
return m_BitmapInfor_Full->bmiHeader.biWidth == m_BitmapInfor_Send->bmiHeader.biWidth &&

View File

@@ -588,6 +588,7 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
break;
}
case COMMAND_SCREEN_CONTROL: {
if (m_ScreenSpyObject == NULL) break;
BlockInput(false);
ProcessCommand(szBuffer + 1, ulLength - 1);
BlockInput(m_bIsBlockInput); //再恢复成用户的设置
@@ -792,6 +793,19 @@ std::string GetTitle(HWND hWnd)
return title;
}
// 辅助判断是否为扩展键
bool IsExtendedKey(WPARAM vKey) {
switch (vKey) {
case VK_INSERT: case VK_DELETE: case VK_HOME: case VK_END:
case VK_PRIOR: case VK_NEXT: case VK_LEFT: case VK_UP:
case VK_RIGHT: case VK_DOWN: case VK_RCONTROL: case VK_RMENU:
case VK_DIVIDE: // 小键盘的 /
return true;
default:
return false;
}
}
VOID CScreenManager::ProcessCommand(LPBYTE szBuffer, ULONG ulLength)
{
int msgSize = sizeof(MSG64);
@@ -1028,17 +1042,12 @@ VOID CScreenManager::ProcessCommand(LPBYTE szBuffer, ULONG ulLength)
}
for (int i = 0; i < ulMsgCount; ++i, ptr += msgSize) {
MSG64* Msg = msgSize == 48 ? (MSG64*)ptr :
(MSG64*)msg64.Create(msg32.Create(ptr, msgSize));
switch (Msg->message) {
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MOUSEMOVE: {
(MSG64*)msg64.Create(msg32.Create(ptr, msgSize));
INPUT input = { 0 };
input.type = INPUT_MOUSE;
// 处理坐标:无论是点击还是移动,都先更新坐标
if (Msg->message >= WM_MOUSEFIRST && Msg->message <= WM_MOUSELAST) {
POINT Point;
Point.x = LOWORD(Msg->lParam);
Point.y = HIWORD(Msg->lParam);
@@ -1049,65 +1058,93 @@ VOID CScreenManager::ProcessCommand(LPBYTE szBuffer, ULONG ulLength)
ReleaseCapture();
return;
}
}
break;
default:
break;
// 映射到 0-65535 的绝对坐标空间
if (m_ScreenSpyObject->GetScreenCount() > 1) {
// 多显示器模式下,必须重新计算 dx, dy 映射到全虚拟桌面空间
// 且必须带上 MOUSEEVENTF_VIRTUALDESK 标志
input.mi.dx = ((Point.x - m_ScreenSpyObject->GetVScreenLeft()) * 65535) / (m_ScreenSpyObject->GetVScreenWidth() - 1);
input.mi.dy = ((Point.y - m_ScreenSpyObject->GetVScreenTop()) * 65535) / (m_ScreenSpyObject->GetVScreenHeight() - 1);
input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_VIRTUALDESK;
} else {
input.mi.dx = (Point.x * 65535) / (m_ScreenSpyObject->GetScreenWidth() - 1);
input.mi.dy = (Point.y * 65535) / (m_ScreenSpyObject->GetScreenHeight() - 1);
input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
}
}
switch(Msg->message) { //端口发加快递费
switch (Msg->message) {
case WM_MOUSEMOVE:
// 仅移动,上面已经设置了 MOUSEEVENTF_MOVE
SendInput(1, &input, sizeof(INPUT));
break;
case WM_LBUTTONDOWN:
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
input.mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
SendInput(1, &input, sizeof(INPUT));
break;
case WM_LBUTTONUP:
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
input.mi.dwFlags |= MOUSEEVENTF_LEFTUP;
SendInput(1, &input, sizeof(INPUT));
break;
case WM_RBUTTONDOWN:
mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
input.mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
SendInput(1, &input, sizeof(INPUT));
break;
case WM_RBUTTONUP:
mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
input.mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
SendInput(1, &input, sizeof(INPUT));
break;
case WM_LBUTTONDBLCLK:
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
break;
case WM_RBUTTONDBLCLK:
mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
// 前面已经收到了一个完整的 Down/Up, 这里我们只需要补一个“按下”动作, 系统就会认定这是双击
input.mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
SendInput(1, &input, sizeof(INPUT));
break;
case WM_MBUTTONDOWN:
mouse_event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0);
input.mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
SendInput(1, &input, sizeof(INPUT));
break;
case WM_MBUTTONUP:
mouse_event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0);
input.mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
SendInput(1, &input, sizeof(INPUT));
break;
case WM_MOUSEWHEEL:
mouse_event(MOUSEEVENTF_WHEEL, 0, 0,
GET_WHEEL_DELTA_WPARAM(Msg->wParam), 0);
input.mi.dwFlags = MOUSEEVENTF_WHEEL;
input.mi.mouseData = GET_WHEEL_DELTA_WPARAM(Msg->wParam);
SendInput(1, &input, sizeof(INPUT));
break;
case WM_KEYDOWN:
case WM_SYSKEYDOWN: {
INPUT input = { 0 };
input.type = INPUT_KEYBOARD;
input.ki.wVk = (WORD)Msg->wParam;
input.ki.wScan = MapVirtualKey(Msg->wParam, 0);
input.ki.dwFlags = 0;
SendInput(1, &input, sizeof(INPUT));
INPUT k_input = { 0 };
k_input.type = INPUT_KEYBOARD;
k_input.ki.wVk = (WORD)Msg->wParam;
k_input.ki.wScan = MapVirtualKey((UINT)Msg->wParam, 0);
k_input.ki.dwFlags = 0;
if (IsExtendedKey(Msg->wParam))
k_input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
SendInput(1, &k_input, sizeof(INPUT));
break;
}
case WM_KEYUP:
case WM_SYSKEYUP: {
INPUT input = { 0 };
input.type = INPUT_KEYBOARD;
input.ki.wVk = (WORD)Msg->wParam;
input.ki.wScan = MapVirtualKey(Msg->wParam, 0);
input.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &input, sizeof(INPUT));
INPUT k_input = { 0 };
k_input.type = INPUT_KEYBOARD;
k_input.ki.wVk = (WORD)Msg->wParam;
k_input.ki.wScan = MapVirtualKey((UINT)Msg->wParam, 0);
k_input.ki.dwFlags = KEYEVENTF_KEYUP;
if (IsExtendedKey(Msg->wParam))
k_input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
SendInput(1, &k_input, sizeof(INPUT));
break;
}
default:
break;
}
}
}