PRB: Excel Does Not Repaint Highlighted Cells Correctly in a MFC MDI Active Document Container (217391)
The information in this article applies to:
- The Microsoft Foundation Classes (MFC), when used with:
- Microsoft Visual C++, 32-bit Enterprise Edition 6.0
- Microsoft Visual C++, 32-bit Professional Edition 6.0
- Microsoft Visual C++, 32-bit Learning Edition 6.0
- Microsoft Visual C++ .NET (2002)
- Microsoft Visual C++ .NET (2003)
This article was previously published under Q217391 SYMPTOMS 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. CAUSE 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
IOleInPlaceActiveObject::OnDocWindowActivate(FALSE) function 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. RESOLUTION To work around this problem, override CView::OnSetFocus()
to redraw all views and their embedded servers. To do this, follow these steps: - Add the following function to the header file of the CView derived class in the protected section:
void DoRedraw();
- Implement this function as follows in the .cpp file of the CView derived:
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);
}
}
}
}
- Override the OnSetFocus() function to call the DoRedraw()
function in the CView derived class as follows:
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);
}
STATUS This behavior is by design.
Modification Type: | Major | Last Reviewed: | 9/23/2003 |
---|
Keywords: | kbActiveDocs kbContainer kbprb KB217391 |
---|
|