我想用 VC++ MFC automation 调用 Excel 并隐藏主菜单条 "Worksheet menu bar" 。但是当我调用了 CommandBar.SetEnabled(false); 后根本没起作用,菜单条依然存在。我也试着调用了 CommandBar.SetVisible(false); 但却报一个OLEException。我的代码是从《Inside Visual C++ 6.0 Version 5》范例代码 CEx25d 修改而来的。
编译环境是:Visual Studio 2005, Windows XP. Excel 2007.如下是关键部分的代码,求高人相助:
void CEx25dView::OnExceloleExecute()
{
LPDISPATCH pRange, pWorkbooks, pCommandBars;
CWnd* pWnd = CWnd::FindWindow("XLMAIN", NULL);
if (pWnd != NULL) {
TRACE("Excel window found\n");
pWnd->ShowWindow(SW_SHOWNORMAL);
pWnd->UpdateWindow();
pWnd->BringWindowToTop();
}
m_app.SetSheetsInNewWorkbook(1); VERIFY(pWorkbooks = m_app.GetWorkbooks());
m_workbooks.AttachDispatch(pWorkbooks); LPDISPATCH pWorkbook = NULL;
if (m_workbooks.GetCount() == 0) {
COleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
pWorkbook = m_workbooks.Add(covOptional);
}
LPDISPATCH pWorksheets = m_app.GetWorksheets();
ASSERT(pWorksheets != NULL);
m_worksheets.AttachDispatch(pWorksheets);
pCommandBars = m_app.GetCommandBars();
m_commandbars.AttachDispatch(pCommandBars);
int CommandBarCount = m_commandbars.GetCount();
TRACE("CommandBarCount = %d\n", CommandBarCount);
char buf[2048];
TRACE("TRUE %d, FALSE %d\n", TRUE, FALSE);
CommandBar oBar(m_commandbars.GetItem(COleVariant((short) 1))); // param 1(index 1) = Worksheet enu bar, equivalent to m_commandbars.GetActiveMenuBar(); sprintf(buf, "name:%s, nameLocal:%s, Context:%s, Height:%d, Index:%d, Left:%d, width:%d, Type:%d, Visual:%d, Enabled:%d \n"
, (LPCTSTR)(oBar.GetName()), (LPCTSTR)(oBar.GetNameLocal()), (LPCTSTR)(oBar.GetContext()), oBar.GetHeight(), oBar.GetIndex(), oBar.GetLeft(), oBar.GetWidth(), oBar.GetType(), oBar.GetVisible(), oBar.GetEnabled()); TRACE(buf);
oBar.SetEnabled(false); // no effect, Menubar still exists.
//oBar.SetVisible(false); // GOT OLEException
// cleanup
if (pWorkbook != NULL) {
pWorkbook->Release();
}
}
void CEx25dView::OnUpdateExceloleExecute(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_app.m_lpDispatch != NULL);
}void CEx25dView::OnExceloleLoad()
{ // if Excel is already running, attach to it, otherwise start it
LPDISPATCH pDisp;
LPUNKNOWN pUnk;
CLSID clsid;
TRACE("Entering CEx25dView::OnExcelLoad\n");
BeginWaitCursor();
::CLSIDFromProgID(L"Excel.Application.12", &clsid); // from registry
if(::GetActiveObject(clsid, NULL, &pUnk) == S_OK) {
VERIFY(pUnk->QueryInterface(IID_IDispatch,
(void**) &pDisp) == S_OK);
m_app.AttachDispatch(pDisp);
pUnk->Release();
TRACE(" attach complete\n");
}
else {
if(!m_app.CreateDispatch("Excel.Application.12")) {
AfxMessageBox("Excel 97 program not found");
}
TRACE(" create complete\n");
}
EndWaitCursor();
OnExceloleExecute() ;
}void CEx25dView::OnUpdateExceloleLoad(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_app.m_lpDispatch == NULL);
}
编译环境是:Visual Studio 2005, Windows XP. Excel 2007.如下是关键部分的代码,求高人相助:
void CEx25dView::OnExceloleExecute()
{
LPDISPATCH pRange, pWorkbooks, pCommandBars;
CWnd* pWnd = CWnd::FindWindow("XLMAIN", NULL);
if (pWnd != NULL) {
TRACE("Excel window found\n");
pWnd->ShowWindow(SW_SHOWNORMAL);
pWnd->UpdateWindow();
pWnd->BringWindowToTop();
}
m_app.SetSheetsInNewWorkbook(1); VERIFY(pWorkbooks = m_app.GetWorkbooks());
m_workbooks.AttachDispatch(pWorkbooks); LPDISPATCH pWorkbook = NULL;
if (m_workbooks.GetCount() == 0) {
COleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
pWorkbook = m_workbooks.Add(covOptional);
}
LPDISPATCH pWorksheets = m_app.GetWorksheets();
ASSERT(pWorksheets != NULL);
m_worksheets.AttachDispatch(pWorksheets);
pCommandBars = m_app.GetCommandBars();
m_commandbars.AttachDispatch(pCommandBars);
int CommandBarCount = m_commandbars.GetCount();
TRACE("CommandBarCount = %d\n", CommandBarCount);
char buf[2048];
TRACE("TRUE %d, FALSE %d\n", TRUE, FALSE);
CommandBar oBar(m_commandbars.GetItem(COleVariant((short) 1))); // param 1(index 1) = Worksheet enu bar, equivalent to m_commandbars.GetActiveMenuBar(); sprintf(buf, "name:%s, nameLocal:%s, Context:%s, Height:%d, Index:%d, Left:%d, width:%d, Type:%d, Visual:%d, Enabled:%d \n"
, (LPCTSTR)(oBar.GetName()), (LPCTSTR)(oBar.GetNameLocal()), (LPCTSTR)(oBar.GetContext()), oBar.GetHeight(), oBar.GetIndex(), oBar.GetLeft(), oBar.GetWidth(), oBar.GetType(), oBar.GetVisible(), oBar.GetEnabled()); TRACE(buf);
oBar.SetEnabled(false); // no effect, Menubar still exists.
//oBar.SetVisible(false); // GOT OLEException
// cleanup
if (pWorkbook != NULL) {
pWorkbook->Release();
}
}
void CEx25dView::OnUpdateExceloleExecute(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_app.m_lpDispatch != NULL);
}void CEx25dView::OnExceloleLoad()
{ // if Excel is already running, attach to it, otherwise start it
LPDISPATCH pDisp;
LPUNKNOWN pUnk;
CLSID clsid;
TRACE("Entering CEx25dView::OnExcelLoad\n");
BeginWaitCursor();
::CLSIDFromProgID(L"Excel.Application.12", &clsid); // from registry
if(::GetActiveObject(clsid, NULL, &pUnk) == S_OK) {
VERIFY(pUnk->QueryInterface(IID_IDispatch,
(void**) &pDisp) == S_OK);
m_app.AttachDispatch(pDisp);
pUnk->Release();
TRACE(" attach complete\n");
}
else {
if(!m_app.CreateDispatch("Excel.Application.12")) {
AfxMessageBox("Excel 97 program not found");
}
TRACE(" create complete\n");
}
EndWaitCursor();
OnExceloleExecute() ;
}void CEx25dView::OnUpdateExceloleLoad(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_app.m_lpDispatch == NULL);
}
CommandBar::void PutVisible ( VARIANT_BOOL pvarfVisible );//Office 2003
//试试有没有这个函数,参数类型应该是COleVariant((short) 1)
搜索过程中曾注意到PutVisible, 但我生成的mso.h, mso.cpp (MicroSoft Office) 里面的CommandBar类是确实没有PutVisible这个函数的.只有SetVisible和GetVisible。
CommandBar.SetEnabled(false);
CommandBar.SetVisible(false);
之后,成功隐掉了,然而对于"Worksheet menu bar"束手无策