C++ 在长时间处理过程中与GUI交互

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

我有一个阶级继承权:

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对象的最佳方式是什么?我希望解决方案尽可能通用,以便根据请求返回不同类型的数据

注意:请忽略任何代码错误,我快速地将示例组装在一起只是为了说明问题

更新:


很抱歉澄清,这将在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()将被阻止,因此不需要事件。