Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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...

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

i only want to close the messagebox using the CANCEL Button...

So,i want to disable the X-Button Icon...

i am already try MB_ICONMASK MB_MODEMASK Somethink like that.

But i cant get it,what i need...

How can i Resolve it?

like image 283
Sanju Monu Avatar asked Nov 02 '12 05:11

Sanju Monu


3 Answers

In your OnInitDialog, you can try:

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)
{
//disable the X
pSysMenu->EnableMenuItem (SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
} 
like image 78
mots_g Avatar answered Nov 10 '22 03:11

mots_g


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;
}
like image 25
Remy Lebeau Avatar answered Nov 10 '22 03:11

Remy Lebeau


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
}
like image 3
chris Avatar answered Nov 10 '22 03:11

chris