[Solved] Show Yes/No messagebox where No is grayed out win32api C++ [closed]


Use SetWindowsHookEx() or SetWinEventHook() with a thread-local hook to capture the MessageBox() dialog’s HWND, then you can use EnableWindow() to disable the button.

Here is how to do it using SetWindowsHookEx():

HHOOK hHook = NULL;

LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if( nCode == HCBT_ACTIVATE )
    {
        HWND hDlg = (HWND) wParam;
        HWND hBtnWnd = GetDlgItem(hDlg, IDNO);
        if (hBtnWnd != NULL)
            EnableWindow(hBtnWnd, FALSE);
    }

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

{
    //...

    hHook = SetWindowsHookEx(WH_CBT, &CBTProc, NULL, GetCurrentThreadId());

    MessageBox(NULL, TEXT("Test"), TEXT("Test"), MB_YESNO);

    if (hHook != NULL)
        UnhookWindowsHookEx(hHook);

    //...
}

Here is how to do it using SetWinEventHook():

void CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
    if( event == EVENT_SYSTEM_DIALOGSTART )
    {
        HWND hBtnWnd = GetDlgItem(hwnd, IDNO);
        if (hBtnWnd != NULL)
            EnableWindow(hBtnWnd, FALSE);
    }
}

{
    //...

    HRESULT hRes = CoInitialize(NULL);

    HWINEVENTHOOK hHook = SetWinEventHook(EVENT_SYSTEM_DIALOGSTART, EVENT_SYSTEM_DIALOGSTART, NULL, &WinEventProc, GetCurrentProcessId(), GetCurrentThreadId(), WINEVENT_OUTOFCONTEXT);

    MessageBox(NULL, TEXT("Test"), TEXT("Test"), MB_YESNO);

    if (hHook != NULL)
        UnhookWinEvent(hHook);

    if (SUCCEEDED(hRes))
        CoUninitialize();

    //...
}

13

solved Show Yes/No messagebox where No is grayed out win32api C++ [closed]