2简介WindowImplBase的OnCreate()函数

1.简介

WM_CREATE是windows中一个窗口消息。当一个应用程序通过CreateWindowEx函数或者CreateWindow函数请求创建窗口时发送此消息,产生时间是窗口创建之后显示之前,同时WM_CREATE也必须是不进队列消息,(此消息在函数返回之前发送),此消息类似于SendMessage()所发送的消息。

2.简化

以下对WindowImplBase的OnCreate()函数(即WM_CREATE消息处理函数)进行简化,简化后如下:

LRESULT WindowImplBase::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    //将窗口设置为无标题栏的:WS_CAPTION
    //.......

    //重新调整窗口位置,将窗口移动到原来窗口的客户区位置处
    //.......

    m_PaintManager.Init(m_hWnd);
    m_PaintManager.AddPreMessageFilter(this);

    //获取并设置窗口文字及图片等资源的位置
    //.......

    m_PaintManager.SetResourcePath(strResourcePath.GetData());

    //解析资源,并将其中的布局xml解析成CControlUI树结构
    //.......

    CControlUI* pRoot = builder.Create(GetSkinFile().GetData(), (UINT)0, this, m_PaintManager);

    m_PaintManager.AttachDialog(pRoot);
    m_PaintManager.AddNotifier(this);

    m_PaintManager.SetBackgroundTransparent(TRUE);//设置背景透明

    InitWindow();//此函数为虚函数,想在窗口初始化干的事情可在该函数中实现
    return 0;
}

3.分解

注意上述函数的几个重要步骤(其中m_PaintManager为WindowImplBase的成员变量):

- m_PaintManager.Init(m_hWnd);
- m_PaintManager.AddPreMessageFilter(this);
- m_PaintManager.AttachDialog(pRoot);
- m_PaintManager.AddNotifier(this);

下面需要对上述四个函数进行解析

3.1 函数 Init()

void CPaintManagerUI::Init(HWND hWnd)
{
    ASSERT(::IsWindow(hWnd));

    // Remember the window context we came from
    m_hWndPaint = hWnd;
    m_hDcPaint = ::GetDC(hWnd);

    // We'll want to filter messages globally too
    m_aPreMessages.Add(this);
}

其中 m_aPreMessages 为静态成员变量,在以下函数中被用到(可以猜测以下为静态函数):

//设置颜色时,用于循环刷新界面
void CPaintManagerUI::SetHSL(bool bUseHSL, short H, short S, short L)
{
    //.......
    for( int i = 0; i < m_aPreMessages.GetSize(); i++ ) 
    {
        CPaintManagerUI* pManager = static_cast<CPaintManagerUI*>(m_aPreMessages[i]);
        if( pManager != NULL && pManager->GetRoot() != NULL )
            pManager->GetRoot()->Invalidate();
    }
}

//换肤,循环重新加载图片资源
void CPaintManagerUI::ReloadSkin()
{
    for( int i = 0; i < m_aPreMessages.GetSize(); i++ ) 
    {
        CPaintManagerUI* pManager = static_cast<CPaintManagerUI*>(m_aPreMessages[i]);
        pManager->ReloadAllImages();
    }
}

//CPaintManagerUI对消息进行提前处理
//该函数在void CPaintManagerUI::MessageLoop()中调用(此函数为进程的消息循环)
bool CPaintManagerUI::TranslateMessage(const LPMSG pMsg)
{
    //1.当窗口有父窗口时,循环搜索当前的hwnd所以对应的窗口或其长辈窗口(父窗口、祖父窗口);
    //2.当窗口无父窗口时,循环搜索当前的hwnd所以对应的窗口;
    //如果找到,则处理;否则直接返回false

    CPaintManagerUI* pT = static_cast<CPaintManagerUI*>(m_aPreMessages[i]);        

    if (pT->TranslateAccelerator(pMsg))
        return true;

    if( pT->PreMessageHandler(pMsg->message, pMsg->wParam, pMsg->lParam, lRes) ) 
        return true;

    return false;
}

3.2 函数 AddPreMessageFilter()

bool CPaintManagerUI::AddPreMessageFilter(IMessageFilterUI* pFilter)
{
    ASSERT(m_aPreMessageFilters.Find(pFilter)<0);
    return m_aPreMessageFilters.Add(pFilter);
}

其中 m_aPreMessageFilters 为非静态成员变量,在以下函数中被用到:

