65.9K
CodeProject 正在变化。 阅读更多。
Home

PowerPoint 定时器(加载项)

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2012 年 8 月 7 日

CPOL

4分钟阅读

viewsIcon

49115

downloadIcon

2519

PowerPoint 2007 的计时器时钟 (PPT 插件)。

介绍 

在我的工作场所,我们有很多员工会议。在这些会议上,我们使用 PowerPoint 演示文稿。我们中的一个人演示新闻——几分钟后,其他人就睡着了。我认为这种情况对于任何在大公司工作的人来说都很熟悉。我的想法是用一个计时器时钟来控制演讲时间。解决方案是一个计时器时钟插件,显示在演示文稿的顶部。

背景 

本文有助于学习

  • 如何制作 Office (在本例中是 PowerPoint) 插件
  • 如何将图像存储为资源
  • 如何在 PowerPoint 中使用新的功能区和任务窗格
  • 如何使用特殊的用户控件(这是一个包含按钮、复选框和其他视觉控件的容器)
  • 如何捕捉屏幕的一部分,并直接绘制图像 

Using the Code

这段代码不是很简单。理解它的最好方法是研究我的代码并仔细阅读我的注释。要启动插件,您必须启动一个新项目并选择 PowerPoint 插件。在本例中,我选择了 PowerPoint2007 插件。

它将创建一个原始模板。我们必须订阅特殊的 PowerPoint 事件

((PowerPoint.EApplication_Event)this.Application).SlideShowBegin += 
    new PowerPoint.EApplication_SlideShowBeginEventHandler(ThisAddIn_SlideShowBegin); 
((PowerPoint.EApplication_Event)this.Application).SlideShowEnd += 
   new PowerPoint.EApplication_SlideShowEndEventHandler(ThisAddIn_SlideShowEnd);
((PowerPoint.EApplication_Event)this.Application).SlideShowNextSlide += 
   new PowerPoint.EApplication_SlideShowNextSlideEventHandler(ThisAddIn_SlideShowNextSlide);

在这个程序中,我创建了自己的类,名为 Ido,位于 class1 文件中。这个类只有一个部分,所以实际上这只是一个类型集合。然后我定义了静态属性和方法。该程序在一个部分中使用它: 

Ido myido = new Ido();

orapercmasodperc 属性表示计时器的小时、分钟和秒值。这个类控制时钟的数字、颜色、表面和其他属性。它将时间数字转换为数字,并制作一个图像,即计时器时钟的真实表面。透明情况有点棘手:在我放置新时钟之前,我必须像这样保存屏幕的原始部分

public Image CaptureImage(int x, int y, int width, int height, int HWND)
{
    //in fact not desktop, but screen with given by HWND.
    //In our explample will be the SlightShowWindow.
    int desktop_win = HWND;

    //Gets the DC of SlightShowWindow
    int desktop_dc = GetDC(desktop_win);
    //Defines new bitmap
    Bitmap bm = new Bitmap(width, height);
    //Defines new Graphics
    Graphics bm_gr = Graphics.FromImage(bm);

    //Gets the new Graphics handle, because BitBlt using handles.
    IntPtr bm_hdc = bm_gr.GetHdc();
    //BitBlt copies graphics(given by handle) with normal copy (SRCCOPY)
    BitBlt(bm_hdc, 0, 0, width, height, (IntPtr)desktop_dc, x, y, SRCCOPY);

    // Release the bitmap's  and desktop's DCs.
    bm_gr.ReleaseHdc(bm_hdc);
    ReleaseDC(desktop_win, desktop_dc);

    // Return the result image.
    Image i = (Image)bm;

    return i;

}

我使用旧的 C++ 方法,但它有一个很大的优势:它有效。我尝试使用 .NET 函数捕获屏幕的一部分,但没有成功。  这有可能改进。

另一个技巧是重新着色数字。我从资源中加载原始图片,然后重新着色它。

从资源文件中加载原始图片是这样完成的

