I am automating a Powerpoint scenario using Coded UI & VSTO. In my powerpoint presentation I have created an 'Action' setting on a shape to launch notepad. During slideshow I need to invoke this action by clicking on the 'text/shape' so that it will open notepad.exe. Could anyone help me how to achieve this. I wrote the following code.
//To launch Powepoint
PowerPoint.Application objPPT = new PowerPoint.Application();
objPPT.Visible = Office.MsoTriState.msoTrue;
//Add new presentation
PowerPoint.Presentations oPresSet = objPPT.Presentations;
PowerPoint.Presentation oPres = oPresSet.Add(Office.MsoTriState.msoTrue);
//Add a slide
PowerPoint.Slides oSlides = oPres.Slides;
PowerPoint.Slide oSlide = oSlides.Add(1, PowerPoint.PpSlideLayout.ppLayoutTitleOnly);
//Add text
PowerPoint.TextRange tr = oSlide.Shapes[1].TextFrame.TextRange;
tr.Text = "Launch notepad";
tr.Select();
//Add Action settings on the shape
oSlide.Shapes[1].ActionSettings[PowerPoint.PpMouseActivation.ppMouseClick].Action = PowerPoint.PpActionType.ppActionRunProgram;
oSlide.Shapes[1].ActionSettings[PowerPoint.PpMouseActivation.ppMouseClick].Run = "c:\\windows\\notepad.exe";
//start slideshow
objPPT.ActivePresentation.SlideShowSettings.Run();
This will launch the slideshow for the presentation and the 1st slide 'where the action settings are defined on the shape' will be displayed. Now how can I launch notepad.exe automatically thru APIs? unfortunately coded UI cannot detect objects in a slide. So a UI mouse click option may not be possible.
[Edit] Able to make little bit progress. I have got shape object during slide show. This is extension to the above code.
PowerPoint.SlideShowWindow oSsWnd = objPPT.ActivePresentation.SlideShowWindow;
PowerPoint.Shape oShape = oSsWnd.View.Slide.Shapes[1];
Don't ask me why C# behaves like this but it does!
You have to issue the command twice for it to work...
private void button1_Click(object sender, EventArgs e)
{
//To launch Powepoint
PowerPoint.Application objPPT = new PowerPoint.Application();
objPPT.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;
//Add new presentation
PowerPoint.Presentations oPresSet = objPPT.Presentations;
PowerPoint.Presentation oPres = oPresSet.Add(Microsoft.Office.Core.MsoTriState.msoTrue);
//Add a slide
PowerPoint.Slides oSlides = oPres.Slides;
PowerPoint.Slide oSlide = oSlides.Add(1, PowerPoint.PpSlideLayout.ppLayoutTitleOnly);
//Add text
PowerPoint.TextRange tr = oSlide.Shapes[1].TextFrame.TextRange;
tr.Text = "Launch notepad";
//tr.Select();
//Add Action settings on the shape
oSlide.Shapes[1].ActionSettings[PowerPoint.PpMouseActivation.ppMouseClick].Action = PowerPoint.PpActionType.ppActionRunProgram;
oSlide.Shapes[1].ActionSettings[PowerPoint.PpMouseActivation.ppMouseClick].Run = @"C:\WINDOWS\system32\notepad.exe";
oSlide.Shapes[1].ActionSettings[PowerPoint.PpMouseActivation.ppMouseClick].Action = PowerPoint.PpActionType.ppActionRunProgram;
oSlide.Shapes[1].ActionSettings[PowerPoint.PpMouseActivation.ppMouseClick].Run = @"C:\WINDOWS\system32\notepad.exe";
//start slideshow
objPPT.ActivePresentation.SlideShowSettings.Run();
}
This might be a more complicated solution than what you were hoping for, but if you could somehow determine the X and Y coordinate of your "text/shape" object on the screen (perhaps with the Coded UI and VSTO Libraries?), you could use the User32 "SendInput" method to emulate moving the mouse to the location of the object and then emulate a mouse click.
Here is the code to emulate the user's input:
int x, y;
// ... First obtain the X and Y coordinate of the "text/shape" object from APIs
//
InputEmulator inputEmulator = new InputEmulator();
inputEmulator.MoveMouse(x, y);
inputEmulator.ClickMouse();
And here is a stripped down version of an InputEmulator class I use to emulate Windows UI actions:
class InputEmulator
{
private const int INPUT_MOUSE = 0;
private const uint MOUSEEVENTF_MOVE = 0x0001;
private const uint MOUSEEVENTF_ABSOLUTE = 0x8000;
private const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
private const uint MOUSEEVENTF_LEFTUP = 0x0004;
public void MoveMouse(int x, int y)
{
INPUT[] inp = new INPUT[1];
inp[0].type = INPUT_MOUSE;
inp[0].mi = createMouseInput(x, y, 0, 0, MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE);
SendInput((uint)1, inp, Marshal.SizeOf(inp[0].GetType()));
}
public void ClickMouse()
{
INPUT[] inp = new INPUT[2];
inp[0].type = INPUT_MOUSE;
inp[0].mi = createMouseInput(0, 0, 0, 0, MOUSEEVENTF_LEFTDOWN);
inp[1].type = INPUT_MOUSE;
inp[1].mi = createMouseInput(0, 0, 0, 0, MOUSEEVENTF_LEFTUP);
SendInput((uint)inp.Length, inp, Marshal.SizeOf(inp[0].GetType()));
}
[DllImport("user32.dll", SetLastError = true)]
private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
private static MOUSEINPUT createMouseInput(int x, int y, uint data, uint t, uint flag)
{
MOUSEINPUT mi = new MOUSEINPUT();
mi.dx = x;
mi.dy = y;
mi.mouseData = data;
mi.time = t;
//mi.dwFlags = MOUSEEVENTF_ABSOLUTE| MOUSEEVENTF_MOVE;
mi.dwFlags = flag;
return mi;
}
[StructLayout(LayoutKind.Explicit)]
private struct INPUT
{
[FieldOffset(0)]
public int type;
[FieldOffset(sizeof(int))] //[FieldOffset(8)] for x64
public MOUSEINPUT mi;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With