Как получить текущий CDocument или CView из любого
места программы
В приложениях 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. Получив такой указатель, Вы
можете обращаться к членам Вашего нового класса.
|