Здравствуйте, Feral, Вы писали:
F>CMainFrame::GetActiveDocument () возвращает CDocument*, а как его можно преобразовать в CMyDoc*? F>Поскажите, пожалуйста.
Бери и преобразовывай
AppWizard прямо такой код и вставляет при генерации приложения:
return (CMyDoc*)m_pActiveDocument;
(не уверен насчёт правильного названия переменной, но не суть)
К>Бери и преобразовывай К>AppWizard прямо такой код и вставляет при генерации приложения: К>return (CMyDoc*)m_pActiveDocument; К>(не уверен насчёт правильного названия переменной, но не суть)
Но когда я пытаюсь обращаться к полям CMyDoc, которых нет в CDocument он вылетает с ошибкой.
Как изменять содержимое документа?
Здравствуйте, Feral, Вы писали:
F>Но когда я пытаюсь обращаться к полям CMyDoc, которых нет в CDocument он вылетает с ошибкой. F>Как изменять содержимое документа?
Так... А ты уверен, что там действительно лежит именно CMyDoc?
Здравствуйте, Feral, Вы писали:
F>Где? Я наверное очень глупый, Вот что я хотел:
F>void CMainFrame::OnActionsConv() F>{ F> CCTGDoc *pDoc = (CCTGDoc*) GetActiveDocument (); pDoc->>m_count = 100; F>}
F>т.е. в CMainFrame получить указатель на активный объект класса CCTGDoc. F>Неподскажите как?
Ок, тогда такие вопросы:
1. Приложение MDI или SDI?
2. Пройдись в дебаге в таком коде:
void CMainFrame::OnActionsConv()
{
CDocument* pDoc = GetActiveDocument (); // <-- Вот здесь поставь Breakpoint
// CCTGDoc *pDoc = (CCTGDoc*) GetActiveDocument ();
// pDoc->>m_count = 100;
}
После выполнения GetActiveDocument() проверь, чему равен pDoc: во-первых, не NULL ли это, а во-вторых, дебаггер пишет "настоящий" тип документа в окне Watch'ей, проверь — действительно ли там лежит тип CCTGDoc.
К>Ок, тогда такие вопросы: К>1. Приложение MDI или SDI? К>2. Пройдись в дебаге в таком коде: К>void CMainFrame::OnActionsConv() К>{ К> CDocument* pDoc = GetActiveDocument (); // <-- Вот здесь поставь Breakpoint К>// CCTGDoc *pDoc = (CCTGDoc*) GetActiveDocument (); К>// pDoc->>m_count = 100; К>} К>После выполнения GetActiveDocument() проверь, чему равен pDoc: во-первых, не NULL ли это, а во-вторых, дебаггер пишет "настоящий" тип документа в окне Watch'ей, проверь — действительно ли там лежит тип CCTGDoc.
Приложение MDI.
Проделал как вы сказали. pDoc не 0 и имеет тип CDocument.
Здравствуйте, Feral, Вы писали:
F>Приложение MDI. F>Проделал как вы сказали. pDoc не 0 и имеет тип CDocument.
Какая среда? 6.0, .NET, .NET 2003? Я, похоже, не совсем правильно выразился. В окне Watch должно быть написано что-то вроде:
pDoc 0x002f55c0 {CCTGDoc}
Если у тебя в фигурных скобочках написано {CDocument}, значит что-то неправильное происходит, и создаётся документ не твоего типа, а базового. Тогда понятно, почему он вылетает — в нём нет тех полей, что добавлены в CCTGDoc, и никаким преобразованием ты их не получишь. Нужно искать, почему создаётся документ именно базового типа, а не твоего... Как это сделать — общих рекомендаций дать не могу. Разве что трассировкой по всему пути выполнения...
Здравствуйте, Feral, Вы писали:
F>CMainFrame::GetActiveDocument () возвращает CDocument*, а как его можно преобразовать в CMyDoc*? F>Поскажите, пожалуйста
(CMyDoc*)GetActiveDocument()
разве не проходит?
Здравствуйте, Feral, Вы писали:
F>CMainFrame::GetActiveDocument () возвращает CDocument*, а как его можно преобразовать в CMyDoc*? F>Поскажите, пожалуйста.
Если использовать RTTI (run-time type information) предоставляемую MFC (DECLARE_DYNAMIC, IMPLEMENT_DYNAMIC)
То вот так
CMyDoc *pDoc = DYNAMIC_DOWNCAST(CMyDoc, CMainFrame::GetActiveDocument());
if (pDoc)
{
...
}
Такое преобразование гарантирует что GetActiveDocument вернула указатель именно на CMyDoc
W>Не понял, какие объекты какого документа? W>Если нужно получить список всех открытых документов то:
W>
W> POSITION posTemplate = theApp.GetFirstDocTemplatePosition();
W> while (posTemplate)
W> {
W> CDocTemplate *pTemplate = theApp.GetNextDocTemplate(posTemplate);
W> POSITION posDocument = pTemplate->GetFirstDocPosition();
W> while (posDocument)
W> {
W> CDocument *pDoc = pTemplate->GetNextDoc(posDocument);
W> TRACE(_T("%s\n"), pDoc->GetTitle());
W> }
W> }
W>
Спасибо!
т.е. можно
CMyDoc *pDoc = (CMyDoc*)pTemplate->GetNextDoc(posDocument);
или СMyDoc *pDoc = DYNAMIC_DOWNCAST(CMyDoc, pTemplate->GetNextDoc(posDocument));
Здравствуйте, Feral, Вы писали:
F>Спасибо! F>т.е. можно F>CMyDoc *pDoc = (CMyDoc*)pTemplate->GetNextDoc(posDocument); F>или СMyDoc *pDoc = DYNAMIC_DOWNCAST(CMyDoc, pTemplate->GetNextDoc(posDocument));
Похоже проблемы с пониманием.
Архитектура MDI следующая:
У аппликации есть несколько шаблонов у шаблона несколько документов.
Каждый шаблон работает со своим типом документа.
По умолчанию шаблон один и тип документа, соответственно, тоже один.
Если у тебя шаблонов несколько, то для того чтобы спокойно делать простое преобразование
нужно быть увернным что pTemplate является шаблоном для документов типа CMyDoc
А вообще никогда не лишним будет сделать DYNAMIC_DOWNCAST или ASSERT_KINDOF
CChildWnd *pWnd=STATIC_DOWNCAST(CChildWnd, GetActiveWindow());
if(pWnd!=NULL&&::IsWindow(pWnd->GetSafeHwnd()))
{
CView *pView = pWnd->GetActiveView(); //Здесь тоже можно взять DOWNCAST даже скорее нужно шоб було CMyView
CMyDoc *d =(CMyDoc) pView->GetDocument(); //ежели взял свой виев то он должен вернуть CMyDoc если нет преобразуем
}
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.
Здравствуйте, ol-lv, Вы писали:
OL>Как я понял вызов в функции MainFrame OL>
OL> CChildWnd *pWnd=STATIC_DOWNCAST(CChildWnd, GetActiveWindow());
OL> if(pWnd!=NULL&&::IsWindow(pWnd->GetSafeHwnd()))
OL> {
OL> CView *pView = pWnd->GetActiveView(); //Здесь тоже можно взять DOWNCAST даже скорее нужно шоб було CMyView
OL> CMyDoc *d =(CMyDoc) pView->GetDocument(); //ежели взял свой виев то он должен вернуть CMyDoc если нет преобразуем
OL> }
OL>
Думаю, вместо GetActiveWindow лучше воспользоваться GetActiveFrame или MDIGetActive
Здравствуйте, Willi, Вы писали:
W>Думаю, вместо GetActiveWindow лучше воспользоваться GetActiveFrame или MDIGetActive
Согласен.., хотя принципиальная разница только в том случае, если мы узнаем активный документ в фоновом режиме..,
в потоке, к примеру. Тогда GetActiveWindow даст активное окно в системе а
(HWND)::SendMessage(m_hWndMDIClient, WM_MDIGETACTIVE, 0,
(LPARAM)pbMaximized);
даст активный чилдрен .., ежели нам надо узнавать активное окно по действию пользователя . хотя все же конечно лучше MDIGetActive.. дык шо сорри
Compiler can be as trained AI but can't compose music.
Antheil piano jazz sonata. Я болен ПГМ.