Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / productivity / Office

PowerPoint timer (addin)

5.00/5 (3 votes)
27 Oct 2012CPOL4 min read 48.6K   2.5K  
Timer clock for PowerPoint 2007 (PPT add-in).

Introduction 

In my workplace we have many staff meetings. In these meetings we use PowerPoint presentations. One of us demonstrates the news - and a few minutes after, the others are sleeping. I think this situation is very familiar to anyone who works in a big company. My idea was to control the time of speaking with a timer clock. The resolution is a timer clock add-in, shown on the top of the presentation.

Background 

This article is useful to learn:

  • How to make an Office (in this case PowerPoint) add-in
  • How to store images as resources
  • How to use the new Ribbon and task pane in PowerPoint
  • How to use a special user control (this is a container for buttons, checkboxes, and other visual controls)
  • How to capture a part of a screen, and draw images directly 

Using the Code

This code is not very simple. The best way to understand it is to study my code and carefully read my comments. To start an add-in, you have to start a new project and choose the PowerPoint add-in. In this example I chose PowerPoint2007 add-in.

It will make a raw template. We have to subscribe for special PowerPoint events:

C#
((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);

In this program, I made my own class, named Ido in the class1 file. This class has only one piece, so in fact this is only a type-collection. I then defined static properties and methods. The program uses it in one piece: 

C#
Ido myido = new Ido();

The ora, perc, masodperc properties represents the timer's hours, minutes, and seconds values. This class controls the digits, the colors, the face, and other properties of the clock. It converts the time-number to digits, and makes an image, the real face of the timer clock. The transparent case is a little bit tricky: before I place the new clock, I have to save the original part of the screen like this:

C#
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;

}

I use the old C++ methods, but it has a big advantage: it works. I tried to capture the part of the screen with .NET functions, but it was not successful.  This is a possibility to improve.

The other trick is recoloring of digits. I load the original pictures from the resource, then recolor it.

Loading the original pictures from the resource file is done like this:

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

To change the color of digits bit by bit (the original color is: "#FFB219"):

C#
//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);
            }
        }
    }
}

In the main program (ThisAddin file) I used a timer. This timer ticks every 50 ms. It controls if 1s have elapsed or not. If not, it does nothing. If yes, it will decrease the time. If the time is up, stop the counting. If the time value is one minute, or five seconds, start to play the sound effect. This sound effect I store in resource file as well.

The start of slide show will start the timer and set the parameters (time, color transparency, etc.): 

C#
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

The end of slideshow will stop the timer:

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

A new slide sets the new slide flag: if the clock is transparent, we have to save the original display:

C#
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;
}

and:

C#
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;
}

To set the parameters, I made a new Ribbon. The best way for it can be found in this article: http://msdn.microsoft.com/en-us/library/bb386104.aspx. You can add a Ribbon to your application like this: right click on project, Add new item, Ribbon (Visual Designer). After that, you can design your new ribbon.

To add a new user control, the method  is similar (right click, Add, etc., new user control). I made MyUserControl to contain the setting parameters of the timer. Then the program stores these parameters in the Registry. No matter if the starting parameters are set or not, they will get the default parameters, and write into the Registry when the slideshow starts.

The parameters will be read at the starting of the user control: 

C#
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);
        ... 

and catches an exception if the Registry is empty, and fills the default values:

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

And last, I made an About box to advertise myself.

Points of Interest 

I offer this article to those who are interested in Office add-ins. I think the way is very similar to creating any other add-in, e.g., Excel or Word. The methods are the same, the Ribbons, user controls are the same, and of course, the original events are specific.

History

This is the 1.0 version. It works with PowerPoint 2007.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)