How can to change cursor for MessageBox()? WinAPI, C++ (23)

148 views Asked by At

I use:

MessageBox(nullptr, "Hello, World!", "Test", MB_OK);

But I need to use SetCursor function (my abstract task).

For example:

SetCursor(LoadCursor(nullptr, IDC_NO));

Is it possible for MessageBox?

Or any primitive implementation with a window will do...

1

There are 1 answers

5
RbMm On

If you need more functional than what the MessageBox provides, it's way simpler to use DialogBoxParam. However, if want do this exactly with MessageBox, you could use SetWindowsHookExW to take control inside MessageBox call and then subclass its window.

class __declspec(novtable) SubClsWnd
{
    static LRESULT CALLBACK s_MySubclassProc(
        HWND hWnd,
        UINT uMsg,
        WPARAM wParam,
        LPARAM lParam,
        UINT_PTR uIdSubclass,
        DWORD_PTR dwRefData
        )
    {
        return reinterpret_cast<SubClsWnd*>(dwRefData)->MySubclassProc(hWnd, uMsg, wParam, lParam, uIdSubclass);
    }

protected:
    virtual LRESULT CALLBACK MySubclassProc(HWND hWnd,
        UINT uMsg,
        WPARAM wParam,
        LPARAM lParam,
        UINT_PTR uIdSubclass) = 0;

public:

    BOOL SetSubclass(_In_ HWND hwnd, _In_ UINT_PTR uIdSubclass)
    {
        return SetWindowSubclass(hwnd, s_MySubclassProc, uIdSubclass, (ULONG_PTR)this);
    }

    BOOL RemoveSubclass(_In_ HWND hwnd, _In_ UINT_PTR uIdSubclass)
    {
        return RemoveWindowSubclass(hwnd, s_MySubclassProc, uIdSubclass);
    }
};

class CDemo : public SubClsWnd
{
    HCURSOR _M_hc = 0;


    virtual LRESULT CALLBACK MySubclassProc(HWND hWnd,
        UINT uMsg,
        WPARAM wParam,
        LPARAM lParam,
        UINT_PTR uIdSubclass)
    {
        switch (uMsg)
        {
        case WM_SETCURSOR:
            SetCursor(_M_hc);
            return TRUE;

        case WM_NCDESTROY:
            RemoveSubclass(hWnd, uIdSubclass);
            delete this;
            break;
        }

        return DefSubclassProc(hWnd, uMsg, wParam, lParam);
    }

public:
    ~CDemo()
    {
        if (_M_hc) DestroyCursor(_M_hc);
    }

    BOOL Init()
    {
        return 0 != (_M_hc = LoadCursorW(0, IDC_SIZEALL));
    }
};

LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam )
{
    if (nCode == HCBT_CREATEWND)
    {
        CBT_CREATEWND* pccw = reinterpret_cast<CBT_CREATEWND*>(lParam);

        if (pccw->lpcs->lpszClass == WC_DIALOG)
        {
            if (CDemo* p = new CDemo)
            {
                if (!p->Init() || !p->SetSubclass((HWND)wParam, 0))
                {
                    delete p;
                }

            }
        }
    }

    return CallNextHookEx(0, nCode, wParam, lParam);
}

///////////////////////////////////////////////////////////////////
if (HHOOK hhk = SetWindowsHookExW(WH_CBT, CBTProc, 0, GetCurrentThreadId()))
{
    MessageBoxW(0,0,0,MB_ICONINFORMATION);
    UnhookWindowsHookEx(hhk);
}