使用DuiLib开发Windows界面实在是太简单了,对于MFC程序员真的是脱离苦海,控件自绘什么的GDI\GDI+真要把人搞死。DuiLib是国内一个非常有名的开源界面库,目前很多软件都是用了它(百度卫士、杀毒、PPS……),感谢开源的前辈们。
扩展列表控件的滚动消息,加上一个定时器,让他可以自动滚动一段再停下来。
void CDownloadListUI::DoEvent( TEventUI& event ) { if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) { if( m_pParent != NULL ) m_pParent->DoEvent(event); else CTileLayoutUI::DoEvent(event); return; } if( event.Type == UIEVENT_TIMER && event.wParam == SCROLL_TIMERID ) { if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) { POINT pt = m_pManager->GetMousePos(); LONG cy = (pt.y - m_ptLastMouse.y); m_ptLastMouse = pt; SIZE sz = GetScrollPos(); sz.cy -= cy; SetScrollPos(sz); return; } else if( m_dwDelayLeft > 0 ) { --m_dwDelayLeft; SIZE sz = GetScrollPos(); LONG lDeltaY = (LONG)(CalculateDelay((double)m_dwDelayLeft / m_dwDelayNum) * m_dwDelayDeltaY); if( (lDeltaY > 0 && sz.cy != 0) || (lDeltaY < 0 && sz.cy != GetScrollRange().cy ) ) { sz.cy -= lDeltaY; SetScrollPos(sz); return; } } m_dwDelayDeltaY = 0; m_dwDelayNum = 0; m_dwDelayLeft = 0; m_pManager->KillTimer(this, SCROLL_TIMERID); return; } if( event.Type == UIEVENT_SCROLLWHEEL ) { LONG lDeltaY = 0; if( m_dwDelayNum > 0 ) lDeltaY = (LONG)(CalculateDelay((double)m_dwDelayLeft / m_dwDelayNum) * m_dwDelayDeltaY); switch( LOWORD(event.wParam) ) { case SB_LINEUP: if( m_dwDelayDeltaY >= 0 ) m_dwDelayDeltaY = lDeltaY + 8; else m_dwDelayDeltaY = lDeltaY + 12; break; case SB_LINEDOWN: if( m_dwDelayDeltaY <= 0 ) m_dwDelayDeltaY = lDeltaY - 8; else m_dwDelayDeltaY = lDeltaY - 12; break; } if( m_dwDelayDeltaY > 100 ) m_dwDelayDeltaY = 100; else if( m_dwDelayDeltaY < -100 ) m_dwDelayDeltaY = -100; m_dwDelayNum = (DWORD)sqrt((double)abs(m_dwDelayDeltaY)) * 5; m_dwDelayLeft = m_dwDelayNum; m_pManager->SetTimer(this, SCROLL_TIMERID, 50U); return; } CTileLayoutUI::DoEvent(event); }
首先是添加节点到列表控件中,为了在后面对每个节点的点击事件进行区分,我们需要唯一标识每个节点里的控件,这里我是用控件名称来标识的。
void CDownloadListUI::AddItem() { CDialogBuilder builder; CContainerUI* pItem=static_cast<CContainerUI*>(builder.Create(L"Item_load.xml", 0)); if ( pItem ) { int i=GetCount(); CDuiString strText; strText.Format(L"%02d", i+1); CControlUI* pControl=pItem->GetItemAt(0); if ( pControl ) pControl->SetText(strText); pControl=pItem->GetItemAt(2); CProgressUI* pProgress=(CProgressUI*)pControl->GetInterface(L"Progress"); if ( pProgress ) pProgress->SetValue(i+1); pControl=pItem->GetItemAt(3); if ( pControl ) { strText.Format(L"%d%%", i+1); pControl->SetText(strText); } pControl=pItem->GetItemAt(4); if ( pControl ) pControl->SetText(L"正在下载"); pControl=pItem->GetItemAt(5); if ( pControl ) { strText.Format(L"BtnLoad1%d", i); pControl->SetName(strText); pControl->SetTag(i); } pControl=pItem->GetItemAt(6); if ( pControl ) { strText.Format(L"BtnLoad2%d", i); pControl->SetName(strText); pControl->SetTag(i); } pControl=pItem->GetItemAt(7); if ( pControl ) { strText.Format(L"BtnLoad3%d", i); pControl->SetName(strText); pControl->SetTag(i); } Add(pItem); } }
因此在点击事件的判断里,我只需要对比前面几个字符就可以对消息进行分发了:
void CMainWnd::OnClick( TNotifyUI& msg ) { if ( wcsncmp(msg.pSender->GetName(), L"BtnLoad1", 8)==0 ) OnBtnCancel(msg); else if ( wcsncmp(msg.pSender->GetName(), L"BtnLoad2", 8)==0 ) OnBtnPause(msg); else if ( wcsncmp(msg.pSender->GetName(), L"BtnLoad3", 8)==0 ) OnBtnContinue(msg); else if ( wcsncmp(msg.pSender->GetName(), L"BtnFinish", 9)==0 ) OnBtnDelete(msg); CWindowBase::OnClick(msg); }
分发消息处理函数里,我需要知道到底点击的是那个节点上的控件,这时候我们前面设置的Tag就有用了:
void CMainWnd::OnBtnCancel( TNotifyUI& msg ) { int nIndex=msg.pSender->GetTag(); int nCount=m_pDownloadList->GetCount(); if ( nIndex<0 || nIndex>=nCount ) return ; m_pDownloadList->RemoveAt(nIndex); for ( int i=0; i<nCount; ++i ) { CContainerUI* pLayout=static_cast<CContainerUI*>(m_pDownloadList->GetItemAt(i)); if ( pLayout==NULL ) continue; CControlUI* pBtn=pLayout->GetItemAt(5); if ( pBtn ) pBtn->SetTag(i); pBtn=pLayout->GetItemAt(6); if ( pBtn ) pBtn->SetTag(i); pBtn=pLayout->GetItemAt(7); if ( pBtn ) pBtn->SetTag(i); } }
这个小例只是做了界面的处理部分,没有什么实际的功能。你如果需要做下载管理,可以在里面扩展下载部分。
程序运行截图:
提供源码下载:
时间: 2024-10-10 06:27:05