2010-02-27 5 views
2

J'ai fait une application MFC, et maintenant je veux désactiver le bouton de fermeture de la fenêtre pendant que je fais mes opérations de copie. Je l'ai fait RÉUSSI avec ce code:Comment utiliser CMenu dans une application MFC?

BOOL bEnable = FALSE; // To disable 

UINT menuf = bEnable ? (MF_BYCOMMAND) : (MF_BYCOMMAND | MF_GRAYED | MF_DISABLED); 

CMenu* pSM = GetSystemMenu( , FALSE); 
if (pSM) 
{ 
    pSM->EnableMenuItem(SC_CLOSE, menuf); 
} 

Mais maintenant, à la fin de mon programme dans mon fil (UINT CopyThread (LPVOID pParam)) je veux le réactiver, mais je ne peux pas. J'ai passé plus tôt à mon thread le m_hWnd, et maintenant je ne vais pas passer à la fonction GetSystemMenu mais j'obtiens une erreur de compilation: erreur C2440: 'initializing': impossible de convertir 'HMENU' en 'CMenu *'. Je suis sûr que c'est une question facile, mais je suis un débutant, alors s'il vous plaît aider, mais je ne peux pas comprendre, ce que je fais usé!

Merci d'avance!

Kampi

Mise à jour: J'ai essayé de cette façon, qui fonctionne presque. Le Close "X" sera à nouveau noir, mais si j'appuie dessus, mon programme n'existe pas. Est-ce que je fais quelque chose de mal, ou c'est parce que quelque chose d'autre?

BOOL bEnable = TRUE;  // To enable 
UINT menuf = bEnable ? (MF_BYCOMMAND) : (MF_BYCOMMAND | MF_GRAYED | MF_DISABLED); 

HMENU pSM = ::GetSystemMenu(Test->hWnd, FALSE); 
if (pSM) 
{ 
    ::EnableMenuItem(pSM, SC_CLOSE, menuf); 
} 

Répondre

2
  1. Il est un moyen facile de désactiver le menu 'fermer' dans le système. S'il vous plaît ajouter le bit de CS_NOCLOSE dans le style de classe. Vous pouvez changer le style de classe en utilisant SetClassLong. Pourquoi n'utilisez-vous pas simplement l'API Win32, pas la fonction MFC? Par exemple, utilisez simplement ::GetSystemMenu qui renvoie HMENU. En général, vous pouvez créer CMenu à partir du HMENU par CMenu::FromHandle, mais dans un tel cas, il est préférable d'utiliser directement l'API Win32.

S'il vous plaît noter que la correspondance entre les objets MFC (par exemple, CMenu, CWnd) et poignées Win32 (par exemple, HMENU, HWND) est somewhat complex. La raison pour laquelle je l'ai dit complexe est qu'il existe deux types de cartographie: temporelle et permanente. Si vous faites CMenu en appelant CMenu::FromHandle, il s'agit d'une cartographie temporaire; le mappage sera déconnecté (c'est-à-dire que l'objet CMenu sera supprimé) lorsque le gestionnaire inactif (OnIdle) sera appelé la prochaine fois. Au contraire, si vous créez un objet CWnd et créez une fenêtre réelle (notez que MFC ne crée pas automatiquement un objet Fenêtre réel en créant simplement CWnd), il existe un mappage permanent entre CWnd et HWND.

+0

Sachez que CS_NOCLOSE affectera les fenêtres _ALL_ de cette classe dans le processus. Ce n'est généralement pas un problème pour votre fenêtre d'application, mais cela peut poser un problème pour les fenêtres contextuelles. –

+0

Merci! C'est vrai. – minjang

+0

Salut! J'ai mis à jour mon message. Cela fonctionne presque bien, mais appuyez sur le bouton après l'avoir réactivé, il ne se ferme pas :(Savez-vous pourquoi? – kampi

0

GetSystemMenu est le nom d'une api Win32 qui retourne HMENU, GetSystemMenu est également le nom d'une méthode MFC sur la classe CWnd, donc quand vous êtes dans une méthode de la classe CWnd, vous utiliserez le MFC GetSystemMenu méthode qui renvoie CMenu, mais lorsque vous n'êtes pas, vous utiliserez l'API Win32, qui renvoie HMENU.

Vous pouvez utiliser ::GetSystemMenu pour toujours utiliser l'API Win32. Ou vous pouvez ajouter une méthode publique à votre classe dérivée de CWnd et l'appeler pour effectuer la correction du menu.

Questions connexes