【发布时间】:2015-01-13 15:20:59
【问题描述】:
需要在 C++ 库中用 WPF 替换旧的 GUI 引擎。我无法控制应用程序主程序(实现 DLL),这意味着我无法控制线程模型(与 Walkthrough: Hosting WPF Content in Win32 相比)。由于 WPF 需要 STA,我知道我需要为它启动一个单独的线程,如下所示:
Thread^ t = gcnew Thread(gcnew ThreadStart(this, &ThreadClass::ThreadEntryPoint));
t->SetApartmentState(ApartmentState::STA);
t->Start();
ThreadEntryPoint() {
App^ app = gcnew App();
Window^ w = gcnew Window();
app->Run(w);
}
回到本机,旧的 GUI 引擎会这样做,这与 MFC 会做的类似:
Create dialog/window d;
d->SomeLabel->Caption = "abc";
d->ComboBox->Add(item);
etc...
d->ShowDialog(); // at which point control passes to user
和:
DialogClass:OnButtonPress() {
SomeLabel->Caption = "xyz";
}
一个。理想情况下,我希望能够对 WPF 使用如此简单的指令 (Control.property = x),但由于它位于单独的线程中,所以不可能,是吗?
b.为了能够在窗口出现之前操作 GUI 控件,我在 gcnew Window() 之后但在 app->Run(w) 和 Interupt() 主线程之前做了 Sleep(Infinite)。我使用了这个获取属性的示例(如何更改字段值?):
Type^ t = w->label1->GetType();
Object^ o = w->label1;
DispatcherObject ^dispObj = (DispatcherObject^)(o);
PropertyInfo ^propertyInfo = t->GetProperty( "Name" );
Object^ result = dispObj->Dispatcher->Invoke(gcnew Func<Object^,array<Object^>^, Object^>(propertyInfo, &PropertyInfo::GetValue), dispObj);
由于 WPF 线程处于睡眠状态而失败。当然,我可以为我设置的每个属性实现一个完整的睡眠/中断机制,但这似乎是糟糕的设计。
我的问题,假设 WPF 是要走的路,正确的实现方法是什么?
【问题讨论】:
-
如果可行,我会鼓励将 C++/CLI 限制为互操作 dll,并在 C# dll 中编写大部分核心 WPF 逻辑。以这种方式犯一个微妙的错误更具挑战性,而且它的构建速度so 快得多。 :)
标签: wpf multithreading c++-cli interop