如何在MFC应用程序中使用CMenu?

时间:2010-02-27 01:41:53

标签: c windows mfc

我制作了一个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 );
}

但是现在,在我的程序结束时(UINT CopyThread(LPVOID pParam))我想重新启用它,但我不能。我之前传递给我的线程m_hWnd,现在我不想将它传递给GetSystemMenu函数但是我得到一个编译器错误:错误C2440:'initializing':无法从'HMENU'转换为'CMenu *'。我确信这是一个简单的问题,但我是初学者,所以请帮助,但我无法弄明白,我正在做什么!

提前致谢!

kampi

更新: 我试过这种方式,几乎可以。关闭“X”将再次变为黑色,但如果按下它,我的程序将不存在。我做错了什么,或者这是因为别的什么?

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

2 个答案:

答案 0 :(得分:2)

  1. 有一种简单的方法可以禁用系统中的“关闭”菜单。请将CS_NOCLOSE的位添加到类样式中。您可以使用SetClassLong更改课程样式。

  2. 为什么不使用Win32 API而不是MFC功能?例如,只需使用返回::GetSystemMenu的{​​{1}}即可。通常,您可以通过HMENUCMenu创建HMENU,但在这种简单的情况下,直接使用Win32 API要好得多。

  3. 请注意,MFC对象(例如,CMenu,CWnd)和Win32句柄(例如,HMENU,HWND)之间的映射是somewhat complex。我说它复杂的原因是有两种类型的映射:时间和永久。如果您通过调用CMenu::FromHandleCMenu,则它是一个临时映射;下次调用空闲处理程序(CMenu::FromHandle)时,将断开映射(即,CMenu对象将被删除)。相反,如果您创建一个OnIdle对象并创建一个实际的窗口(请注意,MFC不会通过创建CWnd自动创建一个真正的Window对象),那么{之间存在永久映射{1}}和CWnd

答案 1 :(得分:0)

GetSystemMenu是返回HMENU的Win32 api的名称,GetSystemMenu 也是 CWnd类上MFC方法的名称,所以当你在CWnd类的方法,你将使用返回CMenu的MFC GetSystemMenu方法,但是当你不是时,你将使用返回HMENU的Win32 API。

您可以使用::GetSystemMenu始终使用Win32 API。或者你可以向你的类添加一个公共方法,派生自CWnd可以调用它来进行菜单修复。