В приложениях MFC очень часто бывает необходимо получить указатель на активный документ или Вид из любого места программы. Например, иногда полезно иметь доступ к документу из диалогового окна. В данной статье обсуждаются простейшие методы того, как это сделать используя связи между объектами MFC и основной архитектурой MFC. Как уже упоминалось, один из случаев, когда может потребоваться указатель на текущий активный Вид или документ, это модальное или немодальное диалоговое окно. Вообще-то, диалоговое окно должно быть создано классом Вида, так Вид имеет прямое отношение к пользовательскому интерфесу приложения.
Так как класс Вид создаёт диалоговое окно, то он может передать диалоговому окну указатель на самого себя либо на активный документ [полученный функцией GetActiveDocument()]. Это можно сделать через конструктор диалога либо через другую функцию-член. Для модальных диалогов, Вид также может помещать данные из диалогового окна в документ когда DoModal() возвращает управление.
Чтобы получить указатель на текущий активный документ из любого места программы, добавьте статическую функцию-член в Ваш класс, наследованный от CDocument как показано ниже:
В заголовочном файле документа, добавляем статическую функцию GetDoc(): // Заголовочный файл документа class CMyDoc : public CDocument { ... public: static CMyDoc * GetDoc(); ... }; Для однодокументного приложения (SDI), добавляем следующий код функции CMyDoc::GetDoc(): // файл исходника SDI документа CMyDoc * CMyDoc::GetDoc() { CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd); return (CMyDoc *) pFrame->GetActiveDocument(); } Для многодокументного приложения (MDI), код функции CMyDoc::GetDoc() будет выглядеть следующим образом: CMyDoc * CMyDoc::GetDoc() { CMDIChildWnd * pChild = ((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();
if ( !pChild ) return NULL;
CDocument * pDoc = pChild->GetActiveDocument();
if ( !pDoc ) return NULL;
// Ошибка, если документ неправильного типа if ( ! pDoc->IsKindOf( RUNTIME_CLASS(CMyDoc) ) ) return NULL;
return (CMyDoc *) pDoc; } Чтобы получить указатель на текущий активный Вид из любого места программы, добавьте статическую функцию-член в Ваш класс, наследованный от CView как показано ниже:
В заголовочном файле Вида добавляем статическую функцию GetView(): // Заголовочный файл Вида class CMyView { ... public: static CMyView * GetView(); ... }; Для SDI приложения тело функции CMyView::GetView() будет выглядеть следующим образом: // View implementation file CMyView * CMyView::GetView() { CFrameWnd * pFrame = (CFrameWnd *)(AfxGetApp()->m_pMainWnd);
CView * pView = pFrame->GetActiveView();
if ( !pView ) return NULL;
// Ошибка, если Вид неправильного типа // (это может случиться с окнами разделителями (splitter windows), // либо с дополнительными Видами в одном документе if ( ! pView->IsKindOf( RUNTIME_CLASS(CMyView) ) ) return NULL;
return (CMyView *) pView; } Для многодокументного приложения (MDI), код функции CMyView::GetView() будет выглядеть следующим образом: // MDI view implementation file CMyView * CMyView::GetView() { CMDIChildWnd * pChild = ((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();
if ( !pChild ) return NULL;
CView * pView = pChild->GetActiveView();
if ( !pView ) return NULL;
// Ошибка, если Вид неправильного типа if ( ! pView->IsKindOf( RUNTIME_CLASS(CMyView) ) ) return NULL;
return (CMyView *) pView; } Теперь, из любого места Вашей программы где включён заголовочный файл документа или Вида можно вызвать: CMyDoc::GetDoc(); - Или - CMyView::GetView(); чтобы получить указатель на текущий активный документ или Вид соответственно. Если нет ниодного активного документа или Вида, то эти функции вернут NULL. Получив такой указатель, Вы можете обращаться к членам Вашего нового класса. |