Skip to content

Commit

Permalink
refactor: new implementation for sending key combinations
Browse files Browse the repository at this point in the history
The `IsNeedKeep()` (with tick fault tolerance) introduced in the previous version will expose the issue in #69. Because when the user sends a right click, the program captures the middle click operation sent by itself, causing the two operations to be within the tick fault tolerance range, thus triggering the sending of the two commands in `HandleMiddleClick`. To this end, this commit introduces `dwExtraInfo` information to prevent the capture of operations sent by the program itself.
  • Loading branch information
Ritchie1108 authored and Bush2021 committed May 7, 2024
1 parent 80561dc commit 2d42777
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/tabbookmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ int HandleRightClick(WPARAM wParam, PMOUSEHOOKSTRUCT pmouse) {
ExecuteCommand(IDC_NEW_TAB, hwnd);
ExecuteCommand(IDC_WINDOW_CLOSE_OTHER_TABS, hwnd);
} else {
SendKeys(VK_MBUTTON);
// Attempt new SendKey function which includes a `dwExtraInfo`
// value (MAGIC_CODE).
SendKey(VK_MBUTTON);
}
return 1;
}
Expand Down Expand Up @@ -263,6 +265,8 @@ LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
return CallNextHookEx(mouse_hook, nCode, wParam, lParam);
}

// Defining a `dwExtraInfo` value to prevent hook the message sent by
// Chrome++ itself.
if (pmouse->dwExtraInfo == MAGIC_CODE) {
// DebugLog(L"MAGIC_CODE %x", wParam);
goto next;
Expand Down
73 changes: 73 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,79 @@ class SendKeys {
std::vector<INPUT> inputs_;
};

template <typename... T>
void SendKey(T&&... keys) {
std::vector<typename std::common_type<T...>::type> keys_ = {
std::forward<T>(keys)...};
std::vector<INPUT> inputs{};
inputs.reserve(keys_.size() * 2);
for (auto& key : keys_) {
INPUT input = {0};
// 修正鼠标消息
switch (key) {
case VK_RBUTTON:
input.type = INPUT_MOUSE;
input.mi.dwFlags = ::GetSystemMetrics(SM_SWAPBUTTON) == TRUE
? MOUSEEVENTF_LEFTDOWN
: MOUSEEVENTF_RIGHTDOWN;
input.mi.dwExtraInfo = MAGIC_CODE;
break;
case VK_LBUTTON:
input.type = INPUT_MOUSE;
input.mi.dwFlags = ::GetSystemMetrics(SM_SWAPBUTTON) == TRUE
? MOUSEEVENTF_RIGHTDOWN
: MOUSEEVENTF_LEFTDOWN;
input.mi.dwExtraInfo = MAGIC_CODE;
break;
case VK_MBUTTON:
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
input.mi.dwExtraInfo = MAGIC_CODE;
break;
default:
input.type = INPUT_KEYBOARD;
input.ki.wVk = (WORD)key;
input.ki.dwExtraInfo = MAGIC_CODE;
break;
}
inputs.emplace_back(std::move(input));
}

for (auto& key = keys_.rbegin(); key != keys_.rend(); ++key) {
INPUT input = {0};
// 修正鼠标消息
switch (*key) {
case VK_RBUTTON:
input.type = INPUT_MOUSE;
input.mi.dwFlags = ::GetSystemMetrics(SM_SWAPBUTTON) == TRUE
? MOUSEEVENTF_LEFTUP
: MOUSEEVENTF_RIGHTUP;
input.mi.dwExtraInfo = MAGIC_CODE;
break;
case VK_LBUTTON:
input.type = INPUT_MOUSE;
input.mi.dwFlags = ::GetSystemMetrics(SM_SWAPBUTTON) == TRUE
? MOUSEEVENTF_RIGHTUP
: MOUSEEVENTF_LEFTUP;
input.mi.dwExtraInfo = MAGIC_CODE;
break;
case VK_MBUTTON:
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
input.mi.dwExtraInfo = MAGIC_CODE;
break;
default:
input.type = INPUT_KEYBOARD;
input.ki.dwFlags = KEYEVENTF_KEYUP;
input.ki.wVk = (WORD)(*key);
input.ki.dwExtraInfo = MAGIC_CODE;
break;
}
inputs.emplace_back(std::move(input));
}
::SendInput((UINT)inputs.size(), &inputs[0], sizeof(INPUT));
}

// Send a single key operation.
void SendOneMouse(int mouse) {
// Swap the left and right mouse buttons (if defined).
Expand Down

0 comments on commit 2d42777

Please sign in to comment.