//============================================================
// Приложение MultiMenu
// (c) Frolov G.V., 1996
// E-mail: frolov@glas.apc.org
//============================================================

// Включаемые файлы для MFC
#include <afxwin.h>
#include <afxext.h> 
#include <afxcmn.h>

// Включаемый файл для ресурсов приложения и идентификаторов
#include "resource.h"

//============================================================
// Класс CMultiMenuApp - главный класс приложения 
//============================================================
class CMultiMenuApp : public CWinApp
{
public:
   // Мы будем переопределять метод InitInstance,
   // предназначенный для инициализации приложения
   virtual BOOL InitInstance();
};
 
// Создаем объект приложение класса CMultiMenuApp
CMultiMenuApp MultiMenuApp;
 
//============================================================
// Класс CMultiMenuWindow - представляет главное окно 
//============================================================
class CMultiMenuWindow : public CFrameWnd
{

protected:  
   // Панель состояния
   CStatusBar  m_wndStatusBar;   
   
   // Флаг управляет строкой Prosess меню Mission
   BOOL  bEnable; 

   // Флаг управляет строкой Construction меню Mission
   BOOL  bRadio;  

   // Флаг управляет строкой Restrict меню Menu
   int   nCheck;  
       
protected:
   // Метод для создания окна приложения и панели состояния
   afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

   // Методы для обработки командных сообщений 
   // от меню приложения
   afx_msg void CMultiMenuWindow::OnDisable();
   afx_msg void CMultiMenuWindow::OnCommand();
   afx_msg void CMultiMenuWindow::OnExit();
   afx_msg void CMultiMenuWindow::OnConstruct();
   afx_msg void CMultiMenuWindow::OnRestrictMenu();
   afx_msg void CMultiMenuWindow::OnFullMenu();

   // Методы для обновления меню
   afx_msg void OnUpdateProcess(CCmdUI* pCmdUI);
   afx_msg void OnUpdateConstruct(CCmdUI* pCmdUI);
   afx_msg void OnUpdateDisable(CCmdUI* pCmdUI);
   
public:
   // Конструктор класса CMultiMenuWindow
   CMultiMenuWindow();

   // Макрокоманда необходима, так как класс 
   // CMultiMenuWindow обрабатывает сообщения
   DECLARE_MESSAGE_MAP()    
}; 

//============================================================
// Таблица сообщений класса CMultiMenuWindow
//============================================================
BEGIN_MESSAGE_MAP(CMultiMenuWindow, CFrameWnd)
   
   // Макрокоманда вызывает метод OnCreate
   ON_WM_CREATE()

   // Макрокоманда вызывает метод OnContextMenu
   ON_WM_CONTEXTMENU()

   // Макрокоманды для обработки командных сообщений 
   ON_COMMAND(ID_MENU_DISABLE, OnDisable)
   ON_COMMAND(ID_MISSION_CONSTRUCT, OnConstruct)
   ON_COMMAND(ID_FILE_EXIT, OnExit)
   ON_COMMAND(ID_MISSION_PROCESS, OnCommand)
   
   ON_COMMAND(ID_MENU_RESTRICT, OnRestrictMenu)
   ON_COMMAND(ID_MENU_FULL, OnFullMenu)

   // Обработчики сообщений ON_UPDATE_COMMAND_UI 
   ON_UPDATE_COMMAND_UI(ID_MISSION_PROCESS, OnUpdateProcess)
   ON_UPDATE_COMMAND_UI(ID_MISSION_CONSTRUCT, 
                           OnUpdateConstruct)
   ON_UPDATE_COMMAND_UI(ID_MENU_DISABLE, OnUpdateDisable)

END_MESSAGE_MAP()

// Индикатор панели управления
UINT indicator = ID_SEPARATOR;

//============================================================
// Метод InitInstance класса CMultiMenuApp
// Создает главное окно приложения и отображает его на экране
//============================================================
BOOL CMultiMenuApp::InitInstance()
{
   m_pMainWnd = new CMultiMenuWindow();
   m_pMainWnd -> ShowWindow(m_nCmdShow);
   m_pMainWnd -> UpdateWindow();

   return TRUE;
}

//============================================================
// Конструктор класса CMultiMenuWindow
//============================================================
CMultiMenuWindow::CMultiMenuWindow()
{ 
   // Создаем окно приложения, соответствующее 
   // данному объекту класса CMultiMenuWindow
   Create(NULL, "Multi Menu Sample", WS_OVERLAPPEDWINDOW,
      rectDefault, NULL, MAKEINTRESOURCE(IDR_FULL_MENU));

   // Загружаем таблицу клавиш акселерации
   LoadAccelTable(MAKEINTRESOURCE(IDR_ACCELERATOR));

   // Инициализируем флаги
   bEnable = TRUE;         
   bRadio = TRUE;         
   nCheck = 0;
}

