PRB: Excel Does Not Repaint Highlighted Cells Correctly in a MFC MDI Active Document ContainerID: Q217391
|
When an AppWizard-generated MFC MDI Active Document Container has an Excel spreadsheet embedded in one of its views, and another view open at the same time, any highlighted cells in the Excel spreadsheet is not repainted correctly when the other view is dragged over the spreadsheet view.
This problem occurs because the Excel document server does not "unhighlight" the cells after the document has lost focus. The MFC Active Document Container calls the function IOleInPlaceActiveObject::OnDocWindowActivate(FALSE) from CMDIChildWnd::OnMDIActivate to notify the Active Document Server that it should deactivate the document. The implementation of the Excel document server deactivates the document, but does not unhighlight the cells. Excel unhighlights the cells when its view is redrawn after it has lost focus. Therefore, the Excel document server must be notified to redraw itself after it has lost focus.
To work around this problem, override CView::OnSetFocus() to redraw all views and their embedded servers.
The following steps should be taken to work around this problem:
void DoRedraw();
void CMyAXDocContView::DoRedraw()
{
// This function causes the embedded Active Document Server to be redrawn
// Iterate document templates...
POSITION posTmpl = AfxGetApp()->GetFirstDocTemplatePosition();
while(posTmpl != NULL){
CDocTemplate *pTmpl = AfxGetApp()->GetNextDocTemplate(posTmpl);
// Iterate documents in this template.
POSITION posDoc = pTmpl->GetFirstDocPosition();
while(posDoc != NULL) {
COleDocument *pDoc = (COleDocument *)pTmpl->GetNextDoc(posDoc);
// Iterate views of each document.
POSITION posView = pDoc->GetFirstViewPosition();
while(posView != NULL) {
CView *pView = pDoc->GetNextView(posView);
// Completely redraw.
pView->RedrawWindow(NULL, NULL, RDW_ERASE|RDW_INVALIDATE|RDW_UPDATENOW|RDW_FRAME|RDW_ALLCHILDREN);
}
}
}
}
void CMyAXDocCont1View::OnSetFocus(CWnd* pOldWnd)
{
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL &&
pActiveItem->GetItemState() == COleClientItem::activeUIState)
{
// Need to set focus to this item if it is in the same view.
CWnd* pWnd = pActiveItem->GetInPlaceWindow();
if (pWnd != NULL)
{
pWnd->SetFocus(); // Don't call the base class.
DoRedraw(); // Redraw Server
return;
}
}
DoRedraw(); // Redraw Server.
CView::OnSetFocus(pOldWnd);
}
This behavior is by design.
© Microsoft Corporation 1999, All Rights Reserved.
Contributions by Bret Bentzinger, Microsoft Corporation
Additional query words:
Keywords : kbActiveDocs kbActiveX kbContainer kbExcel kbMFC kbVC600
Version : winnt:6.0
Platform : winnt
Issue type : kbprb
Last Reviewed: March 5, 1999