将Powerpoint演示文稿嵌入到C#应用程序中

5
我希望能够在C#表格(WinForms)中嵌入PowerPoint演示文稿。我们有一台52英寸的监视器,想要在一个角落里循环播放PPT,而另外三个角落将显示程序本身的信息。
我认为这应该是很简单的,但似乎我错了。
我曾被建议使用WebBrowser控件,但它不起作用,反而将PowerPoint文件视为下载,即给我一个“保存、打开”对话框。
有什么建议吗?
AK

1
你的应用程序是否必须与演示文稿交互?否则,你可以尝试在虚拟机中运行ppt... - Adam
1
请参见http://stackoverflow.com/questions/10955496/powerpoint-2010-multiple-instances/11737090#11737090。 - TFD
4个回答

8
您可以直接运行PowerPoint,获取窗口句柄,然后使用SetParent函数设置新的父窗口。
你只需要知道PowerPoint窗口的窗口类名称,但由于Spy++的存在,这不是什么大问题。

spy++


这是 PowerPoint 运行在自定义应用程序“内部”的截图:

PowerPoint


完整示例(取自此处并修改为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);
}

这很不错,但是否有类似的方法只运行幻灯片展示,而不是整个环境? - KingCronus
PowerPoint中有一个设置,可以在窗口模式下运行幻灯片,而不是全屏模式。然后它看起来就像这样:链接。也许这已经足够让你感到满意了 :-) - sloth
我相信您也可以仅显示PowerPoint窗口的幻灯片部分。您需要使用GetDlgItem来获取PowerPoint窗口的MDIClient子控件,然后从该控件中获取"Slide" paneClassDC控件。但我没有测试过这个方法。 - sloth
我已经使用你提供的内容作为基础,但是我稍微修改了一下,因为我要尝试使用 .pps 文件。这样当 PowerPoint 运行时,它会直接启动全屏模式,并使用窗口类 "screenClass"。这似乎有点起作用(自动定时只有在屏幕有焦点时才能工作等)。感谢你让我走上了正确的轨道,如果一切顺利,我会给你贡献奖励。 - KingCronus

2
一个嵌入式Active/X控件的PowerPoint查看器应该是一个不错的选择 - 您可以尝试使用这个(显然它不能工作 - 请参见评论)或这个
请参见此处以在Windows Forms应用程序中嵌入Active/X控件。
如果您计划显示PowerPoint的窗口大小不会改变,您也可以将PowerPoint幻灯片转换为位图,然后仅显示位图。

尽管我已经尝试了很多次,但我仍然无法让那个ActiveX控件正常工作。它的版本是2007年的,我怀疑它是否还能正常运行。至于位图,这将会很麻烦,因为我们的想法是让最终用户能够轻松更新Powerpoint。 - KingCronus
我自己没有尝试过那个 Active/X 控件 - 在我看来,那似乎是正确的方法,你有没有尝试寻找其他的控件(通过谷歌搜索可以得到一些结果 - 我在回答中添加了一个链接)?关于位图“技巧”,应该可以编写脚本让 PowerPoint 自动生成位图。 - MiMo
感谢您的帮助,但我找到的每个控件要么不能与Powerpoint 07及以后版本一起使用,要么价格过高。除此之外,如果可能的话,我不想使用ActiveX。 - KingCronus

0

我真的不知道是否可以在winforms中嵌入ppt查看器。我还有一个建议:使用浏览器控件(或下载一个支持更好的HTML5的webkit),并使用像impress.js这样的js库来呈现演示文稿。只是一个想法。


不幸的是,在这种情况下,客户提供幻灯片,并且他们需要能够经常而容易地使用PowerPoint进行更改。 - KingCronus
Impress.js看起来很有趣,也许我得尝试一下用它做些别的东西! - KingCronus

0

最初由@danish发布,此处

请查看链接。你也可以在WebBrowser控件中显示PPT。这个也可能很有用。

基本上它允许你在WebBrowser控件中打开ppt,并且你可以轻松地嵌入它。如果你需要更多信息,请告诉我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接