//消息的提前处理
//在bool CPaintManagerUI::TranslateMessage(const LPMSG pMsg)函数中被调用
bool CPaintManagerUI::PreMessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& /*lRes*/)
{
    for( int i = 0; i < m_aPreMessageFilters.GetSize(); i++ ) 
    {
        bool bHandled = false;
        LRESULT lResult = static_cast<IMessageFilterUI*>(m_aPreMessageFilters[i])->MessageHandler(uMsg, wParam, lParam, bHandled);
        if( bHandled ) 
        {
            return true;
        }
    }
    switch( uMsg ) 
    {
        case WM_KEYDOWN:
        case WM_SYSCHAR:
        case WM_SYSKEYDOWN:
    }
    return false;
}

3.3 函数 AttachDialog()

bool CPaintManagerUI::AttachDialog(CControlUI* pControl)
{
    //......

    //删除原来的控件树结构,重设控件树
    if( m_pRoot != NULL ) 
    {
        m_aPostPaintControls.Empty();
        AddDelayedCleanup(m_pRoot);
    }
    m_pRoot = pControl;

    //......

    //初始化控件
    return InitControls(pControl);
}

其中InitControls()的具体实现如下:

bool CPaintManagerUI::InitControls(CControlUI* pControl, CControlUI* pParent /*= NULL*/)
{
    ASSERT(pControl);
    if( pControl == NULL ) 
        return false;

    //重要、重要、重要
    pControl->SetManager(this, pParent != NULL ? pParent : pControl->GetParent(), true);
    pControl->FindControl(__FindControlFromNameHash, this, UIFIND_ALL);
    return true;
}

3.4 函数 AddNotifier()

bool CPaintManagerUI::AddNotifier(INotifyUI* pNotifier)
{
    ASSERT(m_aNotifiers.Find(pNotifier)<0);
    return m_aNotifiers.Add(pNotifier);
}

其中 m_aNotifiers 为非静态成员变量,在以下函数中被用到:

bool CPaintManagerUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRes)
{
    TNotifyUI* pMsg = NULL;
    while( pMsg = static_cast<TNotifyUI*>(m_aAsyncNotify.GetAt(0)) ) 
    {
        m_aAsyncNotify.Remove(0);
        if( pMsg->pSender != NULL ) 
        {
            if( pMsg->pSender->OnNotify ) pMsg->pSender->OnNotify(pMsg);
        }
        for( int j = 0; j < m_aNotifiers.GetSize(); j++ ) 
        {
            static_cast<INotifyUI*>(m_aNotifiers[j])->Notify(*pMsg);
        }
        delete pMsg;
    }

    // Cycle through listeners
    for( int i = 0; i < m_aMessageFilters.GetSize(); i++ ) 
    {
        bool bHandled = false;
        LRESULT lResult = static_cast<IMessageFilterUI*>(m_aMessageFilters[i])->MessageHandler(uMsg, wParam, lParam, bHandled);
        if( bHandled ) 
        {
            lRes = lResult;
            return true;
        }
    }

    // Custom handling of events
    switch( uMsg ) 
    {
        case WM_APP + 1:
        case WM_CLOSE:
        case WM_ERASEBKGND:
        case WM_PAINT: //重要,负责绘制窗口中的各个控件
        ....
    }

    pMsg = NULL;
    while( pMsg = static_cast<TNotifyUI*>(m_aAsyncNotify.GetAt(0)) ) 
    {
        m_aAsyncNotify.Remove(0);
        if( pMsg->pSender != NULL ) 
        {
            if( pMsg->pSender->OnNotify ) pMsg->pSender->OnNotify(pMsg);
        }
        for( int j = 0; j < m_aNotifiers.GetSize(); j++ ) 
        {
            static_cast<INotifyUI*>(m_aNotifiers[j])->Notify(*pMsg);
        }
        delete pMsg;
    }

    return false;
}

3.5 小结

//初始化PaintManager的句柄及画笔
//在PaintManager的静态成员变量中注册该窗口,在消息循环、换肤等中使用
- m_PaintManager.Init(m_hWnd); 

//注册该窗口,就可以调用该窗口的MessageHandler函数了
- m_PaintManager.AddPreMessageFilter(this);

//为窗口设置控件树,并初始化各个控件
//控件的绘制与此PaintManager种的画笔有很大关系
- m_PaintManager.AttachDialog(pRoot);

//注册上了Notify()函数,供PaintManager中的MessageHandler()函数调用
//PaintManager的MessageHandler()处理系统的各种消息,自己窗口不处理的消息均由此处理
- m_PaintManager.AddNotifier(this);

4.总结

NOTHING, END

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值