6

我正在使用 C++ win32 API ...

我有一个包含OKCANCEL按钮的 Windows 消息框...

消息框的右上角有一个关闭(X 按钮)...

retun1=MessageBox(hDlg,TEXT("Your password will expired,you must change the password"),TEXT("Logon Message"),MB_OK | MB_ICONINFORMATION);

我只想使用CANCEL按钮关闭消息框...

所以,我想禁用 X 按钮图标...

我已经在尝试MB_ICONMASK MB_MODEMASK这样的 Somethink 了。

但我无法得到它,我需要什么...

我该如何解决?

4

4 回答 4

7

在您的 OnInitDialog 中,您可以尝试:

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)
{
//disable the X
pSysMenu->EnableMenuItem (SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
} 
于 2012-11-02T05:34:22.213 回答
4

您可以使用SetWindowsHookEx()安装特定于线程的WH_CBT钩子来获取 MessageBox HWND,然后您可以以任何您想要的方式操作它。例如:

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;
}

在 Windows Vista 及更高版本上,还有另一种解决方案 - 使用TaskDialogIndirect()而不是MessageBox(). 从字段中省略TDF_ALLOW_DIALOG_CANCELLATION标志TASKDIALOGCONFIG.dwFlags将禁用 X 按钮以及 Escape 键:

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;
}
于 2012-11-02T07:41:19.440 回答
3

除了您给我们的问题之外,很可能还有一个更大的问题,但是禁用关闭按钮的一种方法是将类样式设置为 include CS_NOCLOSE,您可以使用窗口句柄和SetClassLongPtr. 考虑以下完整示例:

#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
}
于 2012-11-02T05:39:03.503 回答
0

只需使用此功能:

void DisableCloseButton(HWND hwnd)
{
    EnableMenuItem(GetSystemMenu(hwnd, FALSE), SC_CLOSE,
        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
}
于 2021-09-13T21:02:27.643 回答