写了一个IM的底层库,把它用在客户端,要为客户端设计一个界面。但现在不知道如何来设计一个很好的API供上层界面调用。底层库主要负责接收和发送网络数据,对接收到的数据进行协议处理。呈现到界面上,就是有网络事件发生就在界面上表示。
这种功能的实现是通过回调函数来实现的。上层界面来实现这个回调函数,底层库则调用这个回调函数。我见到过的一种回调函数的设计是:回调函数只从底层库获得简单的消息(这个消息是文本格式,将到来的事件以文本方式通知上层界面),然后上层界面,在来解析这个消息,然后再调用PostMessage交给句柄来操作。 这种方式好处就是降低了底层库和上层界面的耦合度。底层和上层是分离的,没有用到底层的任何数据结构。另外,我想的一种方法是,通过回调函数,将窗口的句柄传到底层,这样可以用到底层的数据结构。如对于一个用户的联系人,在底层已经有结构体来记录,这样可以重用底层的代码,而不需要在上层重新建立结构体。大家都是如何解决这个问题的?可以聊聊。
有什么书和文章,代码可以参考的,谢谢!

解决方案 »

  1.   

    传递窗口句柄是一个不错的主意,能避免跨线程调用带来的麻烦,你可以在消息里面传递结构的指针,窗口过程解析这个结构数据做相应的呈现。记得传递指针时必须使用SendMessage,不能使用PostMessage
      

  2.   

    我在做过一个。
    界面在调用底层库API的时候如果需要回应,就注册一个窗口和消息。
    eg. CServer::GetUserInfo(UINT nUserID, HWND hRegWnd = NULL,UINT nMsg = 0);
    底层发送的时候为消息设置一个递增的ID,将其与注册的窗口和消息关联(如果不为NULL),可以用个表或者Map保存,服务器回复的时候带上ID,客户端就可以找到对这个回复信息感兴趣的窗口了。
    然后接收的时候用SendMessage会比较影响性能,因为会在对这个消息处理完才返回。
    所以消息的接收都是new一个结构体,然后::PostMessage(hRegWnd,nMsg,isAutoDelete,pStruct);由界面判断isAutoDelete然后释放内存。
      

  3.   

    UI 层 <-> 中间调度层 < - > 网络层
      

  4.   

    UI层向网络层注册消息回调。
    =========================
    agree on this.