//============================================================
// Метод OnCreate класса CMultiMenuWindow
// Вызывается во время создания окна приложения
//============================================================
int CMultiMenuWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   // Вызываем метод OnCreate базового класса
   if(CFrameWnd::OnCreate(lpCreateStruct) == -1)
      return -1;
   
   // Создаем панель состояния 
   if(!m_wndStatusBar.Create(this))
   {
      // Ошибка при создании панели состояния
      TRACE0("Failed to create status bar\n");
      return -1;   
   }

   // Отображаем индикаторы панели состояния
   if(!m_wndStatusBar.SetIndicators(&indicator,1))
   {
      // Ошибка при установке индикатора
      TRACE0("Failed to set indicators\n");
      return -1;   
   }
   
   return 0;
}

//============================================================
// Метод OnDisable класса CMultiMenuWindow
// Изменяем состояние флагов bEnable и nCheck 
//============================================================
void CMultiMenuWindow::OnDisable()
{
   // Меняем значение bEnable с TRUE на FALSE и наоборот
   bEnable = !bEnable;
   
   // Меняем значение bEnable с 1 на 0 и наоборот
   nCheck = (nCheck == 1) ? 0 : 1; 
}

//============================================================
// Метод OnRestrictMenu класса CMultiMenuWindow
// Изменяем меню приложения с IDR_FULL_MENU на 
// IDR_RESTRICT_MENU
//============================================================
void CMultiMenuWindow::OnRestrictMenu()
{
   CMenu menuOld;       // текущее меню
   CMenu menuRestrict;  // новое меню
   CMenu* pMenu;

   // Получаем указатель на текущее меню 
   pMenu = this->GetMenu();
   
   // Связываем меню с объектом menuOld
   menuOld.Attach(pMenu->m_hMenu);

   // Удаляем меню 
   menuOld.DestroyMenu();
   
   // Загружаем меню IDR_RESTRICT_MENU
   menuRestrict.LoadMenu(IDR_RESTRICT_MENU);

   // Устанавливаем загруженное меню 
   SetMenu(&menuRestrict);

   // Разрываем связь меню с объектом menuRestrict
   menuRestrict.Detach();
}

//============================================================
// Метод OnFullMenu класса CMultiMenuWindow
// Изменяем меню приложения с IDR_RESTRICT_MENU на 
// IDR_FULL_MENU 
//============================================================
void CMultiMenuWindow::OnFullMenu()
{
   CMenu menuOld;
   CMenu menuRestrict;
   CMenu* pMenu;

   pMenu = this->GetMenu();
   menuOld.Attach(pMenu->m_hMenu);
   menuOld.DestroyMenu();

   menuRestrict.LoadMenu(IDR_FULL_MENU);
   SetMenu(&menuRestrict);
   menuRestrict.Detach();
}

//============================================================
// Метод OnCommand класса CMultiMenuWindow
//============================================================
void CMultiMenuWindow::OnCommand()
{
   MessageBox("Command not implemented");
}

//============================================================
// Метод OnConstruct класса CMultiMenuWindow
// Изменяем состояние флага bRadio
//============================================================
void CMultiMenuWindow::OnConstruct()
{
   // Меняем значение bRadio с TRUE на FALSE и наоборот
   bRadio = !bRadio;
}

//============================================================
// Метод OnExit класса CMultiMenuWindow
//============================================================
void CMultiMenuWindow::OnExit()
{
   // Завершаем приложение
   DestroyWindow();
   return;
}

//============================================================
// Метод OnUpdateProcess класса CMultiMenuWindow
//============================================================
void CMultiMenuWindow::OnUpdateProcess(CCmdUI* pCmdUI)
{
   // Блокируем или разблокируем строку Process меню Mission
   pCmdUI->Enable(bEnable); 
}

//============================================================
// Метод OnUpdateConstruct класса CMultiMenuWindow
//============================================================
void CMultiMenuWindow::OnUpdateConstruct(CCmdUI* pCmdUI)
{
   // Устанавливаем или снимаем пометку 
   // строки Construction меню Mission
   pCmdUI->SetRadio(bRadio);
}

//============================================================
// Метод OnUpdateDisable класса CMultiMenuWindow
//============================================================
void CMultiMenuWindow::OnUpdateDisable(CCmdUI* pCmdUI)
{
   // Устанавливаем или удаляем пометку 
   // у строки Disable меню Menu
   pCmdUI->SetCheck(nCheck);
}
