Как программно вызывать действие во время слайд-шоу Powerpoint?
Я могу автоматизировать сценарий Powerpoint с использованием кодированного пользовательского интерфейса и VSTO. В моей презентации PowerPoint я создал настройку "Действие" для формы для запуска блокнота. Во время показа слайдов мне нужно вызвать это действие, нажав на "текст/фигуру", чтобы он открыл файл notepad.exe. Может ли кто-нибудь помочь мне, как добиться этого. Я написал следующий код.
//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();
Это запустит слайд-шоу для презентации, и будет отображаться первый слайд, где будут определены параметры действия в форме. Теперь, как я могу запустить notepad.exe автоматически через API? к сожалению, кодированный пользовательский интерфейс не может обнаружить объекты в слайде. Таким образом, пользовательский интерфейс мыши может быть недоступен.
[Изменить]
Способный немного продвинуться вперед. Во время слайд-шоу у меня есть объект формы. Это расширение для вышеуказанного кода.
PowerPoint.SlideShowWindow oSsWnd = objPPT.ActivePresentation.SlideShowWindow;
PowerPoint.Shape oShape = oSsWnd.View.Slide.Shapes[1];
Ответы
Ответ 1
Не спрашивайте меня, почему С# ведет себя так, но это делает!
Вам нужно дважды выполнить команду, чтобы она работала...
Пробовал и тестировал
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();
}
НТН
Сид
Ответ 2
Это может быть более сложное решение, чем то, на что вы надеялись, но если бы вы могли каким-то образом определить координату X и Y вашего объекта "текст/форма" на экране (возможно, с помощью кодированных пользовательских интерфейсов и библиотек VSTO)?, вы можете использовать метод User32 "SendInput" для эмуляции перемещения мыши к местоположению объекта, а затем эмулировать щелчок мышью.
Вот код для эмуляции пользовательского ввода:
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();
И вот урезанная версия класса InputEmulator, который я использую для эмуляции действий Windows UI:
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;
}
}