6
votes

Désactiver l'icône de boutons X en haut de la droite dans MessageBox à l'aide de l'API C ++ Win32?

J'utilise l'API C ++ Win32 ...

J'ai une fenêtre Windowsbox contenir okcancel bouton ...

La messagerie de la messagerie a une fermeture de fermeture (bouton x) située sur le haut de droite ...

return1 = MessageBox (HDLG, texte ("Votre mot de passe sera expiré, vous devez modifier le mot de passe"), Texte ("Message de connexion"), MB_OK | MB_ICONInformation);

Je veux seulement fermer la messagerieBox à l'aide de la touche Annuler ...

Donc, je veux désactiver l'icône de bouton x ...

Je suis déjà essaie mb_iconmask mb_modemask quelque chose comme ça.

Mais je ne peux pas l'obtenir, ce dont j'ai besoin ...

Comment puis-je le résoudre?


2 commentaires

Le bouton X est un raccourci pour annuler. Ce n'est pas clair pourquoi vous voulez désactiver le X si vous autorisez toujours l'utilisateur à cliquer sur Annuler.


@Raymondchen, je suis d'accord. C'est un peu ce qui a motivé l'ouverture de ma réponse.


4 Réponses :


7
votes

Dans votre surinitdialog, vous pouvez essayer:

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)
{
//disable the X
pSysMenu->EnableMenuItem (SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
} 


1 commentaires

Pas ce que l'OP demandait, mais exactement ce que je cherchais, alors +1



3
votes

Il y a probablement un problème plus important au-delà de ce que vous avez donné, mais d'une manière de désactiver le bouton de fermeture consiste à définir le style de classe pour inclure cs_noclose code>, que vous pouvez faire avec une poignée de fenêtre et SetClassLongpTR code>. Considérez l'exemple complet suivant:

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


8 commentaires

@ Chris: Merci u, mais j'utilise Windows MessageBox ... je vais essayer cs_noclose à cette messageriebox.mébut il ne fonctionne pas ... return1 = Messagebox (HDLG, texte ("Votre Le mot de passe sera expiré, vous devez modifier le mot de passe "), Texte (" Message de connexion "), MB_OK | MB_ICONInformation); ... J'ai besoin de cette messagerie Masquer le bouton X-Fermer.


@Sanjumonu, j'ai mis à jour ma réponse. Vous pouvez choisir de ne pas lui donner un menu système, ce qui supprime efficacement le bouton de fermeture, plutôt que de la désactiver. Cela implique setwindowlongptr , par opposition à setclasslongptr .


@chris: Vous n'avez pas besoin d'utiliser un thread séparé pour trouver le message hwnd . Vous pouvez utiliser setwindowhookex () à la place pour installer un wh_cbt wh_cbt qui recherche la notification hcbt_creawnd .


@RemyleBeau, vous pourriez le faire aussi. Il convient de mentionner, mais cela ne convient pas à un court exemple.


@ Chris, @ Remy: J'utiliserai MB_YESNO au lieu de MB_OKCANCEL ... CS_NOCLOSE fonctionne bien ... Merci pour URS Aide. ..


Notez que cs_noclose affectera les boîtes de messages Tous tous les


@Raymondchen, très bon point. Je n'y pensais pas quand j'écris la réponse. Je suppose que c'est ce qui reproche beaucoup le comportement que j'aime lire.


FYI, Microsoft recommande d'appeler SetWindowpos après avoir appelé SetWindowLONGPTR : Certaines données de la fenêtre sont mises en cache, des modifications que vous apportez à l'aide de SetWindowLONGPTR ne prennent effet que lorsque vous appelez la fonction SetWindowowPos.



4
votes

Vous pouvez utiliser setwindowshookex () code> pour installer un wh_cbt code> wh_cbt coche pour obtenir le message code> hwnd code>, alors que vous pouvez le manipuler tout bien tu veux. Par exemple: xxx pré>

sur Windows Vista et ultérieurement, il existe une autre solution - utilisez TaskDialogindect () code> au lieu de MessageBox () Code>. Omission du tdf_allow_dialog_cancellation code> Drapeau du champ code> TaskDialogconfig.dwflags code> Désactivera le bouton X, ainsi que la touche d'échappement: P>

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


4 commentaires

Intéressant, je n'ai jamais su sur l'option Vista +. Un Nitpick: Si vous déclarez le rappel correctement, vous n'avez pas besoin de la jeter dans l'appel à SetwindowshookeX .


Alors quelle est la valeur du paramètre HDLG dans MessageBox ?


@ java.begginer Lire le Documentation .


Utilisez SetWindowshookeX bien sûr mieux que de créer un thread séparé. Utilisez également ici setwineventhook pour Event_Object_create . Je n'ayez que vérifier à l'intérieur du crochet que réinterpret_cast (LPCS-> lpszclass == makeintresource (32770) ou getclasslongw (hwnd, gcw_atom) == 32770 Parce que non une fenêtre unique sera créée



0
votes

Utilisez simplement cette fonction:

void DisableCloseButton(HWND hwnd)
{
    EnableMenuItem(GetSystemMenu(hwnd, FALSE), SC_CLOSE,
        MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
}


2 commentaires

Pouvez-vous expliquer comment cela est significativement différent de (ou mieux que) Cette réponse , posté il y a près de 8 ans?


Votre réponse pourrait être améliorée avec des informations justificatives supplémentaires. S'il vous plaît Modifier pour ajouter des détails supplémentaires, tels que des citations ou une documentation, de sorte que d'autres puissent confirmer que votre réponse est correcte. Vous pouvez trouver plus d'informations sur la façon d'écrire de bonnes réponses dans le centre d'aide .