请问如何用VC操作PowerPoint,读写PowerPoint页面的备注页中的文本?自己写了一段读写代码,但是有问题,没有完成备注页文本的读写。

scq2099yt 2008-05-06 04:15:17
首先感谢您以前给我解答了问题,现在又要麻烦您了。

开发工具是:VC6.0
应用方向是:读写Office PowerPoint 2003备注页中的文本

采用您以前给我的建议,参考了VBA帮助中的实现步骤。
VBA中往备注页中写入字符串的代码如下:
ActivePresentation.Slides(1).NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.InsertAfter "My first Nodes Page"
我参考VBA的过程,用VC写的读写备注页的代码如下:

// 相关变量定义
_Application app;
Presentations Presentations;
_Presentation Presentation;
Slides slides;
_Slide slide;

// 启动PowerPoint
app.CreateDispatch("Powerpoint.Application"))
app.SetVisible(TRUE);

// 打开PowerPoint
static char BASED_CODE szFilter[] = "PowerPoint Files (*.ppt)|*.ppt||";
CFileDialog FileDlg(TRUE,"PPT",NULL,OFN_FILEMUSTEXIST|OFN_NONETWORKBUTTON
|OFN_PATHMUSTEXIST,szFilter);
FileDlg.DoModal();
CString strFileName;
strFileName = FileDlg.GetPathName();
Presentations = app.GetPresentations();
Presentation = Presentations.Open(strFileName,0,0,1);

// 写备注页,在第一页的备注页中写入字符串“My first Nodes Page”
Presentation = app.GetActivePresentation();
slides = Presentation.GetSlides();
slide = slides.Range(COleVariant((long)1));
//slide = slides.Item(COleVariant((long)1)); // 注释掉上句,启用这句出现的情况是一样的
Shapes shapes = slide.GetNotesPage();
Shape shape= shapes.GetPlaceholders();
TextFrame textFrame(shape.GetTextFrame());
// 程序执行到此弹出异常:TextFrame.TextRange:Invalid request. Nothing appropriate is currently selected.
TextRange textRange(textFrame.GetTextRange());
textRange.SetText("My first Nodes Page");

// 读备注页,读取第一页的备注页中的字符串“My first Nodes Page”
CString strText = _T("");
Presentation = app.GetActivePresentation();
slides = Presentation.GetSlides();
slide = slides.Range(COleVariant((long)1));
//slide = slides.Item(COleVariant((long)1)); // 注释掉上句,启用这句出现的情况是一样的
Shapes shapes = slide.GetNotesPage();
Shape shape= shapes.GetPlaceholders();
TextFrame textFrame(shape.GetTextFrame());
// 程序执行到此弹出异常:TextFrame.TextRange:Invalid request. Nothing appropriate is currently selected.
TextRange textRange(textFrame.GetTextRange());
strText = textRange.GetText();

为了让代码更加简洁我省略了异常处理和退出的代码。
上面的代码执行就会出现异常:
TextFrame.TextRange:Invalid request. Nothing appropriate is currently selected.
并且无法读写备注页中的文本。


问题:请问问题出在哪儿,应该如何改写才能实现读写备注页的功能?


谢谢!
如果分不够可以再加。
再次感谢!
...全文
1117 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
rocchetta 2011-11-18
  • 打赏
  • 举报
回复
请问是怎么解决的呢?在网上搜了很久,大多没有结尾
n70joey 2010-11-25
  • 打赏
  • 举报
回复
很好,mark
CSharpProgrammer 2010-07-07
  • 打赏
  • 举报
回复
我最近也在找这方面的资料。
CSharpProgrammer 2010-07-07
  • 打赏
  • 举报
回复
我最近也在找这方面的资料。
scq2099yt 2008-05-09
  • 打赏
  • 举报
回复
谢谢胡大哥这几天的指导,问题已经解决了,结贴啦。
scq2099yt 2008-05-08
  • 打赏
  • 举报
回复
可能是我COM知识太薄弱吧,MSPPT的那些接口参数和返回值类型看起来都很晦涩。
scq2099yt 2008-05-08
  • 打赏
  • 举报
