From 9a5ac18da1977ee448169660d917cc98c654480f Mon Sep 17 00:00:00 2001 From: GaZaTu Date: Sat, 12 Mar 2022 21:17:55 +0100 Subject: [PATCH] windows support mvp --- src/EmojiPickerSettings.cpp | 6 +- src/crossdo.h | 159 ++++++++++++++++-------------------- 2 files changed, 76 insertions(+), 89 deletions(-) diff --git a/src/EmojiPickerSettings.cpp b/src/EmojiPickerSettings.cpp index 99f671c..17688cd 100644 --- a/src/EmojiPickerSettings.cpp +++ b/src/EmojiPickerSettings.cpp @@ -120,7 +120,7 @@ std::vector EmojiPickerSettings::recentEmojis() { recentEmojis = readQSettingsArrayToStdVector(*this, prefix, handler); } - return std::move(recentEmojis); + return recentEmojis; } void EmojiPickerSettings::setRecentEmojis(const std::vector& recentEmojis) { auto prefix = "recentEmojis"; @@ -354,7 +354,11 @@ void EmojiPickerSettings::setWindowOpacity(double windowOpacity) { } bool EmojiPickerSettings::swapEnterAndShiftEnter() const { +#ifdef __linux__ return value("swapEnterAndShiftEnter", false).toBool(); +#elif _WIN32 + return true; +#endif } void EmojiPickerSettings::setSwapEnterAndShiftEnter(bool swapEnterAndShiftEnter) { setValue("swapEnterAndShiftEnter", swapEnterAndShiftEnter); diff --git a/src/crossdo.h b/src/crossdo.h index 23902d9..2497087 100644 --- a/src/crossdo.h +++ b/src/crossdo.h @@ -1,11 +1,13 @@ #pragma once +#ifdef __linux__ #ifdef __cplusplus extern "C" { #endif - -#ifdef __linux__ #include "xdo.h" +#ifdef __cplusplus +} +#endif #elif _WIN32 #ifndef _WIN32_WINNT #define _WIN32_WINNT _WIN32_WINNT_WIN10 @@ -30,12 +32,12 @@ extern "C" { #define NOGDI 1 #define NOKERNEL 1 // #define NOUSER 1 -#define NONLS 1 +// #define NONLS 1 #define NOMB 1 #define NOMEMMGR 1 #define NOMETAFILE 1 #define NOMINMAX 1 -#define NOMSG 1 +// #define NOMSG 1 #define NOOPENFILE 1 #define NOSCROLL 1 #define NOSERVICE 1 @@ -53,6 +55,10 @@ extern "C" { // https://docs.microsoft.com/en-us/windows/win32/winprog/using-the-windows-headers #include "windows.h" #include "windowsx.h" +#include "ole2.h" +#include "oleacc.h" +#include "UIAutomation.h" +#include "stringapiset.h" #endif #ifdef __linux__ @@ -65,7 +71,8 @@ typedef HWND window_t; typedef xdo_t crossdo_t; #elif _WIN32 typedef struct { - int nothing; + IUIAutomation* ui_automation; + IUIAutomationElement* ui_element; } crossdo_t; #endif @@ -73,7 +80,15 @@ crossdo_t* crossdo_new() { #ifdef __linux__ return xdo_new(NULL); #elif _WIN32 - return (crossdo_t*)malloc(sizeof(crossdo_t)); + if (FAILED(CoInitialize(NULL))) { + printf("CoInitialize(...) failed"); + return NULL; + } + + crossdo_t* crossdo = (crossdo_t*)malloc(sizeof(crossdo_t)); + crossdo->ui_automation = NULL; + crossdo->ui_element = NULL; + return crossdo; #endif } @@ -82,11 +97,13 @@ void crossdo_free(crossdo_t* crossdo) { xdo_free(crossdo); #elif _WIN32 free(crossdo); + + CoUninitialize(); #endif } int crossdo_get_mouse_location2( - const crossdo_t* crossdo, int* x_ret, int* y_ret, int* screen_num_ret, window_t* window_ret) { + crossdo_t* crossdo, int* x_ret, int* y_ret, int* screen_num_ret, window_t* window_ret) { #ifdef __linux__ return xdo_get_mouse_location2(crossdo, x_ret, y_ret, screen_num_ret, window_ret); #elif _WIN32 @@ -110,7 +127,7 @@ int crossdo_get_mouse_location2( } int crossdo_get_caret_location2( - const crossdo_t* crossdo, int* x_ret, int* y_ret, int* screen_num_ret, window_t* window_ret) { + crossdo_t* crossdo, int* x_ret, int* y_ret, int* screen_num_ret, window_t* window_ret) { #ifdef __linux__ *x_ret = 0; *y_ret = 0; @@ -128,7 +145,7 @@ int crossdo_get_caret_location2( #endif } -int crossdo_get_pid_window(const crossdo_t* crossdo, window_t window) { +int crossdo_get_pid_window(crossdo_t* crossdo, window_t window) { #ifdef __linux__ return xdo_get_pid_window(crossdo, window); #elif _WIN32 @@ -139,124 +156,90 @@ int crossdo_get_pid_window(const crossdo_t* crossdo, window_t window) { #endif } -int crossdo_get_active_window(const crossdo_t* crossdo, window_t* window_ret) { +int crossdo_get_active_window(crossdo_t* crossdo, window_t* window_ret) { #ifdef __linux__ return xdo_get_active_window(crossdo, window_ret); #elif _WIN32 *window_ret = GetForegroundWindow(); + if (crossdo->ui_element == NULL) { + if (FAILED(CoCreateInstance( + __uuidof(CUIAutomation8), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&crossdo->ui_automation)))) { + printf("CoCreateInstance(__uuidof(CUIAutomation8), ...) failed"); + return -1; + } + + if (FAILED(crossdo->ui_automation->GetFocusedElement(&crossdo->ui_element))) { + printf("ui_automation->GetFocusedElement(...) failed"); + return -1; + } + } + return 0; #endif } -int crossdo_activate_window(const crossdo_t* crossdo, window_t window) { +int crossdo_activate_window(crossdo_t* crossdo, window_t window) { #ifdef __linux__ return xdo_activate_window(crossdo, window); #elif _WIN32 - window_t current_window = GetForegroundWindow(); - - unsigned long process_thread = GetProcessId(); - unsigned long current_thread = GetWindowThreadProcessId(current_window, NULL); - unsigned long window_thread = GetWindowThreadProcessId(window, NULL); - - if (process_thread == current_thread && process_thread != window_thread) { - AttachThreadInput(window_thread, process_thread, TRUE); - } - - SetActiveWindow(window); - - if (process_thread == window_thread && process_thread != current_thread) { - AttachThreadInput(current_thread, process_thread, FALSE); - } - return 0; #endif } -int crossdo_wait_for_window_active(const crossdo_t* crossdo, window_t window, int active) { +int crossdo_wait_for_window_active(crossdo_t* crossdo, window_t window, int active) { #ifdef __linux__ return xdo_wait_for_window_active(crossdo, window, active); #elif _WIN32 - Sleep(25); - return 0; #endif } -int crossdo_enter_text_window(const crossdo_t* crossdo, window_t window, const char* string, unsigned int delay) { +int crossdo_enter_text_window(crossdo_t* crossdo, window_t window, const char* string, unsigned int delay) { #ifdef __linux__ return xdo_enter_text_window(crossdo, window, string, delay); #elif _WIN32 - // string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - size_t input_len = strlen(string) * 2; - INPUT* input = (INPUT*)malloc(sizeof(INPUT) * input_len); - - window_t current_window = GetForegroundWindow(); - unsigned long current_thread = GetWindowThreadProcessId(current_window, NULL); - unsigned long window_thread = GetWindowThreadProcessId(window, NULL); - - AttachThreadInput(window_thread, current_thread, TRUE); - - // SetActiveWindow(window); - - for (int i = 0; i < (input_len / 2); i++) { - INPUT* down = &input[(i * 2) + 0]; - INPUT* up = &input[(i * 2) + 1]; - - down->type = INPUT_KEYBOARD; - down->ki.wScan = string[i]; - down->ki.time = 0; - down->ki.dwExtraInfo = NULL; - down->ki.wVk = 0; - down->ki.dwFlags = KEYEVENTF_UNICODE | 0; - - up->type = INPUT_KEYBOARD; - up->ki.wScan = string[i]; - up->ki.time = 0; - up->ki.dwExtraInfo = NULL; - up->ki.wVk = 0; - up->ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; - - // INPUT input[2]; - - // input[0].type = INPUT_KEYBOARD; - // input[0].ki.wScan = string[i]; - // input[0].ki.time = 0; - // input[0].ki.dwExtraInfo = NULL; - // input[0].ki.wVk = 0; - // input[0].ki.dwFlags = KEYEVENTF_UNICODE | 0; - - // input[1].type = INPUT_KEYBOARD; - // input[1].ki.wScan = string[i]; - // input[1].ki.time = 0; - // input[1].ki.dwExtraInfo = NULL; - // input[1].ki.wVk = 0; - // input[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; - - // SendInput(2, input, sizeof(INPUT)); + IUnknown* value_pattern_tmp; + if (FAILED(crossdo->ui_element->GetCurrentPattern(UIA_ValuePatternId, &value_pattern_tmp))) { + printf("ui_element->GetCurrentPattern(UIA_ValuePatternId, ...) failed"); + return -1; } - SendInput(input_len, input, sizeof(INPUT)); + IUIAutomationValuePattern* value_pattern = (IUIAutomationValuePattern*)value_pattern_tmp; - SetActiveWindow(current_window); + BSTR current_bstr; + if (FAILED(value_pattern->get_CurrentValue(¤t_bstr))) { + printf("value_pattern->get_CurrentValue(...) failed"); + return -1; + } + int current_wslen = SysStringLen(current_bstr); - AttachThreadInput(window_thread, current_thread, FALSE); + int string_wslen = MultiByteToWideChar(CP_UTF8, 0, string, strlen(string), 0, 0); + BSTR string_bstr = SysAllocStringLen(0, string_wslen); + MultiByteToWideChar(CP_UTF8, 0, string, strlen(string), string_bstr, string_wslen); - free(input); + BSTR new_bstr = SysAllocStringLen(NULL, current_wslen + string_wslen); + memcpy(new_bstr, current_bstr, current_wslen * sizeof(OLECHAR)); + memcpy(new_bstr + current_wslen, string_bstr, string_wslen * sizeof(OLECHAR)); + new_bstr[current_wslen + string_wslen] = NULL; + + if (FAILED(value_pattern->SetValue(new_bstr))) { + printf("value_pattern->SetValue(...) failed"); + return -1; + } + + SysFreeString(new_bstr); + SysFreeString(string_bstr); + SysFreeString(current_bstr); return 0; #endif } -int crossdo_send_keysequence_window(const crossdo_t* crossdo, window_t window, const char* keysequence, unsigned int delay) { +int crossdo_send_keysequence_window(crossdo_t* crossdo, window_t window, const char* keysequence, unsigned int delay) { #ifdef __linux__ return xdo_send_keysequence_window(crossdo, window, keysequence, delay); #elif _WIN32 return 0; #endif } - -#ifdef __cplusplus -} -#endif