【问题标题】:Update GUI from another thread in Visual C++ 2008从 Visual C++ 2008 中的另一个线程更新 GUI
【发布时间】:2013-06-05 09:31:42
【问题描述】:

我正在开发一个程序,该程序需要我从另一个线程(而不是创建此 GUI 的主线程)更新我的 windows 窗体 GUI。我尝试使用:

rMainGUI->textBox3->Text = "TestDLL Try";
rMainGUI->textBox3->Update();

但是程序卡在了第一行。 如果我删除第一行,它会在运行时给我一个错误,说:

"Cross-thread operation not valid: Control 'textBox3' accessed from a thread other than the thread it was created on."

我想知道是否有一些简单的、线程安全的 UI 更新功能可以用来更新 GUI 而不会弄乱这些线程?或者,如果有一些命令我可以用来暂停当前线程,转到主线程,更新 GUI,然后返回当前线程?

以下是一些截图: Scr1 Scr2 Scr3

我对 C++ 有一定的了解,对线程有一点了解。 任何帮助将不胜感激。

【问题讨论】:

标签: user-interface c++-cli


【解决方案1】:

答案取决于您使用的 Windowin 库。通常它们提供一个函数,该函数将函数指针作为参数,将在主 UI 线程上运行。

这是相当常见的操作,“[windows framework] update ui thread”的快速谷歌应该会产生结果。

编辑:

好的,在 winforms 中你需要一个委托。委托是普通 c++ 中函数指针的等价物。那么你需要从 UI 线程调用它。

我建议你看看this question。基本上,您向您的表格询问InvokeRequired。这会询问表单“如果我尝试修改你,你会抛出对我无效的跨线程操作吗?”。如果是真的,那么你从 UI 线程创建委托和BeginInvoke 它。否则修改它是安全的。

【讨论】:

  • 您好 Eric,首先感谢您的帮助。你的意思是如果我在当前线程中调用某个函数,该函数会暂停当前线程,让其参数函数在主线程中运行?
  • 这应该异步完成。您告诉主线程您要运行一个函数,然后主线程将在有时间时运行它。您似乎正在使用带有 C++/CLI 的 Windows 窗体,是这样吗?如果不了解您的框架,就不可能确定如何做到这一点
  • 是的,这个程序是C++/CLI Windows Form Application。
【解决方案2】:

您可以尝试将 Windows 消息发布到窗口。

PostMessage((HWND)rMainGUI->textBox3->Handle.ToPointer(), WM_SETTEXT, 0, (LPARAM)L"TestDLL Try");

不确定 Windows 窗体控件的响应是否与旧控件相同,但值得一试。

【讨论】:

  • 嗨,马克。首先感谢您的帮助。我试过上面的命令。但是我收到以下 2 个错误: 'type cast' : cannot convert from 'System::IntPtr' to 'HWND'; “PostMessageW”:无法将参数 4 从“const wchar_t [12]”转换为“LPARAM”;没有可以进行这种转换的上下文;
  • 编译成功。然而,当程序运行到这一行时,错误弹出“跨线程操作无效:控件'textBox3'从创建它的线程以外的线程访问。”
  • @zhang835,如果连窗口句柄都不让你拿到,那我就放弃了。有什么方法可以从主线程获取该句柄并将其传递到您需要的地方?
  • rMainGUI 是一个全局静态实例,因此可以在我的程序中的任何位置使用。问题是 VC++ 似乎不允许从没有创建它们的线程访问组件。一个可能的解决方案是以某种方式回到主线程并让主线程更新 UI。但遗憾的是,我对如何做到这一点一无所知。有一些关于类似问题的帖子,但都是在 C# 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-13
相关资源
最近更新 更多