Message box with cancel button only

后端 未结 3 887
半阙折子戏
半阙折子戏 2021-01-15 05:36

Can we have a message box with cancel button only ? If so , any hints ? Is there a built in api method to get only messagebox with cancel button alone/

How to create

3条回答
  •  一整个雨季
    2021-01-15 06:11

    You can use a thread-local CBT hook via SetWindowsHookEx() to customize the MessageBox() dialog however you want.

    For instance, you can change the text of the "OK" button to say "Cancel" instead, eg:

    HHOOK hHook = NULL;
    
    LRESULT CALLBACK CBTHookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if (nCode < 0)
            return CallNextHookEx(hHook, nCode, wParam, lParam);
    
        if (nCode == HCBT_ACTIVATE)
        {
            HWND hWnd = reinterpret_cast(wParam);
            SetWindowText(GetDlgItem(hWnd, IDOK), TEXT("Cancel"));
            return 0;
        }
    
        return CallNextHookEx(hHook, nCode, wParam, lParam);
    }
    
    {
        ...
        hHook = SetWindowsHookEx(WH_CBT, reinterpret_cast(&CBTHookProc), NULL, GetCurrentThreadId());
        int iResult = MessageBox(..., MB_OK);
        if (iResult == IDOK) iResult = IDCANCEL;
        UnhookWindowsHookEx(hHook);
        ...
    }
    

    Or you can hide the standard "OK" button and let the dialog still use its native "Cancel" button:

    HHOOK hHook = NULL;
    
    LRESULT CALLBACK CBTHookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if (nCode < 0)
            return CallNextHookEx(hHook, nCode, wParam, lParam);
    
        if (nCode == HCBT_ACTIVATE)
        {
            HWND hWnd = reinterpret_cast(wParam);
            ShowWindow(GetDlgItem(hWnd, IDOK), SW_HIDE);
            // optionally reposition the IDCANCEL child window as well....
            return 0;
        }
    
        return CallNextHookEx(hHook, nCode, wParam, lParam);
    }
    
    {
        ...
        hHook = SetWindowsHookEx(WH_CBT, reinterpret_cast(&CBTHookProc), NULL, GetCurrentThreadId());
        int iResult = MessageBox(..., MB_OKCANCEL);
        UnhookWindowsHookEx(hHook);
        ...
    }
    

    Update: on Vista and later, you can (and should) use TaskDialog() or TaskDialogIndirect() instead of MessageBox(). Task dialogs are much more flexible, including the ability to let you specify which buttons are on the dialog, and even use custom buttons. So you can easily display a Cancel-only dialog without using any hooks at all, eg:

    TaskDialog(..., TDCBF_CANCEL_BUTTON, ..., &iResult);
    

    TASKDIALOGCONFIG TaskConfig = {0};
    TaskConfig.cbSize = sizeof(TaskConfig);
    TaskConfig.dwCommonButtons = TDCBF_CANCEL_BUTTON;
    ...
    TaskDialogIndirect(&TaskConfig, &iResult, ...);
    

提交回复
热议问题