使用Windows消息循环实现回调实现

时间:2011-12-28 14:09:19

标签: c++ winapi mfc callback

我有C ++库(Win32控制台),我使用计时器实现了一个异步函数。异步方法返回设备信息。

我创建了一个单独的线程“Timer Thread”来创建一个隐藏窗口,然后我调用SetTimer()然后调用已实现的消息循环。

当计时器到期时,它会启用回调。

当我在控制台应用程序中使用该库时,它工作正常。

MFC应用程序中,我正在发布一条消息,以便在回调触发时更新用户界面。帖子消息无效。

如果我删除了库中的消息循环,它在MFC应用程序中正常工作。

我得出结论:

我猜问题是由于两个消息循环,一个MFC(主线程)和TimerThread消息循环。因此,当调用回调并且后续PostMessage导致TimerThread消息循环并且未在MFC(主线程)消息循环中报告时。

如果我删除了TimerThread消息循环,那么它在MFC应用程序中工作正常,但它无法在控制台应用程序中工作。

我如何克服这个问题?

class IDeviceEnumerationCallback
{
     public:
         virtual void onDeviceDiscovered(DeviceInfo* pDeviceInfo,unsigned short nNoOfDevice) = 0;
};

class IDeviceDiscovery
{
    public:
        virtual int InitialiseDiscovery(IDeviceEnumerationCallback*) = 0;

        virtual void UnInitialiseDiscovery() = 0;

        virtual int EnumerateDevice() = 0;
};

class CDeviceDiscovery:IDeviceDiscovery
{
    //Implementation
}

在MFC /控制台应用程序中,我正在实现IDeviceEnumerationCallback以获得回调。

我正在使用Bonjour API来枚举设备,而Bonjour API中的所有方法都是回调。

我在一段时间间隔内使用Bonjour API枚举设备然后在400毫秒后说我正在调用回调来返回结果。在调用回调的MFC应用程序中,我正在执行PostMessage()来更新用户界面。

早些时候我试过没有Windows消息泵。我有一个SetTimer函数,它正在使用MFC应用程序,但对于控制台应用程序,回调永远不会被调用,所以我在这里实现了一个消息泵。现在它不适用于MFC应用程序。

2 个答案:

答案 0 :(得分:0)

问题是您不应该创建隐藏窗口并使用SetTimer而应该使用MFC工作线程功能进行后台工作。

//You create a thread  like so.
// you need a CMyObject only if you need to pass any information
//to the thread function.
CMyObject *pNewObject = new CMyObject;
AfxBeginThread(MyThreadProc, pNewObject);


//This function will be run in separate thread
UINT MyThreadProc( LPVOID pParam )
{
    //The parameter that was passed to this function
    CMyObject* pObject = (CMyObject*)pParam;

    while( 1 )
    {
        //add your code to do stuff.

        Sleep(5000); //or whatever your SetTimer interval was 
    }

    return 0;   // thread completed successfully
}

答案 1 :(得分:0)

首先,没有理由做你做的事情:创建一个单独的线程,然后在其中创建一个窗口,设置窗口计时器,运行消息循环,响应WM_TIMER消息并调用回调。

如果你创建“你自己的”线程 - 你实际上并不需要这一切。如果你想要一个中止选项,你可以用Sleep(或WaitForXXXX)实现一个简单的循环,并调用你的回调。

通常会创建一个带有计时器的隐藏窗口,以避免创建其他线程。也就是说,在一个操作GUI的线程中(因此 - 运行消息循环),您创建一个窗口,它将由消息循环提供。实际上这是你可以在你的MFC应用程序中做到的。

但是,正如您所说,您需要MFC和控制台应用程序的通用代码。

  

在MFC应用程序中我正在发布消息以更新UI时   回调触发器。帖子消息不是wokring。

“diung post message”究竟是什么意思?消息应该发布到特定窗口或线程。在第一种情况下,它被分派到窗口过程,在第二种情况下,消息循环实现负责处理消息。

如果您将消息发布到特定窗口 - 您如何获得其处理(HWND)?它是您应用的主窗口(AfxGetMainWnd)吗?在MFC创建主窗口之后,或者更早之前,您的线程开始工作了什么?

我问所有这些问题,因为你似乎是一个新手(没有犯罪),这些都是典型的错误。