#include "define.h" bool tryopenclipboard(HWND hwnd = 0) { bool success = false; for (int i = 0; i < 50; i++) { if (OpenClipboard(hwnd)) { success = true; break; } else { Sleep(10); } } return success; } std::optional clipboard_get_internal() { std::optional data = {}; if (tryopenclipboard() == false) return {}; do { HANDLE hData = GetClipboardData(CF_UNICODETEXT); if (hData == 0) break; LPWSTR pszText = static_cast(GlobalLock(hData)); if (pszText == 0) break; int sz = GlobalSize(hData); data = std::move(std::wstring(pszText, sz)); GlobalUnlock(hData); } while (false); CloseClipboard(); return data; } bool clipboard_get(void (*cb)(const wchar_t *)) { auto data = std::move(clipboard_get_internal()); if (!data) return false; cb(data.value().c_str()); return true; } bool clipboard_set(HWND hwnd, wchar_t *text) { bool success = false; // static HWND hwnd=CreateWindowExA(0,"STATIC",0,0,0,0,0,0,0,0,0,0); if (tryopenclipboard(hwnd) == false) return false; EmptyClipboard(); do { HGLOBAL hClipboardData; size_t len = wcslen(text) + 1; hClipboardData = GlobalAlloc(GMEM_MOVEABLE, len * sizeof(wchar_t)); if (hClipboardData == 0) break; auto pchData = (wchar_t *)GlobalLock(hClipboardData); if (pchData == 0) break; wcscpy_s(pchData, len, text); GlobalUnlock(hClipboardData); SetClipboardData(CF_UNICODETEXT, hClipboardData); success = true; } while (false); CloseClipboard(); return success; } static void clipboard_callback_1(void (*callback)(const wchar_t *, bool), HANDLE hsema, HWND *hwnd) { const wchar_t CLASS_NAME[] = L"LunaClipboardListener"; WNDCLASS wc = {}; wc.lpfnWndProc = [](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { if (WM_CLIPBOARDUPDATE == message) { auto data = clipboard_get_internal(); auto callback_ = reinterpret_cast(GetWindowLongPtrW(hWnd, GWLP_USERDATA)); if (data && callback_) { auto ohwnd = GetClipboardOwner(); DWORD pid; GetWindowThreadProcessId(ohwnd, &pid); callback_(data.value().c_str(), pid == GetCurrentProcessId()); } } return DefWindowProc(hWnd, message, wParam, lParam); }; wc.hInstance = GetModuleHandle(0); wc.lpszClassName = CLASS_NAME; static auto _ = RegisterClass(&wc); HWND hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, CLASS_NAME, CLASS_NAME, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(0), 0); SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)callback); *hwnd = hWnd; ReleaseSemaphore(hsema, 1, 0); MSG msg = {}; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } } DECLARE HWND clipboard_callback(void (*callback)(const wchar_t *, bool)) { HANDLE hsema = CreateSemaphoreW(0, 0, 10, 0); HWND hwnd; std::thread(std::bind(clipboard_callback_1, callback, hsema, &hwnd)).detach(); WaitForSingleObject(hsema, INFINITE); CloseHandle(hsema); if (AddClipboardFormatListener(hwnd)) return hwnd; else return NULL; } DECLARE void clipboard_callback_stop(HWND hwnd) { if (!hwnd) return; RemoveClipboardFormatListener(hwnd); DestroyWindow(hwnd); }