当前位置: 首页> 教育> 锐评 > 设计网站如何融入非关系数据库_上海网站建设技术托管_网络推广推广培训_厦门seo排名优化公司

设计网站如何融入非关系数据库_上海网站建设技术托管_网络推广推广培训_厦门seo排名优化公司

时间:2025/7/16 23:40:47来源:https://blog.csdn.net/liulun/article/details/146947539 浏览次数:0次
设计网站如何融入非关系数据库_上海网站建设技术托管_网络推广推广培训_厦门seo排名优化公司

注册鼠标钩子

// 注册鼠标钩子
HHOOK hMouseHook;
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, GetModuleHandle(NULL), 0);// 取消鼠标钩子
UnhookWindowsHookEx(hMouseHook);
hMouseHook = nullptr;

上述代码中MouseProc方法用于处理系统的鼠标消息

处理鼠标消息

LRESULT MouseHook::MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{static QPoint pos;static qint64 lastTriggerTime = 0;if (nCode >= 0) {if (wParam == WM_LBUTTONDOWN) {pos = QCursor::pos();           }else if (wParam == WM_LBUTTONUP) {if (pos != QCursor::pos()) {timer->start(280);  //拖拽}qint64 currentTime = QDateTime::currentMSecsSinceEpoch();if (currentTime - lastTriggerTime <= 500) {timer->start(280); //双击}lastTriggerTime = currentTime;}}return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}

这段代码中,我们使用一个QTimer来处理双击或拖拽选中文本的操作。

文本选中后的处理方法

void MouseHook::processMouseUp()
{auto textGetter = new TextGetter(this);connect(textGetter, &TextGetter::resultReady, this, &MouseHook::onTextReady, Qt::ConnectionType::QueuedConnection);textGetter->start();
}

TextGetter是一个继承自QThread的类,我们将在一个新线程中去获取用户选中的文本。

获取选中文本的第一种情况

QString TextGetter::getSelectedTextByUIAutomation() {try {auto hr = CoInitialize(NULL);if (FAILED(hr)){CoUninitialize();return "";}CComPtr<IUIAutomation> automation;hr = CoCreateInstance(CLSID_CUIAutomation, nullptr, CLSCTX_INPROC_SERVER, IID_IUIAutomation,(void**)(&automation));if (FAILED(hr)){CoUninitialize();return "";}CComPtr<IUIAutomationElement> focusedElement;hr = automation->GetFocusedElement(&focusedElement);if (FAILED(hr) || !focusedElement){CoUninitialize();return "";}CComPtr<IUIAutomationTextPattern> textPattern;hr = focusedElement->GetCurrentPatternAs(UIA_TextPatternId, IID_PPV_ARGS(&textPattern));if (FAILED(hr) || !textPattern){CoUninitialize();return "";}CComPtr<IUIAutomationTextRangeArray> selection;hr = textPattern->GetSelection(&selection);if (FAILED(hr) || !selection){CoUninitialize();return "";}CComPtr<IUIAutomationTextRange> range;hr = selection->GetElement(0, &range);if (FAILED(hr) || !range){ CoUninitialize();return "";}CComBSTR text;range->GetText(-1, &text);std::wstring ws(text, SysStringLen(text));CoUninitialize();return QString::fromStdWString(ws);}catch (std::exception& e) {return "";}       
}

这段代码使用 Microsoft UI Automation (UIA) API 从当前具有焦点的 UI 元素中获取选中文本的方法。但有的时候这种方法获取不到想要的文本(老式窗口中的文本)

获取选中文本的第二种情况

当第一种情况获取到的文本是空时,就要尝试第二种情况

auto hwnd = getCurrentHwnd();
if (!hwnd) {return "";
}
auto cache = cacheClipboard();
sendCtrlC();
str = getClipboardText();
if (str.isEmpty()) {CloseClipboard();return "";
}
restoreClipboard(cache);
CloseClipboard();

这种情况,先获取系统当前聚焦的窗口,然后缓存当前剪切板,然后发送Ctrl+C复制此窗口选中的文本,然后获取剪切板内的文本,然后把之前缓存的内容存入剪切板。

下面我们看看这些实现代码:

获取系统当前聚焦的窗口

HWND TextGetter::getCurrentHwnd()
{HWND hwnd = GetForegroundWindow();DWORD threadId = GetWindowThreadProcessId(hwnd, NULL);AttachThreadInput(GetCurrentThreadId(), threadId, TRUE);hwnd = GetFocus();AttachThreadInput(GetCurrentThreadId(), threadId, FALSE);POINT pt;GetCursorPos(&pt);RECT rect;GetWindowRect(hwnd, &rect);if (pt.x<rect.left || pt.y<rect.top || pt.x>rect.right || pt.y>rect.bottom) {return nullptr;}return hwnd;
}

如果聚焦的窗口与鼠标所在位置的窗口不是一个窗口,那么我们取消任务。

缓存剪切板的内容

ClipboardData TextGetter::cacheClipboard()
{OpenClipboard(nullptr);ClipboardData cache;UINT format = 0;while ((format = EnumClipboardFormats(format)) != 0) {HANDLE hData = GetClipboardData(format);if (hData) {SIZE_T size = GlobalSize(hData);HGLOBAL hCopy = GlobalAlloc(GMEM_MOVEABLE, size);if (hCopy) {void* pDest = GlobalLock(hCopy);void* pSource = GlobalLock(hData);if (pDest && pSource) {memcpy(pDest, pSource, size);}GlobalUnlock(hData);GlobalUnlock(hCopy);cache.push_back({ format, hCopy });}}}EmptyClipboard();CloseClipboard();return cache;
}

发送Ctrl+C按键消息

void TextGetter::sendCtrlC()
{INPUT inputs[4] = { 0 };inputs[0].type = INPUT_KEYBOARD;inputs[0].ki.wVk = VK_CONTROL;inputs[1].type = INPUT_KEYBOARD;inputs[1].ki.wVk = 'C';inputs[2].type = INPUT_KEYBOARD;inputs[2].ki.wVk = 'C';inputs[2].ki.dwFlags = KEYEVENTF_KEYUP;inputs[3].type = INPUT_KEYBOARD;inputs[3].ki.wVk = VK_CONTROL;inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));QThread::msleep(360);
}

按键发送成功后需要等待360毫秒

获取剪切板的内容

QString TextGetter::getClipboardText()
{OpenClipboard(nullptr);if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) {CloseClipboard();return "";}HANDLE hData = GetClipboardData(CF_UNICODETEXT);if (hData == nullptr) {CloseClipboard();return "";}LPCWSTR pText = static_cast<LPCWSTR>(GlobalLock(hData));if (pText == nullptr) {CloseClipboard();return "";}QString result = QString::fromWCharArray(pText);GlobalUnlock(hData);CloseClipboard();return result;
}

不要怀疑发送按键Ctrl+C这个方案是否可行,有道词典就是这么干的。

关键字:设计网站如何融入非关系数据库_上海网站建设技术托管_网络推广推广培训_厦门seo排名优化公司

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: