Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw mouse cursor

I'm trying to simulate a mouse cursor in Win32 forms. On every WM_MOUSEMOVE I have

hCursor = LoadCursor(NULL, IDC_ARROW);
////Get device context
hDeviceContext = GetDC(hwnd);
hDCMem = CreateCompatibleDC(hDeviceContext);
hBitmap = CreateCompatibleBitmap(hDCMem, 50, 50);
hbmOld = SelectObject(hDCMem, hBitmap);
DrawIcon(hDCMem, x, y, hCursor);
SelectObject(hDCMem, hbmOld);

But I don't see anything being drawn. However if I drew directly on the DC:

DrawIcon(hDeviceContext, x, y, hCursor);

I do see the cursor but it does not erase the image as I move the cursor, leaving a long tail behind.

like image 398
dave Avatar asked Feb 20 '23 09:02

dave


1 Answers

Don't paint in WM_MOUSEMOVE, that's what WM_PAINT is for. Basically, you need to handle three messages:

    case WM_CREATE:
        hCursor = LoadCursor(NULL, IDC_ARROW);
        cWidth  = GetSystemMetrics(SM_CXCURSOR); // saving the cursor dimensions
        cHeight = GetSystemMetrics(SM_CYCURSOR);
    break;

    case WM_MOUSEMOVE:
        rcOld = rcNew;
        rcNew.left   = GET_X_LPARAM(lParam);     // saving the mouse coordinates
        rcNew.top    = GET_Y_LPARAM(lParam);
        rcNew.right  = rcNew.left + cWidth;
        rcNew.bottom = rcNew.top + cHeight;
        InvalidateRect(hwnd, &rcOld, TRUE);      // asking to redraw the rectangles
        InvalidateRect(hwnd, &rcNew, TRUE);
        UpdateWindow(hwnd);
    break;

    case WM_PAINT:
        hDC = BeginPaint(hwnd, &ps);
        DrawIcon(hDC, rcNew.left, rcNew.top, hCursor);
        EndPaint(hwnd, &ps);
    break;

Note: I'm not sure what do you mean by "simulating a mouse cursor", but there could be a better way of doing what you probably want. Please check functions SetCursor() and SetWindowLongPtr() with GCL_HCURSOR.

like image 192
Joulukuusi Avatar answered Feb 25 '23 00:02

Joulukuusi