防止在C#PowerPoint 2010加载项中复制对象

防止在C#PowerPoint 2010加载项中复制对象,c#,visual-studio-2010,add-in,powerpoint,C#,Visual Studio 2010,Add In,Powerpoint,我正在使用Visual Studio 2010构建一个PowerPoint 2010 C#加载项。外接程序的功能之一是向当前幻灯片添加形状。一旦形状被添加到幻灯片中,我需要防止它被复制。这就是我遇到问题的地方。我查看了所有应用程序级别的事件,没有看到任何类型的beforeCopy或beforePaste类型的事件 我现在能想到的唯一选项是添加一个按键事件监听器,以侦听“ctrl+c”,并在选择“我的形状”时阻止它,然后创建一个自定义右键单击菜单(甚至不确定是否可以),以在选择“我的形状”时删除“

我正在使用Visual Studio 2010构建一个PowerPoint 2010 C#加载项。外接程序的功能之一是向当前幻灯片添加形状。一旦形状被添加到幻灯片中,我需要防止它被复制。这就是我遇到问题的地方。我查看了所有应用程序级别的事件,没有看到任何类型的beforeCopy或beforePaste类型的事件

我现在能想到的唯一选项是添加一个按键事件监听器,以侦听“ctrl+c”,并在选择“我的形状”时阻止它,然后创建一个自定义右键单击菜单(甚至不确定是否可以),以在选择“我的形状”时删除“复制”选项。不过,必须有更简单的选择


有人知道我如何防止用户复制形状吗?

为了结束这一循环,我将分享我的工作,希望其他有此问题的人不会像我一样在这方面浪费太多时间。最后,我只是使用SlideSelectChanged和WindowsSelectionChange事件以及一个字典来删除我已复制的对象

首先,当我的形状被添加到stage时,我会在字典中添加一个新条目,其中包含形状名称(在我的例子中,它实际上是一组形状)及其ID

itemIDDictionary.Add(myGroup.Name, myGroup.Id);
WindowsSelectionChange是一个相当简单的检查。它只是查看新选择的项是否已经在字典中。如果是,则检查ID是否匹配。如果没有,则删除该项。这是因为复制和粘贴项目时,新粘贴的项目会自动在幻灯片上选中

