代码改变世界

DirectUI消息循环的简单封装

2013-11-09 13:56  Clingingboy  阅读(1133)  评论(0编辑  收藏  举报

 

一.真窗体和假窗体

首先在DirectWindow内部创建一个真窗体(基于WTL),可以接收消息

class CMessageWindow : public CWindowImpl< CMessageWindow >
{
public:
    CMessageWindow();
    ~CMessageWindow();
    BEGIN_MSG_MAP( CMessageWindow )
        MESSAGE_RANGE_HANDLER( 0, 0xFFFF, HandleMessage )
    END_MSG_MAP()
}

然后在在HandleMessage 处理消息

image

二.通过MessageDispatcher转发消息

image

三.组装给上层比较容易理解的数据结构

image

这样上层就捕捉不到WM_LBUTTONUP消息,而变成自己封装的DirectUI_LButtonUp消息了

全部伪代码

class EventArg
{
public:
    int nId;
};

class MouseEventArg:public EventArg
{
public:
    int nX;
    int nY;
    int uKeyFlags;
};

class MessageDispatcher
{
    MessageDispatcher(DirectWindow *pWindow)
    {
        m_pWindow=pWindow;
    }

    void DispatcherLButtonUp(POINT pt,UINT uKeyFlags,BOOL *pbHandled)
    {
        MouseEventArg arg;
        arg.nId=DirectUI_LButtonUp;
        arg.nX=pt.x;
        arg.nY=pt.y;
        m_pWindow->OnMessage(&arg);
    }

private:
    DirectWindow *m_pWindow;
};

class CMessageWindow : public CWindowImpl< CMessageWindow >
{
public:
    CMessageWindow();
    ~CMessageWindow();
    BEGIN_MSG_MAP( CMessageWindow )
        MESSAGE_RANGE_HANDLER( 0, 0xFFFF, HandleMessage )
    END_MSG_MAP()

    virtual    LRESULT            HandleMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled );

private:
    MessageDispatcher *m_pMessageDispatcher;
}

void CMessageWindow::OnLButtonUp( HWND hWnd, int nX, int nY, UINT uKeyFlags, BOOL& bHandled )
{
    POINT pt = {nX, nY};
    ::ClientToScreen(hWnd, &pt);

    m_pMessageDispatcher->DispatcherLButtonUp(pt, uKeyFlags, &bHandled)
}

class IElement;

class DirectWindow
{
    HRESULT OnMessage( IElement *pElement, EventArg *pArg, BOOL* pbHandled);
private:
    CMessageWindow *m_pMessageWindow;
};