본문 바로가기

Win32 api

Win32 api 강의 49 - 50화.

- bfs 활용.

UI 에 대한 마우스 입력 처리를 수정함.

부모 UI 위에 자식 UI 가 있는 상황에서 자식 UI 에 클릭하거나 하면 두 UI 모두 이벤트가 호출되는 문제가 있음.

// CUIMgr.cpp
...
void CUIMgr::late_update()
{
    CScene* pCurScene = CSceneMgr::GetInstance()->GetCurScene();

    if (pCurScene)
    {
        // 현재 씬의 부모 UI 객체들을 가져와서 마우스 입력 검사 수행.
        const vector<CObject*>& vecUI = pCurScene->GetObjByGroup(GROUP_TYPE::UI);
        for (CObject* pObj : vecUI)
        {
            CUI* pUI = dynamic_cast<CUI*>(pObj);

            if(pUI == nullptr)
                continue;

            // 부모 UI로부터 포커스를 받는 자식 UI를 찾아서 마우스 입력 검사 수행.
            if(CUI* pTargetUI = GetTargetUI(pUI))
            {
                UIMouseCheck(pTargetUI);
                continue;
            }
        }
    }
}

 

그래서 부모 UI 포인터를 기준으로 자식들을 탐색하여 최하단의 자식 UI를 선택한다. 

이 최하단 자식 UI 에 입력 처리를 해줌.

// CUIMgr.cpp
...
CUI* CUIMgr::GetTargetUI(CUI* pUI)
{
    if(pUI == nullptr)
        return nullptr;

    static queue<CUI*> qUI;
    // 기존 포커스 UI 에 대한 button release 처리해줘야 함.
    bool bLButtonRelease = KEYRELEASECHECK(KEY::LBUTTON);

    // 큐 초기화
    while (!qUI.empty())
        qUI.pop();

    qUI.push(pUI);

    CUI* pTargetUI = nullptr;

    while (!qUI.empty())
    {
        CUI* pCurrentUI = qUI.front();
        qUI.pop();

        if(pCurrentUI == nullptr)
            continue;

        // 현재 UI가 마우스 hover 상태라면, 포커스를 받는 UI로 설정
        if (pCurrentUI->IsMouseHover() || pCurrentUI->IsLButtonDown())
        {
            // 기존 포커스 UI에 대한 button release 처리
            if (pTargetUI && bLButtonRelease)
            {
                if (pTargetUI->IsLButtonDown())
                {
                    pTargetUI->OnLButtonUp();
                }
            }
            
            // 최종 포커스 UI 갱신
            pTargetUI = pCurrentUI;
        }
        // 자식 UI들을 큐에 추가
        const vector<CUI*>& vecChildUIs = pCurrentUI->GetChildUIs();
        for (CUI* pChildUI : vecChildUIs)
        {
            qUI.push(pChildUI);
        }
    }

    return pTargetUI;
}

 

원리는 간단하게 bfs 를 활용한다. 

모든 자식을 탐색하면서 pTargetUI 포인터를 갱신해줌.

 

pTargetUI 포인터를 변경할 때 유의할 점: 버튼이 release 됐을 때, 기존 타겟 UI 가 눌린 상태였다면, 

그리고 다른 UI 로 포커스가 변경된다면 button up 처리를 해줘야 함.

 

안그러면 부모 UI 에서 누른 상태에서 자식 UI 에서 떼면, 부모 UI 는 눌린 상태로 유지되기 때문에 문제가 생김.

'Win32 api' 카테고리의 다른 글

Win32 api 강의 52화.  (0) 2025.09.26
Win32 api 강의 51화.  (0) 2025.09.25
Win32 api 강의 48화.  (0) 2025.09.24
Win32 api 강의 47화.  (0) 2025.09.24
Win32 api 강의 46화.  (0) 2025.09.24