//Loads original PNG-s from project-resources
private void loadpng()
{
    png0 = new Bitmap(SecondPointAddIn1.Properties.Resources.nullt);
    png1 = new Bitmap(SecondPointAddIn1.Properties.Resources.egyt); 

逐位更改数字的颜色(原始颜色是:“#FFB219”)

//Method for change color of the digits
private void changecolor(Bitmap bmp)
{
    //Goes across the bitmap by columns
    for (int x = 0; x < bmp.Width; x++)
    {
        //Goes across the bitmap by points
        for (int y = 0; y < bmp.Height; y++)
        {
            //If the bitmap pixel color matches the oldcolr then change
            if (bmp.GetPixel(x, y) ==  ColorTranslator.FromHtml("#FFB219"))
            {
                bmp.SetPixel(x, y, newcolor);
            }
        }
    }
}

在主程序(ThisAddin 文件)中,我使用了一个计时器。该计时器每 50 毫秒滴答一次。它控制 1 秒是否已经过去。如果没有,它什么都不做。如果是,它将减少时间。如果时间到了,停止计数。如果时间值为一分钟或五秒钟,则开始播放声音效果。这个声音效果我也存储在资源文件中。

幻灯片放映的开始将启动计时器并设置参数(时间、颜色透明度等): 

void ThisAddIn_SlideShowBegin(PowerPoint.SlideShowWindow Wn)
{
    //set up the timer parameters from myusercontrol1 
    //Set timer hour from myusercontrol 
    NumericUpDown nu = (NumericUpDown)myUserControl1.Controls["numericUpDown1"];
    myido.ora = (int)nu.Value;
    ...
    ti.Start //Starts the timer

幻灯片放映的结束将停止计时器

void ThisAddIn_SlideShowEnd(PowerPoint.Presentation Pres)
{
    //Stops the timer.
    ti.Stop();
}

新幻灯片设置新的幻灯片标志:如果时钟是透明的,我们必须保存原始显示

void ThisAddIn_SlideShowNextSlide(PowerPoint.SlideShowWindow Wn)
{
    //Sets the newslide indicator to true. It uses only when
    //the clock is transparent . If not, it's not important.
    myido.newslide = true;
}

if (myido.newslide == true && myido.transparent == true)
{
    //See captureimage in class1.
    myido.oldimage = myido.CaptureImage(pngx, pngy, myimage.Width, myimage.Height, Wn.HWND);
    //oldimage saved, it is no more new slide
    myido.newslide = false;
}

要设置参数,我创建了一个新的功能区。获得它的最佳方法可以在这篇文章中找到:http://msdn.microsoft.com/en-us/library/bb386104.aspx。您可以像这样将功能区添加到您的应用程序:右键单击项目,添加新项目,功能区(Visual Designer)。之后,您可以设计您的新功能区。

要添加新的用户控件,方法是类似的(右键单击,添加等,新用户控件)。我制作了 MyUserControl 来包含计时器的设置参数。然后程序将这些参数存储在注册表中。无论起始参数是否设置,它们都将获得默认参数,并在幻灯片放映开始时写入注册表。

这些参数将在用户控件启动时读取: 

private void MyUserControl_Load(object sender, EventArgs e)
{
    //Reads the walues from the registry - if it can
    RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\HR\\PPTtimer");

    try
    {
        //Starting values of hour, min, sec, etc....
        numericUpDown1.Value = (int)key.GetValue("Hour", RegistryValueKind.DWord);
        numericUpDown2.Value = (int)key.GetValue("Min", RegistryValueKind.DWord);
        numericUpDown3.Value = (int)key.GetValue("Sec", RegistryValueKind.DWord);
        ... 

如果注册表为空,则捕获异常, 并填充默认值

catch (Exception)
{
    //Hour
    numericUpDown1.Value = 0;
    //Min
    numericUpDown2.Value = 3;

最后,我制作了一个“关于”框来宣传自己。

兴趣点 

我将这篇文章提供给对 Office 插件感兴趣的人。我认为这种方式与创建任何其他插件非常相似,例如 Excel 或 Word。方法相同,功能区、用户控件也相同,当然,原始事件是特定的。

历史

这是 1.0 版。它适用于 PowerPoint 2007。

© . All rights reserved.