在 messageboxa 中使用 sc_close [repicate] 禁用关闭按钮。

问题描述 投票:-1回答:1

我有这个问题已经有一段时间了。

在我的留言框里,我有一个取消按钮。我不想因为我的取消按钮而影响到关闭按钮,因为我的取消按钮会做一些事情,如果我按关闭按钮就不会发生。

我使用了一个循环和查找的技巧,但是当我打开一个和消息框标题相同的文件夹时,代码会禁用资源管理器的关闭按钮,这非常烦人。

我就是用这个方法来禁用关闭按钮,也会干扰其他有相同标题的窗口。

DWORD WINAPI CreateMessageBox(void *argr){
    *(int*)argr = MessageBoxA( NULL, 
        "Time is past active hours\nPlease save your work\nSystem is shutting down in 1 minute.\n", 
        "Warning", 
        MB_OKCANCEL|MB_ICONSTOP|MB_SYSTEMMODAL );

    return 0;
}
thread = CreateThread(NULL, 0, CreateMessageBox, &opt, 0, NULL);
while (!(msg = FindWindow(NULL, "Warning")));
style = GetWindowLongPtr(msg, GWL_STYLE);
SetWindowLongPtr(msg, GWL_STYLE, style & ~WS_SYSMENU);
WaitForSingleObject(thread, INFINITE);

但现在,我在某处读到有这样一个方法 SC_CLOSE 的东西,还可以禁用该窗口专用的关闭按钮。我该如何使用它呢?我看了一些关于它的帖子,但是没有一个帖子使用了 MessageBox() 而这只是压倒我。

拜托,谁能帮帮我?

c winapi
1个回答
1
投票

你的电话 FindWindow() 没有指定类名,因此它将找到 任何 具有匹配标题的顶层窗口。在你的例子中,是一个资源管理器窗口。为 MessageBox 窗口提供实际的类名,也就是 "#32770"例如

msg = FindWindow("#32770", "Warning")

然而,有一个更可靠的方法,不调用搜索窗口标题 - 摆脱对 CreateThread()FindWindow() 完全,而使调用 MessageBox() 就地取材 WH_CBT 勾通 SetWindowsHookEx() 赶上 HWNDMessageBox() 创建,然后你就可以根据需要操作该窗口,例如。

LRESULT CALLBACK MyCBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HCBT_CREATEWND)
    {
        ((CBT_CREATEWND*)lParam)->lpcs->style & ~WS_SYSMENU;
    }

    /* alternatively:
    if (nCode == HCBT_ACTIVATE)
    {
        HWND hwnd = (HWND)wParam;
        LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);
        SetWindowLongPtr(hwnd, GWL_STYLE, style & ~WS_SYSMENU);
    }
    */

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

...

HHOOK hHook = SetWindowsHookEx(WH_CBT, &MyCBTProc, NULL, GetCurrentThreadId());

opt = MessageBoxA(NULL,
    "Time is past active hours\nPlease save your work\nSystem is shutting down in 1 minute.\n",
    "Warning",
    MB_OKCANCEL|MB_ICONSTOP|MB_SYSTEMMODAL);

if (hHook)
    UnhookWindowsHookEx(hHook);

或者,简单地使用 TaskDialog()TaskDialogIndirect() 而不是 MessageBox(). A 任务对话 在标题栏中没有关闭按钮,除非你调用了 TaskDialogIndirect() 随着 TDF_ALLOW_DIALOG_CANCELLATION 标志。

表示应能使用Alt-F4、Escape关闭对话框。和标题栏的关闭按钮 即使没有指定取消按钮,也可以在 dwCommonButtonspButtons 委员们,

TaskDialog(NULL, NULL,
    L"Warning",
    L"Time is past active hours",
    L"Please save your work\nSystem is shutting down in 1 minute.",
    TDCBF_OK_BUTTON | TDCBF_CANCEL_BUTTON,
    TD_ERROR_ICON,
    &opt);
© www.soinside.com 2019 - 2024. All rights reserved.