回复
还有就是GetNotesPage()和GetPlaceholders()返回类型或者返回值不知道如何得到,因为MSPPT中这两个函数的返回类型都是LPDISPATCH,至于返回值调试的时候得到的都是地址值,其中GetNotesPage()返回的是0x001614e4,GetPlaceholders()返回的是0x00161864,shapes和shape返回的都是void。
scq2099yt 2008-05-08
  • 打赏
  • 举报
回复
呵呵,谢谢,我刚才发现个问题:
我的理解是备注页和幻灯片应该不是平级的,备注页是幻灯片的下级,通过下面的代码分析出来的:
ActivePresentation.Slides(1).NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.InsertAfter "My first Nodes Page"
在当前演示文稿的第一张幻灯片备注页的第二个占位符(备注区)中插入文本。
而我的代码:
Shapes shapes(slide1.GetNotesPage()); //这句是不是有问题
微软知识库的文章中是用Shapes shapes(slide1.GetShapes()); 获得幻灯片需要写入字符的区域,而我是将备注页的区域作为写入字符的区域,我的想法可能没问题,但是可能代码实现有问题,再就是GetNotesPage()是不是获得幻灯片的备注页,在msppt中我找不到备注页的影子也就这个函数有点像。
请胡大哥指教。
jameshooo 2008-05-08
  • 打赏
  • 举报
回复
只能看VBA帮助,office也只提供了这个帮助,然后把vba语法转换成C++语法
scq2099yt 2008-05-08
  • 打赏
  • 举报
回复
呵呵,胡大哥说得对,肯定是有用法问题,只是不知道PPT开发帮助在哪儿可以找到,是不是就是VBA帮助,这个帮助估计跟C++的用法还是有很大差距的,尽管思路是一样的。
scq2099yt 2008-05-08
  • 打赏
  • 举报
回复
是啊,英雄所见略同阿,VBA其实是微软自己封装简化了很多操作,但是如果要用VC实现就得好好研究它的那堆COM接口了,而且还没有帮助说明,那些接口连MSDN中都查不到。
我倒是看到有个公司做的软件有写入PPT备注页字符串的功能,只是不知道他怎么做的,说白了还是我研究得不够深入透彻阿。
jameshooo 2008-05-08
  • 打赏
  • 举报
回复
微软的恶心之处就在于此,office仅仅提供vba帮助,而且帮助做得很差,很不方便查询,最好还是靠vba先做测试。
scq2099yt 2008-05-07
  • 打赏
  • 举报
回复
顺便问一下胡大哥转行干嘛去了,不搞技术了岂不是CSDN的一大损失。呵呵,交个朋友吧。
scq2099yt 2008-05-07
  • 打赏
  • 举报
回复
返回的都是地址值。
shape.GetTextFrame()如下:
result 0X00161bf4
IUnknown
__vfptr 0X776735e0
[0] 0X7760723f
[1] 0X77607234
[2] 0X77607229

执行到textFrame.GetTextRange()就进入WINCORE.CPP里了,具体就是进入到下面的函数中了:
LRESULT AFXAPI AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg,
WPARAM wParam = 0, LPARAM lParam = 0)
{
_AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
MSG oldState = pThreadState->m_lastSentMsg; // save for nesting
pThreadState->m_lastSentMsg.hwnd = hWnd;
pThreadState->m_lastSentMsg.message = nMsg;
pThreadState->m_lastSentMsg.wParam = wParam;
pThreadState->m_lastSentMsg.lParam = lParam;

#ifdef _DEBUG
if (afxTraceFlags & traceWinMsg)
_AfxTraceMsg(_T("WndProc"), &pThreadState->m_lastSentMsg);
#endif

// Catch exceptions thrown outside the scope of a callback
// in debug builds and warn the user.
LRESULT lResult;
TRY
{
#ifndef _AFX_NO_OCC_SUPPORT
// special case for WM_DESTROY
if ((nMsg == WM_DESTROY) && (pWnd->m_pCtrlCont != NULL))
pWnd->m_pCtrlCont->OnUIActivate(NULL);
#endif

// special case for WM_INITDIALOG
CRect rectOld;
DWORD dwStyle = 0;
if (nMsg == WM_INITDIALOG)
_AfxPreInitDialog(pWnd, &rectOld, &dwStyle);

// delegate to object's WindowProc
lResult = pWnd->WindowProc(nMsg, wParam, lParam);

// more special case for WM_INITDIALOG
if (nMsg == WM_INITDIALOG)
_AfxPostInitDialog(pWnd, rectOld, dwStyle);
}
CATCH_ALL(e)
{
lResult = AfxGetThread()->ProcessWndProcException(e, &pThreadState->m_lastSentMsg);
TRACE1("Warning: Uncaught exception in WindowProc (returning %ld).\n",
lResult);
DELETE_EXCEPTION(e);
}
END_CATCH_ALL

pThreadState->m_lastSentMsg = oldState;
return lResult;
}
然后就会执行到CATCH_ALL(e)中,返回的错误提示就是:TextFrame.TextRange:Invalid request. Nothing appropriate is currently selected.

