«
DUILIB切换窗口再切换回无焦点事件问题

时间:2023-8-25    作者:范文泉    分类: 编程


问题1:切换窗口后,再切换回来,文本框里的焦点丢失了

原因:因为切换窗口再切换回来后,窗口会有一个WM_SETFOCUS消息,但是DUILIB未对这个消息进行处理,因此窗口下面的所有子控件也不能获取到这个WM_SETFOCUS事件,自然不会做出响应。

解决方法:在CPaintManagerUI::MessageHandler的消息处理函数添加一个分支,响应WM_SETFOCUS,这里不能直接调用m_pFocus->SetFocus(),因为这个SetFocus函数里会判断当前的焦点控件和设置进行的焦点控件是否相同,如果相同就不会处理,因为在切换窗口时,DUILIB里保存了焦点控件,因此需要使用下面的方法。

case WM_SETFOCUS:
    {
        TEventUI event = { 0 };
        event.Type = UIEVENT_SETFOCUS;
        event.pSender = m_pFocus;
        event.dwTimestamp = ::GetTickCount();
        m_pFocus->Event(event);

        return true;
    }

这里虽然解决了切换窗口保持焦点的问题,但是又产生了新的问题,就是在用TAB切换有些控件时,要两次才能切换成功,原因是因为调用SetFocus后,会调用::SetFocus(m_hWndPaint),原焦点控件又会得到一次WM_SETFOCUS,因此把函数void CPaintManagerUI::SetFocus(CControlUI* pControl, bool bFocusWnd)的::SetFocus(m_hWndPaint);放到切换焦点后再执行,如下:

 if( pControl != NULL 
        && pControl->GetManager() == this 
        && pControl->IsVisible() 
        && pControl->IsEnabled() ) 
    {
        DUITRACE("Set focus to new control");
        m_pFocus = pControl;
        TEventUI event = { 0 };
        event.Type = UIEVENT_SETFOCUS;
        event.pSender = pControl;
        event.dwTimestamp = ::GetTickCount();
        m_pFocus->Event(event);
        SendNotify(m_pFocus, DUI_MSGTYPE_SETFOCUS);

        ::SetFocus(m_hWndPaint);
    }

问题2:窗口初始化设置了焦点控件,但是切换了窗口后,返回没有了。

通过在WM_SETFOCUS响应里打印当前控件的名称,发现在切换窗口时,窗口的焦点会切换到下一个控件上,切换窗口回自然会错,通过搜索SetNextTabControl查看哪些地方调用了这个函数,发现在CPaintManagerUI::MessageHandler的WM_PAINT里最可疑,在绘制窗体时,

 if( m_bFocusNeeded) {
      SetNextTabControl();
}

在将窗体最小化时再恢复会发送UIEVENT_WINDOWSIZE,这个里面UIEdit会调用SetFocusNeeded,使m_bFocusNeeded为TRUE,然后重绘的时候,就会SetNextTabControl切换到下一个焦点,导致文本框失败去焦点。初始分析这个代码可能是设置默认焦点的,因此将代码移动到下面

if( m_bFirstLayout ) {
    m_bFirstLayout = false;

    if (m_bFocusNeeded) {
    SetNextTabControl();
    }

    SendNotify(m_pRoot, DUI_MSGTYPE_WINDOWINIT,  0, 0, false);
    if( m_bLayered && m_bLayeredChanged ) {
        Invalidate();
        SetPainting(false);
        return true;
    }
}

标签: DuiLib 焦点 控件