아이템 영역, 비 아이템 영역에 따른 마우스 오른쪽 버튼 Context 메뉴 출력




  트리컨트롤과 마찬가지로 리스트 컨트롤에서 출력되어 있는 아이템 위에서 마우스 오른쪽 버튼을
클릭 하였을때 팝업 되는 Context 메뉴와 아이템 영역이 아닌 곳에서 클릭 하였을 경우 팝업되는
Context 메뉴가 다르게 하고 싶은 경우가 있습니다.

예를 들어 Windows 의 이벤트 뷰어를 확인해 보면 두가지 상황에 따라 다른 Context 메뉴를 출력하고 있습니다.

- 아이템 위에서 Context 메뉴 출력



- 아이템 영역이 아닌 곳에서 Constext 출력






■ ListView 에서의 구현
void ChRmtEvwrView::OnNMRClick(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR);
    UNREFERENCED_PARAMETER(pNMItemActivate);

    CPoint CurrentPosition;
    ::GetCursorPos(&CurrentPosition);

    INT nIndex = -1;
    CListCtrl &ListCtrl = GetListCtrl();
    
    ListCtrl.ScreenToClient(&CurrentPosition);
    nIndex = ListCtrl.HitTest(CurrentPosition);

    if (-1 == nIndex)
    {
        // 아이템 영역이 아닌 곳에서 마우스 오른쪽 버튼을 선택한 경우
    }
    else
    {
        // 아이템 영역에서 마우스 오른쪽 버튼을 선택한 경우
    }
...

    ::GetCursorPos(&CurrentPosition);
    CMenu MenuTemp;
    CMenu *pContextMenu = NULL;
    MenuTemp.LoadMenu(IDR_MENU1);
    pContextMenu = MenuTemp.GetSubMenu(0);
    pContextMenu->TrackPopupMenu(TPM_LEFTALIGN, CurrentPosition.x, CurrentPosition.y, ::AfxGetMainWnd());

    *pResult = 0;


 


::GetCursorPos() 함수를 이용하여 마우스 커서의 Screen 영역에서의 마우스  위치를 구하게 됩니다.
리스트 컨트롤에서 마우스로 선택한 곳이 아이템이 있는 영역인지 확인 하기 위해서는 CListCtrl::HitTest()
함수를 사용합니다. CListCtrl::HitTest() 함수는 인수로 Screen 영역에서의 마우스 위치가 아닌 Client 영역
에서의 마우스 위치를 전달해야 하므로 CListCtrl::ScreenToClient() 함수로 변경해 주어 인수로 전달해야
합니다.

이렇게 하여 CListCtrl::HitTest() 함수의 리턴값으로 마우스가 위치한 곳의 아이템의 인덱스가 리턴이 됩니다.
만약 마우스가 위치한 곳에 아이템이 없다면 -1 을 리턴하게 됩니다.





cf) Screen 좌표, Client 좌표

Posted by six605
,