Привет!

Хочу обратить внимание на то, что изменение формы окон при помощи SetWindowRgn не всегда правильно работает в старых версиях Windows – в частности, такая ситуация наблюдалась под Windows 95 (PLUS) не OSR 2.

Зато совершенно точно это работает под '98, NT, 2000.

-------

Хочу предложить полезную уловку, позволяющую при использовании MFC-шаблонов документов управлять MDI-окнами из приложения. Этот трюк можно использовать при отображении разных категорий данных в различных окнах. При этом можно, в частности, автоматически переключать активные MDI-окна при обновлении данных в них.

Представьте библиотеку (класс), следующего вида:

class TReg {

public: 

 static CMapStringToPtr map;

 static BOOL RegisterTemplate(CString strName, CDocTemplate * ptr);

 static BOOL HasOpenViews(CString strName);

 static BOOL PostForAllViews(CString strName, UINT msg, WPARAM w, LPARAM p);

 static BOOL SendForAllViews(CString strName, UINT msg, WPARAM w, LPARAM p);

 static CDocTemplate * GetTemplate(CString strName);

 ... 

};

Зачем все элементы статические – легко понять, ведь у нас только один MDI-фрейм.

Далее, в методе WinApp::InitInstance при порождении шаблонов документов  вместо (или вместе с) AddDocTemplate( CDocTemplate * )  записываем TReg::RegisterTemplate( "MyName", CDocTemplate * );

Здесь мы просто добавляем указатели шаблонов в словарь map.

С помощью метода GetTemplate мы можем извлечь указатель на шаблон из словаря по имени. Используя этот указатель, мы можем: 

– открыть новое окно при помощи DocTemplate::OpenDocumentFile;

– закрыть все окна, относящиеся к данному шаблону;

– отправить сообщение всем окнам данного шаблона:

for (POSITION pos= pTempl->GetFirstDocPosition; pos != NULL; ) {

 CDocument * pDoc= pTempl->GetNextDoc(pos);

 if (msg == NULL) pDoc->UpdateAllViews(NULL);

 else

  for (POSITION p1= pDoc->GetFirstViewPosition; p1 != NULL; ) {

   CView * pView= pDoc->GetNextView (p1);

   pView->PostMessage (msg, w, l);

  }

}

– проверить, имеются ли открытые окна, относящиеся к данному шаблону:

for (POSITION pos = pTempl->GetFirstDocPosition; pos != NULL; ) {

 CDocument * pDoc= pTempl->GetNextDoc(pos);

 for (POSITION p1 = pDoc->GetFirstViewPosition; p1 != NULL; ) {

  CView * pView = pDoc->GetNextView(p1);

  if (pView != NULL) return TRUE;

 }

}

return FALSE;

и т.д.

Активизация (всплывание наверх) MDI-окна в программе проще всего реализуется добавлением примерно такого метода класса CView:

void CMyView::DoActivate {

 CMDIChildWnd * pFrm = (CMDIChildWnd *)(GetParent);

 if (pFrm != NULL && IsWindow(pFrm->m_hWnd)) pFrm->MDIActivate;

}

Victor Yakovlev
Перейти на страницу:

Похожие книги