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:
((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:
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:
public Image CaptureImage(int x, int y, int width, int height, int HWND)
{
int desktop_win = HWND;
int desktop_dc = GetDC(desktop_win);
Bitmap bm = new Bitmap(width, height);
Graphics bm_gr = Graphics.FromImage(bm);
IntPtr bm_hdc = bm_gr.GetHdc();
BitBlt(bm_hdc, 0, 0, width, height, (IntPtr)desktop_dc, x, y, SRCCOPY);
bm_gr.ReleaseHdc(bm_hdc);
ReleaseDC(desktop_win, desktop_dc);
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:
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"):
private void changecolor(Bitmap bmp)
{
for (int x = 0; x < bmp.Width; x++)
{
for (int y = 0; y < bmp.Height; y++)
{
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.):
void ThisAddIn_SlideShowBegin(PowerPoint.SlideShowWindow Wn)
{
NumericUpDown nu = (NumericUpDown)myUserControl1.Controls["numericUpDown1"];
myido.ora = (int)nu.Value;
...
ti.Start
The end of slideshow will stop the timer:
void ThisAddIn_SlideShowEnd(PowerPoint.Presentation Pres)
{
ti.Stop();
}
A new slide sets the new slide flag: if the clock is transparent, we have to save the original display:
void ThisAddIn_SlideShowNextSlide(PowerPoint.SlideShowWindow Wn)
{
myido.newslide = true;
}
and:
if (myido.newslide == true && myido.transparent == true)
{
myido.oldimage = myido.CaptureImage(pngx, pngy, myimage.Width, myimage.Height, Wn.HWND);
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:
private void MyUserControl_Load(object sender, EventArgs e)
{
RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\HR\\PPTtimer");
try
{
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:
catch (Exception)
{
numericUpDown1.Value = 0;
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.