I am trying to update a powerpoint slide with a lot of data (around 600 items). This was taking around 3 minutes.
If I load the shapes into memory up front, it still takes 35 seconds, so there's a lot of drawing time.
Excel has a simple means to get round this, but it's not so easy with ppt.
I found this post which supposedly uses VBA to suspend drawing and tried to convert it to C# (see below). The methods run without error, but don't stop drawing and don't increase the speed.
Is it possible using C# to suspend drawing in PowerPoint, then update the lot in one go, or is there any way to speed up updating PowerPoint shapes?
My C# Conversion attempt to suspend drawing:
public class PowerPointSuspendDrawing
{
// --------------------------------------------------------------------------------
// Converted from Shyam Pillai's code - see https://stackoverflow.com/questions/28511508/turn-off-screenupdating-for-powerpoint
// --------------------------------------------------------------------------------
// API declarations for FindWindow() & LockWindowUpdate()
// Use FindWindow API to locate the PowerPoint handle.
[DllImport("user32.dll", SetLastError = true)]
static extern long FindWindow(string lpClassName, long lpWindowName);
// Use LockWindowUpdate to prevent/enable window refresh
[DllImport("user32.dll", SetLastError = true)]
static extern long LockWindowUpdate(long hwndLock);
//Use UpdateWindow to force a refresh of the PowerPoint window
[DllImport("user32.dll", SetLastError = true)]
static extern long UpdateWindow(long hwnd);
/// <summary>
/// Should start/stop the screen updating
/// </summary>
/// <param name="state">false = stop animating, true = refresh</param>
/// <param name="fullVersionNumber">Microsoft.Interop.PowerPoint.Application.Version</param>
public void ScreenUpdating(bool state, string fullVersionNumber)
{
long hwnd = 0;
// will come in e.g. as 16.0
var versionNo = fullVersionNumber.Split('.')[0];
if ((state == false))
{
// Get handle to the main application window using ClassName
switch (versionNo)
{
case "8":
hwnd = FindWindow("PP97FrameClass", 0);
break;
case "9":
hwnd = FindWindow("PP9FrameClass", 0);
break;
case "10":
hwnd = FindWindow("PP10FrameClass", 0);
break;
case "11":
hwnd = FindWindow("PP11FrameClass", 0);
break;
case "12":
hwnd = FindWindow("PP12FrameClass", 0);
break;
case "14":
case "15":
case "16":
hwnd = FindWindow("PPTFrameClass", 0);
break;
default:
Console.WriteLine("Version not found. Version too new.");
break;
}
if ((hwnd == 0))
{
Console.WriteLine("Unable to get the PowerPoint Window handle");
}
// Lock the window
if ((LockWindowUpdate(hwnd) == 0))
{
Console.WriteLine("Unable to set a PowerPoint window lock");
}
}
else
{
// Unlock the Window to refresh
LockWindowUpdate(0);
UpdateWindow(hwnd);
hwnd = 0;
}
}
}
Approx Calling code.
PowerPointSuspendDrawing pptSuspension = new PowerPointSuspendDrawing();
pptSuspension.ScreenUpdating(false, myPresentation.CurrentApplication.Version);
// loop here
var shapeName = "box_number_" + boxNumber;
var thisShape = lookup[shapeName];
if (thisShape != null)
{
thisShape.TextFrame.TextRange.Text = "Bob";
}
// end loop
pptSuspension.ScreenUpdating(true, myPresentation.CurrentApplication.Version);