Как использовать CMenu в приложении MFC? - PullRequest
2 голосов
/ 27 февраля 2010

Я сделал приложение 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: «инициализация»: невозможно преобразовать из «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 ]

2 голосов
/ 27 февраля 2010
  1. Существует простой способ отключить меню «Закрыть» в системе. Пожалуйста, добавьте бит CS_NOCLOSE в стиль класса. Вы можете изменить стиль класса, используя SetClassLong.

  2. Почему бы вам просто не использовать Win32 API, а не функцию MFC? Например, просто используйте ::GetSystemMenu, который возвращает HMENU. В общем, вы можете создать CMenu из HMENU по CMenu::FromHandle, но в таком простом случае гораздо лучше использовать напрямую Win32 API.

Обратите внимание, что отображение между объектами MFC (например, CMenu, CWnd) и дескрипторами Win32 (например, HMENU, HWND) является несколько сложным . Причина, по которой я сказал, что это сложно, состоит в том, что есть два типа отображения: временное и постоянное. Если вы наберете CMenu, позвонив CMenu::FromHandle, это временное отображение; сопоставление будет отключено (т. е. объект CMenu будет удален) при следующем вызове обработчика простоя (OnIdle). Напротив, если вы создаете объект CWnd и создаете реальное окно (обратите внимание, что MFC не создает автоматически реальный объект Window, просто создав CWnd), тогда между CWnd и * существует постоянное отображение 1027 *.

0 голосов
/ 27 февраля 2010

GetSystemMenu - это имя API Win32, которое возвращает HMENU, GetSystemMenu - это также имя метода MFC в классе CWnd, поэтому, когда вы находятся в методе класса CWnd, вы будете использовать метод MFC GetSystemMenu, который возвращает CMenu, но когда вы этого не сделаете, вы будете использовать Win32 API, который возвращает HMENU.

Вы можете использовать ::GetSystemMenu, чтобы всегда использовать Win32 API. Или вы можете добавить в ваш класс открытый метод, производный от CWnd, который может вызвать его для исправления меню.

...