Когда начал читать вашу статью на тему мерцания, подумал было, что вы обязательно упомянете тот метод, который использовал я в своей программе. На мой взгляд, он достаточно известен, и, кажется, является самым самым лучшим.
Нужно просто создать обработчик события WM_ERASEBKGND с одной-единственной строчкой:
BOOL CSomeClass::OnEraseBkgnd(CDC* pDC) {
return FALSE;
}
Т.е., по-русски говоря, программа фон не очистила, рисуйтесь полностью.
На ответ A1 из прошлого выпуска:
Теперь практика. Пусть имеется готовое SDI приложение (с технологией Документ/Представление). Создаем дополнительное Представление. Это делается в функции CFrameWnd::OnCreateClient примерно так:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) {
// class CNewView – это наше новое представление
pContext->m_pNewViewClass = RUNTIME_CLASS(CNewView);
// обратите внимание на идентификатор нового Представления
// переменная m_pNewView описанна в CMainFrame как
CNewView* m_pNewView;
m_pNewView = STATIC_DOWNCAST(CNewView, CreateView(pContext, AFX_IDW_PANE_FIRST+1));
m_pNewView->ShowWindow(SW_HIDE); // для сброса флага WS_VISIBLE
return CFrameWnd::OnCreateClient(lpcs, pContext);
}
Этот код работает неправильно, причём это видно даже невооружённым взглядом. В последней строчке функции CMainFrame::OnCreateClient вызывается функция базового класса. Но ведь поле pContext->pNewViewClass уже изменилось! В результате вместо двух разных видов будет создано два одинаковых. Ошибка лечится переносом вызова функции из базового класса в начало переопределённой функции:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) {
int nResult = CFrameWnd::OnCreateClient(lpcs, pContext);
…
return nResult;
}
Кроме того, неясно, как использовать функцию SwitchView. Указатель на созданный нами вид хранится в m_pNewView, но для получения указателя на вид, созданный самой MFC, не видно удобного способа. Вероятно, лучший вариант – также сохранить его в члене класса CMainFrame.