好吧,所以我遇到過一個不太類似的問題,但不是WPF,所以採取以下(非常哈希)的建議與一撮鹽。
下面的方法基本上創建了一個完全獨立的應用程序線程來運行directshow命令,但是告訴直接顯示使用您的WPF應用程序中託管的Windows窗體控件的句柄。
所以,首先我們需要一個虛擬的WinForms形成,我們可以用它來調用進行通話,但就是永遠不會得到渲染:
/// <summary>
/// Just a dummy invisible form.
/// </summary>
private class DummyForm : Form
{
protected override void SetVisibleCore(bool value)
{
//just override here, make sure that the form will never become visible
if (!IsHandleCreated)
{
CreateHandle();
}
value = false;
base.SetVisibleCore(value);
}
}
下一步是創建一個線程,我們可以把消息循環上:
//this will need to be a class level variable, since all the directshow
//calls will get invoked on this form
DummyForm dumbForm;
Thread separateThread;
private void CreateDummyForm()
{
ManualResetEvent reset = new ManualResetEvent(false);
//create our thread
separateThread = new Thread((ThreadStart)
delegate
{
//we need a dummy form to invoke on
dumbForm = new DummyForm();
//signal the calling method that it can continue
reset.Set();
//now kick off the message loop
Application.Run(dumbForm);
});
//set the apartment state of this new thread to MTA
separateThread.SetApartmentState(ApartmentState.MTA);
separateThread.IsBackground = true;
separateThread.Start();
//we need to wait for the windowing thread to have initialised before we can
//say that initialisation is finished
reset.WaitOne();
//wait for the form handle to be created, since this won't happen until the form
//loads inside Application.Run
while (!dumbForm.IsHandleCreated)
{
Thread.Sleep(0);
}
}
所以,一旦虛擬形式(和它的線程)已經創建,您可以在MTA 應用程序線程調用調用就像這樣:
/// <summary>
/// Blank delegate, used to represent any Invoke or BeginInvoke target method.
/// </summary>
public delegate void InvokeHandler();
//i'm assuming here that DSComponent is a class that all your directshow
//code is in, and externalControl is the WinForms control you have embedded in
//your application.
dumbForm.Invoke(new InvokeHandler(delegate
{
//maybe something like this?
DSComponent.Start(externalControl);
}));
//and to stop it...
dumbForm.Invoke(new InvokeHandler(delegate
{
DSComponent.Stop();
}));
然後,當你全部用DirectShow的東西做,關閉您的單獨的應用程序線程像這樣:
//to end the separate thread and application loop,
//just close your invisible form
dumbForm.Close();
這種方法的好處是,你整齊沙箱器directshow到一個單獨的線程。缺點是調用調用的上下文切換,加上另一個應用程序線程的開銷。你可能會有一些有趣的東西進入你當前的架構,但它應該有所幫助。
讓我知道你如何繼續下去,我很好奇它是如何工作的。
發佈代碼或發佈代碼說明?我會和第一個一起去。 – 2011-02-03 00:48:07