如果在watch窗口中查询textFrame.GetTextRange()的值就会程序就会崩溃掉,出现这样的错误:
MSDEV.EXE - 应用程序错误
“0x00000000”指令引用的“0x00000000”内存。该内存不能为“read”。
要终止程序,请单击“确定”。
要调试程序,请单击“取消”。

然后确定VC就被强制结束掉了。

jameshooo 2008-05-07
  • 打赏
  • 举报
回复
看样子用法有问题,真的要去查PPT开发帮助,我猜测slide1.GetNotesPage()返回的可能不是Shapes类型的对象,或者shapes.GetPlaceholders()返回的不是Shape类型的对象,总之对象搞错了后变量的值肯定是NULL
jameshooo 2008-05-07
  • 打赏
  • 举报
回复
是不是textFrame.GetTextRange()返回的是NULL?跟踪一下
scq2099yt 2008-05-07
  • 打赏
  • 举报
回复
下面是微软知识库中提供的VC操作PPT,创建PPT页面并向PPT页面中写入字符串的代码:

// Start PowerPoint.
_Application app;
COleException e;
if(!app.CreateDispatch("Powerpoint.Application", &e)) {
CString str;
str.Format("CreateDispatch() failed w/err 0x%08lx", e.m_sc),
AfxMessageBox(str, MB_SETFOREGROUND);
return;
}

// Make it visible.
app.SetVisible(TRUE);

// Get Presentations collection and add a new presentation.
Presentations presSet(app.GetPresentations());
_Presentation pres(presSet.Add(TRUE));

// Get Slides collection and add a new slide.
Slides slideSet(pres.GetSlides());
_Slide slide1(slideSet.Add(1, 2));

// Add text to slide, by navigating the slide as follows:
// slide1.shapes(#).TextFrame.TextRange.Text
{
Shapes shapes(slide1.GetShapes());
//Shapes shapes(slide1.GetNotesPage());
Shape shape(shapes.Item(COleVariant((long)1)));
//Shape shape(shapes.GetPlaceholders());
TextFrame textFrame(shape.GetTextFrame());
TextRange textRange(textFrame.GetTextRange());
textRange.SetText("My first slide");
}

上面的代码能成功的写入字符串到PPT页面,我只是将上面大括号中的代码稍微改动为注释符所在行的代码就会出错了。
也是这个异常:TextFrame.TextRange:Invalid request. Nothing appropriate is currently selected.

其实写入PPT页面和写入备注页只是类型不一样而以,然后我模仿VBA并参照上面的改法为什么就会出错呢?
scq2099yt 2008-05-07
  • 打赏
  • 举报
回复
跟进去后就是msppt的源文件了,我上面调用的函数都没有参数,只是用调用函数的返回值再赋值给左边,返回值的类型都是IDispatch*。

jameshooo 2008-05-07
  • 打赏
  • 举报
回复
应该是转化的问题,是不是某些参数类型不对,单步跟踪进去看看
scq2099yt 2008-05-07
  • 打赏
  • 举报
回复
刚才用VBA试了,可以写入字符串"My first Nodes Page" ,运行一次写入一个,运行多次就写入多个。
是不是我的转化步骤哪儿有问题?
加载更多回复(7)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