【问题标题】:HCURSOR from another window, possible?来自另一个窗口的 HCURSOR,可能吗?
【发布时间】:2014-10-13 18:52:43
【问题描述】:

我正在我的窗口中寻找绘制 HCURSOR。光标必须是来自另一个窗口的真实光标 (HWND)。

这是我的代码:

GetCursorPos(&pos);
ScreenToClient(hwnd, &pos);
DrawIcon(hdcMemDC, pos.x, pos.y,GetCursor());

它在我的窗口上绘制了一个光标,但它不是“真正的”Windows 光标。例如,当我在另一个窗口上有一个手鼠标图标时,我的并没有改变。

所以我想知道是否可以处理来自指定窗口(HWND)的“真实”光标并绘制它。像GetCursorOf(hwnd, &myCursorInfo) 这样的东西会很酷。

【问题讨论】:

  • 所以当光标在别处时,您的窗口中必须有自己的光标?顺便说一句,GetCursor 的文档: 检索当前光标的句柄。要获取有关全局游标的信息,即使它不属于当前线程,请使用 GetCursorInfo。
  • 我的应用程序的目标是将一个窗口渲染到另一个窗口中。我必须将原始窗口的光标绘制到“复制”窗口中。但是如果我这样做GetCursorInfo(&a);/.../ DrawIcon(hdcMemDC, pos.x, pos.y,a.hCursor);,光标就不再绘制了。
  • 我感觉你在调用GetCursorInfo之前没有设置cbSize

标签: c++ windows cursor dwm


【解决方案1】:

此代码将获取任何窗口的光标。然后它将创建一个线程,并且该线程将不断地将光标绘制到我们的窗口上。

#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif

#include <tchar.h>
#include <windows.h>

DWORD WINAPI BltThreadProc(void *lpParam)
{
    while(true)
    {
        if (!IsIconic((HWND)lpParam)) //if our window isn't minimised, then we get the cursor and draw it.. Makes no sense drawing on a minimised window.
        {
            CURSORINFO Info = {0};
            Info.cbSize = sizeof(Info);
            GetCursorInfo(&Info);

            HDC hDC = GetDC((HWND)lpParam);
            DrawIconEx(hDC, 0, 0, Info.hCursor, 0, 0, 0, (HBRUSH)GetStockObject(COLOR_BACKGROUND), DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
            ReleaseDC((HWND)lpParam, hDC);
        }

        Sleep(1);
    }
    return 0;
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_CREATE:
        {
            CreateThread(NULL, 0, BltThreadProc, hwnd, 0, 0);
        }
        break;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
{
    HWND hwnd;
    MSG messages;
    WNDCLASSEX wincl;
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = _T("CLS");
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof(WNDCLASSEX);
    wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground = (HBRUSH)GetStockObject(COLOR_BACKGROUND);

    if (!RegisterClassEx (&wincl))
        return 0;

    hwnd = CreateWindowEx(0, _T("CLS"), _T("Title"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hThisInstance, NULL);
    ShowWindow(hwnd, nCmdShow);
    while (GetMessage(&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return messages.wParam;
}

【讨论】:

  • 只需使用DrawIconInfo.hCursor。它非常简单,而且有效:i.imgur.com/K7Zt3Tc.png
  • 我验证您的答案是该主题的解决方案,因为它包含正确的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多