none
如何使用VSTO对PPT的复制操作进行控制?希望得到解答 RRS feed

  • 问题

  • 在工作中碰到对于office的二次开始,使用VSTO对于PPT的相关操作,就是复制一个对象时,想对这个对象的一些属性、方法进行操作。

    好像找不到,例如像复制事件什么的,只有复制方法,对于对象的简单操作,代码:

     PowerPoint.Slides slides = Globals.ThisAddIn.Application.ActivePresentation.Slides;

    for (int i = 1; i <= slides.Count; i++)
    {

    PowerPoint.Shapes shapes = slide.Shapes;

     for (int j = 1; j <= count; j++)
    {

     shapes[j].Copy();//复制该对象
     shapes[j].Delete();//删除该对象

    }

    }


    路漫漫其修远兮,吾将上下而求索!

    2013年2月6日 7:11

答案

  • 你好。

    因为你最初的那段代码看起来是逐一的复制一张幻灯片上的shape,然后删除。所以上一个回复里面的sample基本上是照着这个逻辑写的。

    而且,从你最近的回复

    对于shpes.Count的计数是变换的问题,已经注意到了,用一个变量保存就可以。

    看来,我不太确定我上一个回复的内容已经被完全理解,所以下面给出一张图示来描述我上个回复里

    当你 copy 然后 delete Shape 的时候,应该从index 最大的开始。即 for 循环应该从 j = count 开始, j >0 或者 j >= 1, j-- 这样。

    这句话的意义。

    正如你能在PowerPoint 2013对象模型引用里看到的那样。有的 object 有相应的Property、Method、Event,有的可能没有。Shape Object 就没有事件。

    根据你最新的回复

    就是获取一个shape对象,对其右键菜单复制或快捷方式复制,是否又可以控制的事件,可以做一个判断(即有的shape允许复制,有的shape不允许复制)。

    我推荐你看一下

    然后尝试重定义copy/paste。不过在此之前你可以先了解一下Ribbon XML

    希望有所帮助。

    谢谢。


    Quist Zhang [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已编辑 Quist Zhang 2013年2月19日 5:42
    • 已标记为答案 WANG XQ 2013年2月25日 5:21
    2013年2月19日 5:40

全部回复

  • 你好,

    PowerPoint 的Object Model Reference 可以到 http://msdn.microsoft.com/en-us/library/ff743835.aspx 参考。

    关于你的问题,我做了一个sample 传到了SkyDrive上。链接如下,

    https://skydrive.live.com/?cid=edf9c5f7cb70a004&id=EDF9C5F7CB70A004%21119&authkey=!AAqTnKC_2sL-JZc

    代码里特别提到了,当你 copy 然后 delete Shape 的时候,应该从index 最大的开始。即 for 循环应该从 j = count 开始, j >0 或者 j >= 1, j-- 这样。

    因为你把 shape[1] 删除之后,之前 index 为 2 的shape index 会自动的变成1.

    希望能有帮助。

    谢谢。


    Quist Zhang [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年2月7日 4:43
  • 看了源代码,谢谢你的回复,对于shpes.Count的计数是变换的问题,已经注意到了,用一个变量保存就可以。

    但好像不是想要的效果,可能描述不是很清晰。

    就是获取一个shape对象,对其右键菜单复制或快捷方式复制,是否又可以控制的事件,可以做一个判断(即有的shape允许复制,有的shape不允许复制)。

    或者将微软自带的复制禁用、去掉、或扩展编写自己的复制功能,或者可以重载微软的复制功能,有没有很好的解决办法。谢谢。

    参考资料:

    PowerPoint 2013 开发
    http://msdn.microsoft.com/zh-cn/library/office/fp161225.aspx

    PowerPoint 2013 开发人员参考 (机器翻译)
    http://msdn.microsoft.com/zh-cn/library/office/ee861525.aspx

    PowerPoint 2013对象模型引用 
    http://msdn.microsoft.com/zh-cn/library/office/ff743835.aspx

    PowerPoint 解决方案
    http://msdn.microsoft.com/zh-cn/library/vstudio/bb772069.aspx


    路漫漫其修远兮,吾将上下而求索!





    • 已编辑 WANG XQ 2013年2月19日 3:11
    2013年2月19日 3:03
  • 你好。

    因为你最初的那段代码看起来是逐一的复制一张幻灯片上的shape,然后删除。所以上一个回复里面的sample基本上是照着这个逻辑写的。

    而且,从你最近的回复

    对于shpes.Count的计数是变换的问题,已经注意到了,用一个变量保存就可以。

    看来,我不太确定我上一个回复的内容已经被完全理解,所以下面给出一张图示来描述我上个回复里

    当你 copy 然后 delete Shape 的时候,应该从index 最大的开始。即 for 循环应该从 j = count 开始, j >0 或者 j >= 1, j-- 这样。

    这句话的意义。

    正如你能在PowerPoint 2013对象模型引用里看到的那样。有的 object 有相应的Property、Method、Event,有的可能没有。Shape Object 就没有事件。

    根据你最新的回复

    就是获取一个shape对象,对其右键菜单复制或快捷方式复制,是否又可以控制的事件,可以做一个判断(即有的shape允许复制,有的shape不允许复制)。

    我推荐你看一下

    然后尝试重定义copy/paste。不过在此之前你可以先了解一下Ribbon XML

    希望有所帮助。

    谢谢。


    Quist Zhang [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已编辑 Quist Zhang 2013年2月19日 5:42
    • 已标记为答案 WANG XQ 2013年2月25日 5:21
    2013年2月19日 5:40
  • 谢谢回复。对于shapes.Count的问题,基本理解:

     PowerPoint.Slides slides = Application.ActivePresentation.Slides;//获取当前演示文稿所有幻灯片
                if (!IsHandler(slides))//所有对象是否处理过
                {
                    for (int i = 1; i <= slides.Count; i++)
                    {
                        PowerPoint.Slide slide = slides[i];
                        PowerPoint.Shapes shapes = slide.Shapes;
                        int count = shapes.Count;//shapes集合总数是变化的
                        for (int j = 1; j <= count; j++)
                        {
                            if (shapes[i].Name.Contains("PPT"))
                            {
                                shapes[j].Visible = Office.MsoTriState.msoFalse;//将原来多媒体隐藏
                                string picPath = "c:\\PPTAD.jpg";//替换的图片
                                AddPicture(slide, shapes[j], picPath);//替换图片
                            }
                        }
                    }
                }
    
      private void AddPicture(PowerPoint.Slide slide, PowerPoint.Shape shape, string filePath)
            {
                PowerPoint.Shape pic;
                pic = slide.Shapes.AddPicture(filePath, Office.MsoTriState.msoFalse, Office.MsoTriState.msoTrue, shape.Left, shape.Top, shape.Width, shape.Height);
                pic.Name = "AD" + shape.Name;
                pic.Height = shape.Height;
                pic.Width = shape.Width;
            }

    对于copy/paste的重写,在仔细看一下,谢谢你提供的资料,非常感谢。


    路漫漫其修远兮,吾将上下而求索!





    • 已编辑 WANG XQ 2013年2月19日 7:51
    2013年2月19日 7:42
  • 有没有更好的解决办法。相对于VSTO操作Word\Excel\Outlook可以自定义(或扩展)右键菜单。

    对于Word右键菜单项的获取:

            private void AddMenuBar()
            {
                Microsoft.Office.Core.CommandBarControls comBarControls = this.Application.CommandBars["cell"].Controls;

                Microsoft.Office.Core.CommandBarControl comBarControl = comBarControls.Add(Microsoft.Office.Core.MsoControlType.msoControlButton, missing, missing, missing, true);   //添加自己的菜单项
                Microsoft.Office.Core.CommandBarButton comBarButton = comBarControl as Microsoft.Office.Core.CommandBarButton;
                if (comBarButton != null)
                {
                    comBarButton.Tag = "TestTable";
                    comBarButton.Caption = "测试Table";
                    comBarButton.Style = Microsoft.Office.Core.MsoButtonStyle.msoButtonIconAndCaption;
                    comBarButton.Click += new Office._CommandBarButtonEvents_ClickEventHandler(comBarButton_Click);
                }
            }

            void comBarButton_Click(Office.CommandBarButton Ctrl, ref bool CancelDefault)
            {
                System.Windows.Forms.MessageBox.Show("TestClickSuccess!");
            }

    对于Excel的上下文菜单:(只需指定命令按钮name为"cell")

    Microsoft.Office.Core.CommandBar comBarControls = this.Application.CommandBars["cell"].Controls;

    对于Outlook的上下文菜单
    通过注册Application.ItemContextMenuDisplay事件,有两个参数:CommandBar对象和选中的邮件。在上下文菜单添加按钮,调用CommandBar.Controls.Add()。

    而且,对于Word中表格的命令也可以找到:(测试代码)

    Microsoft.Office.Core.CommandBarControls comBarControls = this.Application.CommandBars["Tables"].Controls;
                for (int i = 1; i < comBarControls.Count; i++)
                {
                    string accName = comBarControls[i].accName;
                    string caption = comBarControls[i].Caption;
                    string desp = comBarControls[i].DescriptionText;
                    string accDespp = comBarControls[i].accDescription;
                    MessageBox.Show(accName + "|" + caption + "|" + desp + "|" + accDespp);
                }
    就是说,指定name为Word对应的对象。原认为是根据选择对象来控制,但好像不是:

    选择文本:“Application.Selection.Text;”;选择表格集合:“Application.Selection.Tables;”。

    这样的话,对于PPT也应该有对应的菜单命令,指定其name,添加自定命令按钮,但是一直没找到对应的命令。

    初接触了解不是很多,希望大牛能能帮助一下,非常感谢。


    路漫漫其修远兮,吾将上下而求索!




    • 已编辑 WANG XQ 2013年2月21日 2:49
    2013年2月21日 2:33
  • 对于CommandBars的Name可以查找到了一个很老的版本:
    在 Excel 2000 中的内置命令栏控件的 ID 号列表

    虽然是Excel 2000的,而且不是PPT的可以发现,对于图片选中的右键菜单可以使用Pictures Context Menu或Shapes可以查找命令:

    使用上面的测试代码,可以找到对应的命令而且指定的值也是一样的,但是对一些命令进行操作好像没效果。

    如查到“复制”命令,使其Enabled为false,好像不起效果,很是不解?

    希望懂得大牛给些建议,谢谢。


    路漫漫其修远兮,吾将上下而求索!


    • 已编辑 WANG XQ 2013年2月22日 9:41
    2013年2月22日 9:40
  • 谢谢大牛的帮助,还是你的建议Ribbon XMLRepurpose Copy/Paste比较好用,谢谢你的帮助。

    上面的命令虽然都能找到,对2003兼容的,通过程序使用这些命令不是很好。

    测试了一下,使用Ribbon XML的形式控制更加灵活,而且这些命令都是对应多个命令控制的。

    自己又绕弯了,想的是利用键盘钩子控制快捷键的复制、粘贴,利用鼠标钩子控制鼠标右键上下文菜单,对于工具栏的复制、粘贴还没有好办法。

    使用Ribbon XML重写命令的操作,可以控制这三处:<commands>元素用来重复利用内置控件。还可以实现更丰富的功能。
    使用 Open XML 文件格式自定义 Office Fluent 功能区
    利用您自己的功能区选项卡和控件扩展 2007 Office System
    细品RibbonX(12):使用XML Notepad自定义功能区

    谢谢你的帮助,非常感谢!


    路漫漫其修远兮,吾将上下而求索!



    • 已编辑 WANG XQ 2013年2月25日 5:36
    2013年2月25日 5:30
  • 对于如何使用:

    VSTO处理PPT中复制

    对于PPT中添加对象,不仅可以添加文本框、图片、音频、视频,可以添加OLE对象,添加Word\Excel\PPT
    VSTOPPT中添加文本、图片


    路漫漫其修远兮,吾将上下而求索!

    2013年2月25日 6:07