5

I create an OLE instance of PowerPoint and send commands to it:

procedure ExportSlide(const SlideIndex : Integer);
var
  ppt : Variant;
begin
  ppt := GetActiveOleObject('Powerpoint.Application');  
  ppt.ActivePresentation.Slides.Item(SlideIndex).Export('c:\test.png', 'PNG', 640, 480);
  ppt := Unassigned;
end;

This code works very well with all PowerPoint versions (2000, 2002, 2003, 2007, 2010).

However PowerPoint 2013 sometimes loses focus. We can no longer change slides using keyboard. We must click on full screen slide to restore focus.

Comments: Is it an official bug in PowerPoint 2013?
Answers: Any fix or workaround?

rjobidon
  • 3,055
  • 3
  • 30
  • 36
  • This posting in a help forum for Apple indicates that there was a problem introduced by an update to PowerPoint which caused a number of people problems with losing keyboard focus. They found that going back to a previous version they did not see the problem. It appears there has been an update since that corrected the problem. See http://answers.microsoft.com/en-us/mac/forum/macoffice2011-macpowerpoint/keyboard-becomes-unresponsive-during-powerpoint/6719901b-18b1-48d8-b585-9d9a33956263 – Richard Chambers Sep 17 '14 at 03:36
  • One other question is whether there are other applications running that would grab the input focus. Do you have some kind of tool to see what application has the input focus that you can use to monitor what is going on? I am curious how you do the testing to verify that it works fine for other versions of PowerPoint. Are you installing earlier versions on the same computer or what? – Richard Chambers Sep 17 '14 at 03:43
  • The application Process Explorer may help with understanding what is taking the focus. http://en.wikipedia.org/wiki/Process_Explorer – Richard Chambers Sep 17 '14 at 04:11
  • Hi Richard, problem is with PowerPoint 2013 on Windows, not on Mac. Good idea ti use Process Explorer! The problem is I'm not able to always reproduce this issue... On my system it's intermittent, while on other computers it's more frequent. – rjobidon Sep 18 '14 at 03:24

2 Answers2

4

As a workaround, try playing with Activate on Application and SlideShowWindow:

procedure ExportSlide(const SlideIndex : Integer);
var
  ppt : Variant;
begin
  ppt = GetActiveOleObject('Powerpoint.Application');  

  ppt.Activate();

  ppt.ActivePresentation.Slides.Item(SlideIndex).Export('c:\test.png', 'PNG', 640, 480);

  ppt.ActivePresentation.SlideShowWindow.Activate();

  ppt := Unassigned;
end;

If that doesn't help, you should be able to take ppt.HWND or ppt.ActivePresentation.SlideShowWindow.HWND (which is the raw Windows handle) and force the focus to it via AttachThreadInput/SetForegroundWindow as I described here.

Updated based on the comment, the Activate method doesn't solve the problem, but the AttachThreadInput/SetForegroundWindow one apparently does. The code from linked answer overrides the Windows policy of preventing the focus manipulation from a process which doesn't currently have the focus itself. This is achieved by attaching together the thread input queues of the calling process (the one which is performing the automation), the process being automated (PowerPoint) and the process which currently has the focus (which might be different from the other two).

Community
  • 1
  • 1
noseratio
  • 59,932
  • 34
  • 208
  • 486
  • Noseratio, can you explain AttachThreadInput/SetForegroundWindow in a separate answer *TODAY* for your bounty? While Activate() method doesn't give focus to PowerPoint when in background, second method brings PowerPoint on front and is very promising to solve lost of keyboard control. Thank you! – rjobidon Sep 24 '14 at 10:54
  • 1
    @rjobidon, glad it helped. I think it'd be more appropriate to update this answer (what I just did), let me know if I need to clarify any further details. – noseratio Sep 24 '14 at 11:13
0

I haved the same probleme and i solved with SetFocus api:

Public Declare Function SetFocus Lib "user32.dll" (ByVal hwnd As Long) As Long

Wn.View.Slide.Export filePath, "JPG"

Dim intSlideShowHWnd As Long

Dim result As Long

intSlideShowHWnd = FindWindow("screenClass", 0&)

result = SetFocus(intSlideShowHWnd)

user3161686
  • 281
  • 1
  • 3
  • 2