Как создать приложение 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 приложении.

 
« Предыдущая статья   Следующая статья »