我希望能夠將Powerpoint演示文稿嵌入到C#表單(WinForms)中。基本上我們有一個52英寸的顯示器,我們的想法是在一個角落我們將有一個PPT循環,然後其他三個角將顯示程序本身的信息。將Powerpoint演示文稿嵌入到C#應用程序
我原本以爲這是直截了當的,但似乎我錯了。
我被建議使用WebBrowser控件,但這不起作用,而是將該PowerPoint文件作爲下載對象,即給我一個「保存,打開」對話框。
有什麼建議嗎?
AK
我希望能夠將Powerpoint演示文稿嵌入到C#表單(WinForms)中。基本上我們有一個52英寸的顯示器,我們的想法是在一個角落我們將有一個PPT循環,然後其他三個角將顯示程序本身的信息。將Powerpoint演示文稿嵌入到C#應用程序
我原本以爲這是直截了當的,但似乎我錯了。
我被建議使用WebBrowser控件,但這不起作用,而是將該PowerPoint文件作爲下載對象,即給我一個「保存,打開」對話框。
有什麼建議嗎?
AK
您可以運行PowerPoint,獲取窗口句柄,並使用SetParent函數設置新的父窗口。
所有你需要的是窗口類PowerPoint窗口的名稱,但由於Spy++,這也沒什麼大不了的。
下面是PowerPoint中的屏幕截圖運行定製應用程序的 '內部':
完整的示例(從here截取和修改用於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 2012-07-09 09:25:56
PowerPoint中有一個設置可以在窗口模式而不是全屏模式下運行幻燈片。然後它會看起來像[this](http://imagebin.org/220050)。也許這足以讓你快樂:-) – sloth 2012-07-09 09:41:58
我相信你也可以只顯示PowerPoint窗口的幻燈片部分。您將不得不使用[GetDlgItem](http://msdn.microsoft.com/en-us/library/ms645481(VS.85).aspx)獲取PowerPoint窗口的「MDIClient」子控件,然後獲取該控件的''Slide'paneClassDC'控件。但我沒有測試這個。 – sloth 2012-07-09 09:47:50
我真的不知道羯羊有可能嵌入的WinForms一個PPT查看器。我還有一個其他的建議:使用瀏覽器控件(或者如果你想要更好的html5支持,請下載一個用於webkit的應用程序),並使用像impress.js這樣的js庫來呈現演示文稿。只是一個想法。
不幸的是,在這種情況下,客戶端正在提供powerpoint,他們需要能夠通過powerpoint輕鬆地進行頻繁更改。 – KingCronus 2012-07-06 11:19:54
Impress.js雖然看起來很有趣,但我可能不得不嘗試其他的東西! – KingCronus 2012-07-06 11:20:10
一個PowerPoint播放器是一個可嵌入的主動/ X控件應該要走的路 - 你可以嘗試this(顯然這是行不通的 - 見註釋)或this
於嵌入有源/ X控件見this在Windows窗體應用程序
如果您計劃顯示PowerPoint不改變大小,你也可以轉換的PowerPoint幻燈片成位圖,然後只顯示位圖
盡我所能,我一直無法讓ActiveX控件工作。它的日期是2007年,我想知道它是否有效。至於Bitmaps,這將是一個痛苦的想法是,最終用戶將能夠更新Powerpoint沒有太多的麻煩。 – KingCronus 2012-07-09 10:42:18
我沒有嘗試Active/X控制自己 - 這似乎是去我的方式,你有沒有嘗試尋找其他的(谷歌搜索它返回一些命中 - 我添加了一個鏈接到我的答案)?關於位圖'技巧',應該可以編寫PowerPoint腳本來自動生成位圖。 – MiMo 2012-07-09 11:04:14
感謝您的幫助,但是我發現a)的每一個控件都不適用於Powerpoint 07以上版本,或者成本過高。除此之外,如果我可以提供幫助,我並不想使用ActiveX。 – KingCronus 2012-07-09 12:21:28
您的應用程序是否必須與演示文稿進行交互?你也許可以在虛擬機上運行ppt,否則... – Adam 2012-07-09 08:12:20
請參閱http:// stackoverflow。com/questions/10955496/powerpoint-2010-multiple-instances/11737090#11737090 – TFD 2012-08-02 23:42:12