Microsoft Visual C++ и MFC. Программирование для Win95 и WinNT

         

Недокументированные возможности класса CMainFrame


Изучая пример приложения DOCKTOOL, поставляемого вместе с Microsoft Visual C++, мы обнаружили, что для отображения и удаления с экрана панелей управления используется метод OnBarCheck.

Метод вызывается из таблицы сообщений класса главного окна приложения CMainFrame. Для этого используется макрокоманда ON_COMMAND_EX. В случае прихода командных сообщений от строк меню, отвечающих за показ на экране панелей управления, вызывается метод OnBarCheck и ему в качестве параметра передается идентификатор соответствующей строки меню:

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

   // Другие макрокоманды таблицы сообщений

   ON_COMMAND_EX(IDW_BROWSE_BAR, OnBarCheck)

   ON_COMMAND_EX(IDW_DEBUG_BAR, OnBarCheck)

   ON_COMMAND_EX(IDW_EDIT_BAR, OnBarCheck)

END_MESSAGE_MAP()

Таким образом, когда пользователь выбирает из меню View приложения строку с именем панели управления, выдается командное сообщение с идентификатором, соответствующим строке меню и самой панели управления (идентификаторы панелей управления идентичны идентификаторам соответствующих строк меню View). Командное сообщение обрабатывается таблицей сообщений класса CMainFrame. Для его обработки вызывается метод OnBarCheck, которому в качестве параметра передается идентификатор панели управления.

Если вы решите поискать описание метода OnBarCheck в справочной системе Microsoft Visual C++, вас ждет разочарование. Ни в класс CFrameWnd, ни в один из его базовых классов метод OnBarCheck не входит. Когда вы вернетесь к исходным текстам самого приложения, в них вы также не обнаружите определение этого метода.

Мы проявили настойчивость и смогли обнаружить метод OnBarCheck только в исходных текстах библиотеки классов MFC. Оказывается, несмотря на отсутствие описания метода OnBarCheck в документации библиотеки MFC, этот метод входит в хорошо известный вам класс CFrameWnd.

В файле Afxwin.h, в котором объявлен класс CFrameWnd, вы можете найти объявления входящих в него методов OnUpdateControlBarMenu и OnBarCheck:

class CFrameWnd : public CWnd


{

// ...



// Command Handlers

public:

   afx_msg void OnUpdateControlBarMenu(CCmdUI* pCmdUI);

   afx_msg BOOL OnBarCheck(UINT nID);

}

Определения исходных текстов методов OnUpdateControlBarMenu и OnBarCheck содержатся в файле Winfrm.cpp.

В файле Winfrm.cpp также можно найти обращения к методам OnUpdateControlBarMenu и OnBarCheck в таблице сообщений класса CFrameWnd. Приведем соответствующий фрагмент этой таблицы:

BEGIN_MESSAGE_MAP(CFrameWnd, CWnd)

   // turning on and off standard frame gadgetry

   ON_UPDATE_COMMAND_UI(ID_VIEW_STATUS_BAR,

                        OnUpdateControlBarMenu)

   ON_COMMAND_EX(ID_VIEW_STATUS_BAR, OnBarCheck)

   ON_UPDATE_COMMAND_UI(ID_VIEW_TOOLBAR,

                        OnUpdateControlBarMenu)

   ON_COMMAND_EX(ID_VIEW_TOOLBAR, OnBarCheck)

END_MESSAGE_MAP()

Две пары макрокоманд ON_UPDATE_COMMAND_UI и ON_COMMAND_EX вызывают методы OnUpdateControlBarMenu и OnBarCheck для обработки командных сообщений с идентификаторами ID_VIEW_STATUS_BAR и ID_VIEW_TOOLBAR. Командные сообщения с такими идентификаторами поступают при выборе строк Toolbar и Status Bar меню View.

Меню View, содержащее строки Toolbar и Status Bar, вставляется во все приложения с оконным интерфейсом, которые созданы с использованием средств MFC AppWizard.

Рассмотрим теперь сами методы OnBarCheck и OnUpdateControlBarMenu. Метод OnBarCheck класса CFrameWnd определен следующим образом:

//////////////////////////////////////////////////////////////

// Метод OnBarCheck класса CFrameWnd

BOOL CFrameWnd::OnBarCheck(UINT nID)

{

   ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR);

   ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR);

   CControlBar* pBar = GetControlBar(nID);

   if (pBar != NULL)

   {

      ShowControlBar(pBar,

        (pBar->GetStyle() & WS_VISIBLE) == 0, FALSE);

      return TRUE;

   }

   return FALSE;

}

Отладочная версия метода OnBarCheck класса CFrameWnd проверяет соответствие идентификаторов ID_VIEW_STATUS_BAR, AFX_IDW_STATUS_BAR и ID_VIEW_TOOLBAR, AFX_IDW_TOOLBAR. Отметим, что эти идентификаторы определены в файле Afxres.h следующим образом:



#define AFX_IDW_TOOLBAR      0xE800

#define AFX_IDW_STATUS_BAR   0xE801

#define ID_VIEW_TOOLBAR      0xE800

#define ID_VIEW_STATUS_BAR   0xE801

Метод GetControlBar класса CFrameWnd определяет указатель на объект класса CControlBar, который представляет панель управления или панель состояния с идентификатором nID. Идентификаторы строк меню ID_VIEW_TOOLBAR и ID_VIEW_STATUS_BAR соответствуют стандартным идентификаторам панели управления AFX_IDW_TOOLBAR и панели состояния AFX_IDW_STATUS_BAR. 

При выборе из меню View строки Toolbar передается командное сообщение ID_VIEW_TOOLBAR, а при выборе строки Status bar - сообщение ID_VIEW_STATUS_BAR. Во время обработки этих сообщений, вызов метода GetControlBar определит объект класса CControlBar, соответствующий либо панели управления AFX_IDW_TOOLBAR, либо панели состояния AFX_IDW_STATUS_BAR.

Затем метод ShowControlBar отображает или закрывает соответствующую панель. Если панель была открыта, метод ShowControlBar скрывает ее и наоборот.

Аналогичным образом устроен метод OnUpdateControlBarMenu класса CFrameWnd, который обрабатывает команды обновления (по умолчанию, он обрабатывает команды обновления от строк Toolbar и Status bar меню View).

Метод OnUpdateControlBarMenu проверяет, отображается ли на экране панель управления или панель состояния с идентификатором, соответствующим идентификатору команды обновления. Если панель отображается, то строка меню отмечается символом Ö:

//////////////////////////////////////////////////////////////

// Метод OnUpdateControlBarMenu класса CFrameWnd

void CFrameWnd::OnUpdateControlBarMenu(CCmdUI* pCmdUI)

{

   ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR);

   ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR);

   CControlBar* pBar = GetControlBar(pCmdUI->m_nID);

   if (pBar != NULL)

   {

      pCmdUI->SetCheck((pBar->GetStyle() & WS_VISIBLE) != 0);

      return;

   }

   pCmdUI->ContinueRouting();

}

В конце метода OnUpdateControlBarMenu класса CFrameWnd вызывается метод ContinueRouting класса CCmdUI, который направляет команду обновления для дальнейшей обработки другим классам MFC (см. раздел “Обработка командных сообщений”).


Содержание раздела







Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий