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

 
« Предыдущая статья   Следующая статья »