C++ 在长时间处理过程中与GUI交互
我有一个阶级继承权: class BaseProcess { public virtual void Execute() = 0; }; class SubProcess : BaseProcess { public virtual void Execute() { //Do Something //Need to call back to the GUI here, maybe to get a file path from a file selector //Do Something Else //Now want to update the GUI with the progress of the operation perhaps //More processing } }; 类基进程 { 公共虚拟void Execute()=0; }; 类子进程:BaseProcess { 公共虚拟空执行() { //做点什么 //需要在这里调用GUI,可能需要从文件选择器获取文件路径 //做点别的 //现在想用操作的进度更新GUI吗 //更多处理 } }; 假设从GUI按钮事件处理程序创建并调用子流程对象 我的问题是,在Execute()函数中与GUI交互的最佳方式是什么?(还假设Execute()可能在不同的线程上运行) 我的想法是将回调传递到SubProcess对象,因为这样可以将信息发送到GUI,但是对于文件选择器,将数据返回到SubProcess对象的最佳方式是什么?我希望解决方案尽可能通用,以便根据请求返回不同类型的数据 注意:请忽略任何代码错误,我快速地将示例组装在一起只是为了说明问题 更新:C++ 在长时间处理过程中与GUI交互,c++,user-interface,mfc,C++,User Interface,Mfc,我有一个阶级继承权: class BaseProcess { public virtual void Execute() = 0; }; class SubProcess : BaseProcess { public virtual void Execute() { //Do Something //Need to call back to the GUI here, maybe to get a file path from a
很抱歉澄清,这将在Windows、MFC上进行。我不确定这有多重要,因为我认为总体设计应该适用于大多数GUI框架?取决于GUI。如果您在一个GUI允许您从不同线程控制它的系统上,那么您可以从Execute()中直接调用GUI。如果GUI不允许这样做,那么您可以通过消息与主线程通信,在那里进行GUI调用,并将结果返回给Execute()线程
一个可以直接实现这一点的GUI框架是,使用它。取决于GUI。如果您在一个GUI允许您从不同线程控制它的系统上,那么您可以从Execute()中直接调用GUI。如果GUI不允许这样做,那么您可以通过消息与主线程通信,在那里进行GUI调用,并将结果返回给Execute()线程 一个GUI框架,使用它的
getFilePath
和update
的实现将取决于您使用的平台/gui框架
class SubProcess : BaseProcess
{
public virtual void Execute()
{
//Do Something
char file_name[MAX_PATH +1];
myWindow->SendMessage(WM_GETFILE, max_path, (LPARAM)file_name);
//Do Something Else
myWindow->SendMessage(WM_UPDATE, 50);
//More processing
}
};
getFilePath
和update
的实现将取决于您使用的平台/gui框架
class SubProcess : BaseProcess
{
public virtual void Execute()
{
//Do Something
char file_name[MAX_PATH +1];
myWindow->SendMessage(WM_GETFILE, max_path, (LPARAM)file_name);
//Do Something Else
myWindow->SendMessage(WM_UPDATE, 50);
//More processing
}
};
在window类中:
#define WM_GETFILE (WM_USER+1)
#define WM_UPDATE (WM_USER+2)
BEGIN_MESSAGE_MAP(CMyWindow, CWnd)
ON_MESSAGE(WM_GETFILE, MyGetFileHandler)
ON_MESSAGE(WM_UPDATE, MyUpdateHandler)
END_MESSAGE_MAP()
LRESULT CMyWindow::MyGetFileHandler(WPARAM wParam, LPARAM lParam)
{
}
LRESULT CMyWindow::MyUpdateHandler(WPARAM wParam, LPARAM lParam)
{
}
在window类中:
#define WM_GETFILE (WM_USER+1)
#define WM_UPDATE (WM_USER+2)
BEGIN_MESSAGE_MAP(CMyWindow, CWnd)
ON_MESSAGE(WM_GETFILE, MyGetFileHandler)
ON_MESSAGE(WM_UPDATE, MyUpdateHandler)
END_MESSAGE_MAP()
LRESULT CMyWindow::MyGetFileHandler(WPARAM wParam, LPARAM lParam)
{
}
LRESULT CMyWindow::MyUpdateHandler(WPARAM wParam, LPARAM lParam)
{
}
我不久前使用的MFC技术是基于标准处理的 这是一种简单的方法,因为在主线程中运行时,工作人员可以直接对GUI对象进行操作 如果从工作进程调用消息循环“足够频繁”,GUI将保持平稳运行
如果你能负担得起开发周期中的一些复杂性,你可以使用线程来代替,但根据我的经验,这更困难。我不久前使用的MFC技术是基于标准处理的 这是一种简单的方法,因为在主线程中运行时,工作人员可以直接对GUI对象进行操作 如果从工作进程调用消息循环“足够频繁”,GUI将保持平稳运行
如果你能负担得起开发周期中的一些复杂性,你可以用线程来代替,但根据我的经验,这更难。threads。获取一个线程来完成真正的工作,并告诉它在完成后将结果发布回GUI。如果这是Windows,您可以使用SendMessage()。这很好,但是如果我想在执行过程中发布进度呢?另外,如果我需要从GUI输入,而不仅仅是输出到GUI,该怎么办?您可以使用SendMessage来完成这两项工作。您可以创建自定义消息(WM_USER+1等)并将其发送到您的窗口。您还可以传递一个char数组,并让窗口填充.Threads。获取一个线程来完成真正的工作,并告诉它在完成后将结果发布回GUI。如果这是Windows,您可以使用SendMessage()。这很好,但是如果我想在执行过程中发布进度呢?另外,如果我需要从GUI输入,而不仅仅是输出到GUI,该怎么办?您可以使用SendMessage来完成这两项工作。您可以创建自定义消息(WM_USER+1等)并将其发送到您的窗口。您还可以传递一个字符数组,并让窗口填充它。谢谢您的回答,不幸的是,我希望比这个更通用,这样我可以请求不同类型的数据,而不仅仅是字符串。@TomP89,您可以在
GuiCallback
中声明任意多个您喜欢的返回类型的函数,谢谢您的回答,不幸的是,我希望比这更通用,这样我可以请求不同类型的数据,而不仅仅是字符串。@TomP89,您可以在GuiCallback
中声明您喜欢的任何返回类型的函数,这正是我想要的解决方案,谢谢您还应该使用事件
,这样GUI线程在处理WM_GETFILE
消息时可以提醒工作线程。消息处理程序将包含一个SetEvent()
,工作线程将WaitForSingleObject()
,直到事件被设置为止。@japreiss SendMessage()将被阻止,因此不需要事件。这正是我所寻找的解决方案,感谢您还应该使用事件
,这样GUI线程在处理WM\u GETFILE
消息时可以提醒工作线程。消息处理程序将包含一个SetEvent()
,工作线程将WaitForSingleObject()
,直到事件被设置为止。@japreiss SendMessage()将被阻止,因此不需要事件。