15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Интеллектуальное меню, наподобие Office 2000.


Автор: Piero Viano.

Я долгое время искал исходники этого меню, но поиски не увенчались успехом. Пришлось самому написать серию классов, эмулирующих подобный стиль. (Прим. вебмастера: конечно же, это не исходники от Microsoft, но судя по скриншоту всё выглядит очень даже по-фирменному.) Эти классы основаны на работах MB (mb2@geocities.co.jp) и Brent Corkum.

 

Чтобы вставить в приложение Office 2000-подобные панели меню, предлагаю Вам проделать следующие шаги.

 

  1. Откройте файл MDI.rc с помощью Microsoft Visual C++ и скопируйте из этого файла все диалоги(Dialogs), строки(String) (из таблицы строк) и менюшки в файл ресурсов Вашего проекта.
  2. Скопируйте установки из меню IDR_INT_MENU в Ваше меню, если понадобится использовать различные модификации.
  3. Скопируйте все файлы .cpp и .h из дирректории, содержащей исходники библиотеки в папку Вашего проекта. Включите эти файлы в проект.
  4. Отредактируйте MainFrm.h (заголовочный файл главного фрейма окна) в Вашем проекте:
    Измените объявление класса с:
    class CMainFrame : public CMDIFrameWnd
    на:
    #include "MDIFrmEx.h"
    #include "ToolBarEx.h"
    
    class CMainFrame : public CMDIFrameEx
    и измените класс toolbar с CToolBar на CToolbarEx:
    CToolbar m_wndToolBar;
    соответственно на:
    CToolbarEx m_wndToolBar;
  5. Отредактируйте файл MainFrm.cpp (исходник основного фрейма окна) в Вашем проекте:
    Замените:
    IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
    на:
    IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameEx)
    BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameEx)
    а так же в функции CMainFrame::OnCreate замените:
    if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
    на:
    if (CMDIFrameEx::OnCreate(lpCreateStruct) == -1)
  6. Отредактируйте файл MyApp.h (файл заголовков приложения) в Вашем проекте:
    Замените объявление класса:
    class CTestMDIApp : public CWinApp
    на:
    #include "WinAppEx.h"
    
    class CTestMDIApp : public CWinAppEx
  7. Отредактируйте файл MyApp.cpp (главный исходник) в Вашем проекте:
    Измените:
    BEGIN_MESSAGE_MAP(CTestMDIApp, CWinApp)
    на:
    #include "DocTplEx.h"
    
    BEGIN_MESSAGE_MAP(CTestMDIApp, CWinAppEx)
    и в функции CMyApp::InitInstance замените:
    	CMultiDocTemplate* pDocTemplate;
    	pDocTemplate = new CMultiDocTemplate(
    		IDR_TESTMDTYPE,
    		RUNTIME_CLASS(CTestMDIDoc),
    		// custom MDI child frame
    		RUNTIME_CLASS(CChildFrame), 
    		RUNTIME_CLASS(CTestMDIView));
    	AddDocTemplate(pDocTemplate);
    
    	// create main MDI Frame window
    	CMainFrame* pMainFrame = new CMainFrame;
    	if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
    		return FALSE;
    	m_pMainWnd = pMainFrame;
    на:
    	UINT nID;
    	nID=IDR_MAINFRAME;
    
    	// create main MDI Frame window
    	CMainFrame* pMainFrame = new CMainFrame;
    	if (!pMainFrame->LoadFrame(nID))
    		return FALSE;
    	m_pMainWnd = pMainFrame;
    
    	CMultiDocTemplateEx* pDocTemplate;
    	pDocTemplate = new CMultiDocTemplateEx(
    		IDR_TESTMDTYPE,
    		RUNTIME_CLASS(CTestMDIDoc),
    		// custom MDI child frame
    		RUNTIME_CLASS(CChildFrame), 
    		RUNTIME_CLASS(CTestMDIView),
    		&nID,1);
    	AddDocTemplate(pDocTemplate);
    
    	CWinAppEx::InitInstance();
  8. Откомпилируйте и запустите приложение.

Если Вы захотите создать собственное интеллектуальное меню, то достаточно наследовать класс из CMenuBar и убрать из него следующие функции:

WORD CMenuBar::IncMenuUsage(CMenuEx *pParent, 
                            UINT pos, 
                            WORD curusage)

BOOL CMenuBar::EvaluateIfGrayed(CMenuEx *pParent, 
                                UINT pos, 
                                WORD &curusage, 
                                int iMed, 
                                int iRange)

Первая функция вызывается для увеличения количества доступных меню. Вторая вызывается для определения - доступно меню или нет (закрашено серым цветом или нет). Так же эта функция может использоваться для изменения состояния меню (доступно или нет). Если Вы захотите сохранить состояния меню приложения, то для получения этих данных можно воспользоваться функцией CMenuEx::GetExtraDataPtr(UINT).

Downloads

Скачать демо-проект 1 (~ 68Kb)
Скачать демо-проект 2 (~ 95Kb)
Скачать исходник (~ 86Kb)