public void itemSelectionChange(PowerPoint.Selection SelectedItem)
{
    try
    {
        if (Globals.Ribbons.Ribbon2.itemIDDictionary.ContainsKey(SelectedItem.ShapeRange.Name))
        {
            for (int shapeIDCount = 0; shapeIDCount < Globals.Ribbons.Ribbon2.itemIDDictionary.Count; shapeIDCount++)
            {
                if (!Globals.Ribbons.Ribbon2.itemIDDictionary.ContainsValue(SelectedItem.ShapeRange[1].Id))
                {
                    SelectedItem.Delete();
                    MessageBox.Show("You can not copy the browser object.\nAdd a new one using the ribbon bar");
                }
            }
        }
    }
catch {}
try
{
    if (SldRange.Count > 0)
    {
        var showWarning = false;
        for (int slideCount = 1; slideCount <= SldRange.Count; slideCount++)
        {
            int shapeCount = 1;
            while (shapeCount <= SldRange[slideCount].Shapes.Count)
            {
                if (Globals.Ribbons.Ribbon2.itemIDDictionary.ContainsKey(SldRange[slideCount].Shapes[shapeCount].Name))
                {
                    if (!Globals.Ribbons.Ribbon2.itemIDDictionary.ContainsValue(SldRange[slideCount].Shapes[shapeCount].Id))
                    {
                        SldRange[slideCount].Shapes[shapeCount].Delete();
                        showWarning = true;
                    }
                    else
                    {
                        shapeCount++;
                    }
                }
                else
                {
                    shapeCount++;
                }
            }
        }
        if(showWarning == true)
        {
            MessageBox.Show("You can not copy the browser object.\nAdd a new one using the ribbon bar");
        }
    }
}
catch { }
public void itemSelectionChange(PowerPoint.Selection SelectedItem)
{
尝试
{
if(Globals.Ribbons.Ribbon2.itemIDDictionary.ContainsKey(SelectedItem.shaperage.Name))
{
对于(int-shapeIDCount=0;shapeIDCount
SlideSelectChanged稍微复杂一点,因为我必须循环浏览幻灯片上的所有形状

public void itemSelectionChange(PowerPoint.Selection SelectedItem)
{
    try
    {
        if (Globals.Ribbons.Ribbon2.itemIDDictionary.ContainsKey(SelectedItem.ShapeRange.Name))
        {
            for (int shapeIDCount = 0; shapeIDCount < Globals.Ribbons.Ribbon2.itemIDDictionary.Count; shapeIDCount++)
            {
                if (!Globals.Ribbons.Ribbon2.itemIDDictionary.ContainsValue(SelectedItem.ShapeRange[1].Id))
                {
                    SelectedItem.Delete();
                    MessageBox.Show("You can not copy the browser object.\nAdd a new one using the ribbon bar");
                }
            }
        }
    }
catch {}
try
{
    if (SldRange.Count > 0)
    {
        var showWarning = false;
        for (int slideCount = 1; slideCount <= SldRange.Count; slideCount++)
        {
            int shapeCount = 1;
            while (shapeCount <= SldRange[slideCount].Shapes.Count)
            {
                if (Globals.Ribbons.Ribbon2.itemIDDictionary.ContainsKey(SldRange[slideCount].Shapes[shapeCount].Name))
                {
                    if (!Globals.Ribbons.Ribbon2.itemIDDictionary.ContainsValue(SldRange[slideCount].Shapes[shapeCount].Id))
                    {
                        SldRange[slideCount].Shapes[shapeCount].Delete();
                        showWarning = true;
                    }
                    else
                    {
                        shapeCount++;
                    }
                }
                else
                {
                    shapeCount++;
                }
            }
        }
        if(showWarning == true)
        {
            MessageBox.Show("You can not copy the browser object.\nAdd a new one using the ribbon bar");
        }
    }
}
catch { }
试试看
{
如果(SldRange.Count>0)
{
var showWarning=false;

对于(int slideCount=1;slideCount,可以禁用或重新路由Microsoft Office内置功能区按钮执行的命令。Microsoft将此称为“重新调整用途”,可以找到介绍

因此,另一种方法可能是使用类似的方式“重新调整”内置复制按钮的用途。(需要由GetCustomUI返回以自定义功能区,请参见上面的链接。)这将修改复制按钮执行的操作以及确定按钮是否启用的回调方法

<command idMso="Copy" onAction="copyAction" getEnabled="copyEnabled" />

执行
copyAction
以在选择形状时返回
cancelDefault=true
,这样就不会复制形状

如果选择了形状,则执行
copyEnabled
返回
false
。记住在选择更改事件中使按钮无效


实际上,这两种方法中的一种就足够了。我想,
onAction
更容易实现。

对于构建外接程序来说是非常新的,所以我肯定我很困惑。你指的是什么功能区复制按钮?我的功能区栏上没有复制按钮。我说的是内置的复制按钮,只是试图给出答案earer。感谢您的澄清。我将看看明天是否可以实施,因为它看起来简单多了。如果成功,我将向您更改正确答案。谢谢。因此,我决定不实施您的解决方案,因为我仍将必须循环浏览所选的每个对象,或者如果选择了多个幻灯片,则还要浏览每张幻灯片,以查看是否已选择d、 然后取消默认值。这就是我已经在做的事情,除了让它复制然后删除它的开销。它没有坏,所以我不会修复它。但是,如果我必须重写它,或者如果它是一个企业解决方案,我肯定会使用你的而不是我的。感谢分享。公平点,永远不要更改正在运行的系统:).再想一想,我意识到我的方法不会阻止用户通过拖动+Ctrl键复制形状。因此,您可能需要监听SelectionChanged事件,以获得一个简单的解决方案。