一些上下文:我知道基本的C ++。我第一次尝试使用C ++ / CLI在Visual Studio中创建GUI应用程序。但是,我在网上找不到关于后者的答案。
我有两个类:MyForm
,对应于Windows窗体的主类,以及OtherClass
。 MyForm
有一个OtherClass
类型的对象作为成员。函数MyForm
,在此示例中为myButton_Click
,初始化此对象并在线程中调用其中一个函数:
using namespace System::Threading;
ref class MyForm;
ref class OtherClass;
public ref class MyForm : public System::Windows::Forms::Form {
public:
//...
private:
OtherClass^ o;
System::Void myButton_Click(System::Object^ sender, System::EventArgs^ e) {
//When the button is clicked, start a thread with o->foo
o = gcnew OtherClass;
Thread^ testThread = gcnew Thread(gcnew ThreadStart(o, &OtherClass::foo));
newThread->Start();
}
};
ref class OtherClass {
public:
void foo() {
//Do some work;
}
};
到目前为止,这似乎有效。我想要的是将某种回调函数从MyClass
传递到o->foo
,以便在foo
运行时使用.flex-info {
color: white;
font-family: 'Arial', sans-serif;
font-size: 16px;
box-shadow: 0px 2px 1px rgba(0,0,0,0.2);
padding: 10px;
border-radius: 2px;
width: 20%;
height: 100px;
text-align: center;
}
.flex-info.green {
background: #79B0B4;
}
.flex-info.blue {
background: #7993B4;
}
.flex-info.foam {
background: #79B47D;
}
.flex-info.pink {
background: #9B79B4;
}
.flex-info.red {
background: #B4797F;
}
更新UI。
最好的方法是什么?由于CLI,简单地传递函数指针不起作用。
答案 0 :(得分:0)
我已经开始工作了。然而,正如@Hans Passant指出的那样,这几乎模仿了BackgroundWorker
的行为。无论如何,下面是最热门问题的答案,没有使用BackgroundWorker
。但感觉不是很干净。
正如@ orhtej2所指出的,a delegate
is what's needed。要使上述两个头文件都能识别它,我必须在stdafx.h
中声明委托(如建议的here),例如:
delegate void aFancyDelegate(System::String^);
然后我将这样的委托传递给了OtherClass的构造函数,因此MyForm
中的对象初始化行从
o = gcnew OtherClass;
到
aFancyDelegate^ del = gcnew aFancyDelegate(this, &MyForm::callbackFunction);
o = gcnew OtherClass(del);
最后,为了能够更新callbackFunction
中的UI元素,即使它是从另一个线程调用的,它也必须包含类似这样的内容,如this answer中所示:
void callbackFunction(String^ msg) {
//Make sure were editing from the right thread
if (this->txtBox_Log->InvokeRequired) {
aFancyDelegate^ d =
gcnew aFancyDelegate(this, &MyForm::callbackFunction);
this->Invoke(d, gcnew array<Object^> { msg });
return;
}
//Update the UI and stuff here.
//...
}