duilib进阶教程 -- 改进List控件(3)_支持多选+右键菜单(ctrl,shift, 鼠标滑动框选)(二)

2014-11-24 10:10:34 · 作者: · 浏览: 2
SELECT, m_iCurSel, iOldSel);
}


return true;
}


bool CListUI::SelectRange(int iIndex, bool bTakeFocus)
{
int i = 0;
int iFirst = m_iCurSel;
int iLast = iIndex;
int iCount = GetCount();


if(iFirst == iLast) return true;
CControlUI* pControl = GetItemAt(iIndex);
if( pControl == NULL ) return false;
if( !pControl->IsVisible() ) return false;
if( !pControl->IsEnabled() ) return false;


IListItemUI* pListItem = static_cast (pControl->GetInterface(_T("ListItem")));
if( pListItem == NULL ) return false;
if( !pListItem->Select(true,false) ) {
m_iCurSel = -1;
return false;
}
EnsureVisible(iIndex);
if( bTakeFocus ) pControl->SetFocus();
if( m_pManager != NULL ) {
m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMSELECT, iIndex, m_iCurSel);
}
//locate (and select) either first or last
// (so order is arbitrary)
while(i if(i==iFirst || i == iLast){
i++;
break;
}


CControlUI* pControl = GetItemAt(i);
if( pControl != NULL) {
IListItemUI* pListItem = static_cast (pControl->GetInterface(_T("ListItem")));
if( pListItem != NULL ) pListItem->Select(false,false);
}
i++;
}


// select rest of range
while(i CControlUI* pControl = GetItemAt(i);
if( pControl != NULL) {
IListItemUI* pListItem = static_cast (pControl->GetInterface(_T("ListItem")));
if( pListItem != NULL ) pListItem->Select(true,false);
}
if(i==iFirst || i == iLast){
i++;
break;
}
i++;
}


// unselect rest of range
while(i CControlUI* pControl = GetItemAt(i);
if( pControl != NULL) {
IListItemUI* pListItem = static_cast (pControl->GetInterface(_T("ListItem")));
if( pListItem != NULL ) pListItem->Select(false,false);
}
i++;
}


return true;
}


2 鼠标滑动框选

业务逻辑:鼠标左键或右键按下,开始滑动,出现方框,列表项跟着选中或不选中。

设计思路:检测鼠标按下(UIEVENT_BUTTONDOWN,UIEVENT_RBUTTONDOWN),移动(UIEVENT_MOUSEMOVE),抬起(UIEVENT_BUTTONUP,UIEVENT_RBUTTONUP),还有上下文菜单(UIEVENT_CONTEXTMENU)。

按下时,设定标志位,记录初始点;移动时画框,并根据框与列表项是否选中,改变列表项的状态;抬起时,恢复标识位,右键抬起的话,

还要显示菜单。

主要代码片段:

void CCustomListUI::DoEvent(TEventUI& event){
BOOL bShift = (GetKeyState(VK_SHIFT) & 0x8000);
BOOL bCtrl = (GetKeyState(VK_CONTROL) & 0x8000);
if(bShift || bCtrl){
CListUI::DoEvent(event);
return;
}


switch( event.Type ) {
case UIEVENT_BUTTONDOWN://左键
case UIEVENT_RBUTTONDOWN://右键
{
m_bStartRect = true;
m_startPoint = event.ptMouse; //记录开始点
SetCapture(m_PM.GetPaintWindow());
}
break;
case UIEVENT_MOUSEMOVE:
//if(GetCapture() == m_PM.GetPaintWindow()){
if(m_bStartRect){
HWND hwnd = m_PM.GetPaintWindow();
RECT rcClient;
POINT point = event.ptMouse;
RECT rect = {0};
if(m_startPoint.x == point.x && m_startPoint.y == point.y) break;
::GetClientRect(hwnd, &rcClient);
::InvalidateRect(hwnd, &rcClient, FALSE);


if(point.x RECT rectTemp = {point.x,point.y,m_startPoint.x,m_startPoint.y};
rect = rectTemp;
}else if(point.x>m_startPoint.x && point.y < m_startPoint.y){
RECT rectTemp = {m_startPoint.x,point.y,point.x,m_startPoint.y};
rect = rectTemp;
}else if(point.x m_startPoint.y){
RECT rectTemp = {point.x,m_startPoint.y,m_startPoint.x,point.y};
rect = rectTemp;
}else {
RECT rectTemp = {m_startPoint.x,m_startPoint.y,point.x,point.y};
rect = rectTemp;
}


DWORD bkColor2 = this->GetItemBkColor();
UpdateSelectionForRect(rect);
CRenderEngine::DrawRect(m_PM.GetPaintDC(),rect,1,bkColor2);//draw
}
break;
case UIEVENT_BUTTONUP:
{
m_bStartRect = false;


if(GetCapture