Disable X-Button Icon on the top of the right in Messagebox Using C++ Win32 API?

后端 未结 3 869
一向
一向 2020-12-15 13:30

i am using C++ win32 API...

i have a Windows messagebox contain OKCANCEL Button...

the messagebox have a close(X-Button) on the right top...

相关标签:
3条回答
  • 2020-12-15 13:33

    There's most likely a bigger problem beyond what you've given us, but one way to disable the close button is to set the class style to include CS_NOCLOSE, which you can do with a window handle and SetClassLongPtr. Consider the following full example:

    #include <windows.h>
    
    DWORD WINAPI CreateMessageBox(void *) { //threaded so we can still work with it
        MessageBox(nullptr, "Message", "Title", MB_OKCANCEL);
        return 0;
    }
    
    int main() {
        HANDLE thread = CreateThread(nullptr, 0, CreateMessageBox, nullptr, 0, nullptr);
    
        HWND msg;
        while (!(msg = FindWindow(nullptr, "Title"))); //The Ex version works well for you
    
        LONG_PTR style = GetWindowLongPtr(msg, GWL_STYLE); //get current style
        SetWindowLongPtr(msg, GWL_STYLE, style & ~WS_SYSMENU); //remove system menu 
    
        WaitForSingleObject(thread, INFINITE); //view the effects until you close it
    }
    
    0 讨论(0)
  • 2020-12-15 13:46

    In your OnInitDialog, you can try:

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    
    if (pSysMenu != NULL)
    {
    //disable the X
    pSysMenu->EnableMenuItem (SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
    } 
    
    0 讨论(0)
  • 2020-12-15 13:52

    You can use SetWindowsHookEx() to install a thread-specific WH_CBT hook to obtain the MessageBox's HWND, then you can manipulate it any way you want. For example:

    HHOOK hHook = NULL;
    
    LRESULT CALLBACK CBTHookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if (nCode == HCBT_CREATEWND)
        {
            HWND hMsgBox = (HWND) wParam;
            LONG_PTR style = GetWindowLongPtr(hMsgBox, GWL_STYLE);
            SetWindowLongPtr(hMsgBox, GWL_STYLE, style & ~WS_SYSMENU);
        }
    
        return CallNextHookEx(hHook, nCode, wParam, lParam);
    }
    
    int WarnAboutPasswordChange(HWND hDlg)
    {
        hHook = SetWindowsHookEx(WH_CBT, (HOOKPROC)CBTHookProc, NULL, GetCurrentThreadId());
    
        int retun1 = MessageBox(hDlg, TEXT("Your password will expired, you must change the password"), TEXT("Logon Message"), MB_OK | MB_ICONINFORMATION);
    
        if (hHook)
        {
            UnhookWindowsHookEx(hHook);
            hHook = NULL;
        }
    
        return retun1;
    }
    

    On Windows Vista and later, there is another solution - use TaskDialogIndirect() instead of MessageBox(). Omitting the TDF_ALLOW_DIALOG_CANCELLATION flag from the TASKDIALOGCONFIG.dwFlags field will disable the X button, as well as the Escape key:

    int WarnAboutPasswordChange(HWND hDlg)
    {
        TASKDIALOGCONFIG config = {0};
        config.cbSize = sizeof(config);
        config.hwndParent = hDlg;
        config.dwCommonButtons = TDCBF_OK_BUTTON;
        config.pszWindowTitle = L"Logon Message";
        config.pszMainInstruction = L"Your password will expired, you must change the password";
        config.pszMainIcon = TD_INFORMATION_ICON;
        config.nDefaultButton = IDOK;
    
        int retun1 = 0;
        TaskDialogIndirect(&config, &retun1, NULL, NULL);
    
        return retun1;
    }
    
    0 讨论(0)
提交回复
热议问题