"AND" "OR"
Главная Информер Журнал Форум

Как создать приложение MFC, которое не имеет строки меню

Для большинства приложений Windows, меню является частью пользовательского интерфейса. Меню играет важную роль в управлении программой. Однако, необязательно, чтобы каждое приложение Windows содержало строку меню. В этой статье как раз и описывается, как создать MFC приложение без меню.

В приложениях, сгенерированных визардом, ресурс IDR_MAINFRAME это стандартный ресурс меню как для приложений SDI так и для MDI. В приложении SDI ресурс меню только один. MDI приложения содержать дополнительные меню для дочерних окон. Такие ресурсы меню обычно называются IDR_xxxTYPE, где xxx связан с типом соответствующего документа. Таким образом, создание MDI приложения без меню не такая уж простая задача в отличие от SDI приложения. В основном, Вам прийдётся изменять все функции, связанные с загрузкой и переключением менюшек.

Шаги по созданию SDI приложения не имеющего меню

  1. При помощи визарда сгенерируйте SDI приложение. Не удаляйте ресурс меню IDR_MAINFRAME. Если же у Вас приложение сгенерированное без участия визарда то, соответственно не удаляйте основной ресурс, отвечающий за меню. Оставить ресурс меню необходимо чтобы избежать ошибок в коде MFC.

  2. Чтобы основное окно приложения не имело полоски, необходимо удалить уже загруженное меню и установить в функции CFrameWnd::PreCreateWindow() поле hMenu структуры CREATESTRUCT в NULL:
          BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
          {
             if(cs.hMenu!=NULL)
             {
                 ::DestroyMenu(cs.hMenu);      // удаляем меню, если загружено
                 cs.hMenu = NULL;              // для этого окна меню нет
             }
    
             return CFrameWnd::PreCreateWindow(cs);
          } 



Шаги по созданию MDI приложения не имеющего меню

  1. При помощи визарда сгенерируйте MDI приложение. Не удаляйте ресурс меню IDR_MAINFRAME. Если же у Вас приложение сгенерированное без участия визарда то, соответственно не удаляйте основной ресурс, отвечающий за меню. Оставить ресурс меню необходимо чтобы избежать ошибок в коде MFC.

  2. Удалите ресурсы меню, связанные с дочерними окнами MDI (IDR_xxxTYPE). Они не будут использоваться. Таким образом мы избежим утечки памяти.

  3. В классе CMainFrame переопределите функцию PreCreateWindow():
          BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
          {
             if(cs.hMenu!=NULL)
             {
                 ::DestroyMenu(cs.hMenu);      // удаляем меню, если загружено
                 cs.hMenu = NULL;              // для этого окна меню нет
             }
    
             return CMDIFrameWnd::PreCreateWindow(cs);
          } 



  4. Измените код, отвечающий за переключение меню путём переопределения методов LoadFrame() и OnCreateClient() класса CMainFrame. Это необходимо, так как MFC уже загрузило менюшки автоматически. Следующий код показывает как это сделать:
          // Переопределённые объявления методов для CMainFrame
    
          BOOL LoadFrame( UINT nIDResource,
                 DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
                 CWnd* pParentWnd = NULL, CCreateContext* pContext = NULL );
          BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs,
                 CCreateContext* /*pContext*/);
    
          // Переопределённые объявления методов для CMainFrame
    
          BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
                 CWnd* pParentWnd, CCreateContext* pContext)
          {
              return CFrameWnd::LoadFrame(nIDResource,dwDefaultStyle,
                  pParentWnd,pContext);
          }
    
          BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs,
                  CCreateContext* /*pContext*/)
          {
              return CreateClient(lpcs,NULL);
          } 



 

ОБРАТИТЕ ВНИМАНИЕ: Вместо вызова базового класса (CMDIFrameWnd) в переопределённой LoadFrame, мы вызываем  CFrameWnd, тем самым избегая кода, который работает с менюшками в MDI приложении.