I want to be able to embed a powerpoint presentation into a C# form (WinForms). Basically we have a 52\' monitor, and the idea is that in one corner we will have a PPT on lo
You can just run PowerPoint, get the windows handle, and set a new parent window using the SetParent function.
All you need is the name of the window class of the PowerPoint window, but thanks to Spy++, this is no big deal.
Here's a screenshot of PowerPoint running 'inside' of a custom application:
Full example (taken from here and modified for PowerPoint):
public partial class Form1 : Form
{
public Form1()
{
this.Size = new System.Drawing.Size(800, 600);
this.TopMost = true;
this.Text = "My Application";
this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
Func<bool> run = () =>
Window.Find(hwnd =>
{
var cn = Window.GetClassName(hwnd);
var res = (cn == "PPTFrameClass");
if (res)
{
this.Controls.Clear();
Window.SetParent(hwnd, this.Handle);
Window.SetWindowPos(hwnd, new IntPtr(0), -8, -30, this.Width + 10, this.Height + 37, 0x0040);
}
return res;
});
new Button { Parent = this, Text = "Start" }
.Click += (s, e) =>
{
if (run() == false)
MessageBox.Show("Open PowerPoint");
};
}
}
public static class Window
{
public static bool Find(Func<IntPtr, bool> fn)
{
return EnumWindows((hwnd, lp) => !fn(hwnd), 0) == 0;
}
public static string GetClassName(IntPtr hwnd)
{
var sb = new StringBuilder(1024);
GetClassName(hwnd, sb, sb.Capacity);
return sb.ToString();
}
public static uint GetProcessId(IntPtr hwnd) // {0:X8}
{
uint pid;
GetWindowThreadProcessId(hwnd, out pid);
return pid;
}
public static string GetText(IntPtr hwnd)
{
var sb = new StringBuilder(1024);
GetWindowText(hwnd, sb, sb.Capacity);
return sb.ToString();
}
delegate bool CallBackPtr(IntPtr hwnd, int lParam);
[DllImport("user32.dll")]
static extern int EnumWindows(CallBackPtr callPtr, int lPar);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("User32", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndParent);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int W, int H, uint uFlags);
}
Originally posted by @danish, here.
See this link. You can also display the ppt in a WebBrowser control. This might also be useful.
Basically it allows you to open ppt as well, in a WebBrowser Control that you can embed easily. Let me know if you need more information about it.
A PowerPoint viewer that is an embeddable Active/X control should be the way to go - you can try this (apparently it does not work - see comments) or this
See this for embedding Active/X controls in Windows Forms applications
If the window where you plan to display the PowerPoint does not change size you could also convert the PowerPoint slides into bitmaps, and then just display the bitmaps
I really have no idea wether it is possible to embed a ppt-viewer in winforms. I do have one other suggestion for you: Use the browser control (or download one for webkit if you want better html5 support) and use a js library like impress.js to present the presentation. Just a thought.