打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
在CListCtrl中多项拖动时显示图标
2011年08月13日 星期六 10:49 A.M.
转载自 alexpdl
最终编辑 qhh_2008

   在vc++中,对CListCtrl类有一个很常见的操作,即选中list中的若干项,然后单击左键进行拖拉,比较常见的是拖拉到CTreeCtrl的某 个节点里,见资源管理器。在拖拉的操作过程中,鼠标处会画出选中项的图标,用于模拟显示,类似下图。

 

如果用户选中了多个项目,可以采用以下的算法来画图标: 

const CImageList* CDragDrogDialog::CreateDragImageEx(CListCtrl *pList, LPPOINT lpPoint)  
 
//如果没有选择任何行 
if   (pList->GetSelectedCount() <= 0)  
{
     return NULL;
}

 CRect   rectSingle;  
CRect   rectComplete(0,0,0,0);  
  
//计算客户区图像的宽度 
pList->GetClientRect(rectSingle);  
int nWidth = rectSingle.Width();  
  
//可视区的开始和结束行
int nTopIndex = pList->GetTopIndex() - 1;  
int nBottomIndex = pList->GetTopIndex() + pList->GetCountPerPage() - 1;  
//如果pList没有占满
if (nBottomIndex > (pList->GetItemCount() - 1))  
{
    nBottomIndex = pList->GetItemCount() - 1;  
}
  
//计算拖拉的图标尺寸,此时nTopIndex已经变为选择区的第一行
while (-1 != (nTopIndex = pList->GetNextItem(nTopIndex, LVNI_SELECTED)))  
 
     if (nTopIndex > nBottomIndex)
     {
         break;    
     }
 
     pList->GetItemRect(nTopIndex, rectSingle, LVIR_BOUNDS);  
 
     if (rectSingle.left < 0)    
     {
         rectSingle.left = 0;  
     }
 
     if (rectSingle.right > nWidth)  
     {
         rectSingle.right = nWidth;  
     }
 
     rectComplete.UnionRect(rectComplete,   rectSingle);  
 
  
CClientDC dcClient(this);  
CDC    dcMem;  
CBitmap   Bitmap;  
  
if (!dcMem.CreateCompatibleDC(&dcClient))  
{
     return NULL;  
}
  
if (!Bitmap.CreateCompatibleBitmap(&dcClient, rectComplete.Width(), rectComplete.Height)))  
{
     return NULL;  
}

 

//填充拖拉的背景,一般选用绿色
CBitmap *pOldMemDCBitmap = dcMem.SelectObject(&Bitmap);   
dcMem.FillSolidRect(0, 0, rectComplete.Width(), rectComplete.Height(), RGB(0, 255, 0));  
  
//开始画图标
nTopIndex = pList->GetTopIndex() - 1;  
while (-1 != (nTopIndex = pList->GetNextItem(nTopIndex, LVNI_SELECTED)))  
 
    if (nTopIndex > nBottomIndex)  
    {
        break;  
    }
 
   CPoint pt;
   CImageList* pSingleImageList = pList->CreateDragImage(nIndex, &pt);  
 
    if (pSingleImageList)  
     
        pList->GetItemRect(nTopIndex, rectSingle, LVIR_BOUNDS);  
        pSingleImageList->Draw(&dcMem, 0, CPoint(rectSingle.left - rectComplete.left,     rectSingle.top - rectComplete.top),ILD_MASK);  
        pSingleImageList->DeleteImageList();  
      //一定要记得delete,否则溢出,见MSN
        delete pSingleImageList;  
      
  
   
dcMem.SelectObject(pOldMemDCBitmap);  
CImageList* pCompleteImageList = new CImageList;  
ASSERT(pCompleteImageList);
pCompleteImageList->Create(rectComplete.Width(), rectComplete.Height(), ILC_COLOR | ILC_MASK, 0, 1);  
pCompleteImageList->Add(&Bitmap, RGB(0, 255, 0));
Bitmap.DeleteObject();  
  
if (lpPoint)
 
    lpPoint->x = rectComplete.left;  
    lpPoint->y = rectComplete.top;  
 
  
return pCompleteImageList;   

 }

===========================================

http://group.gimoo.net/review/88101

【话题】CListCtrl如何实现拖动多个Items

2009-06-24 22:05:38 来自:superworld 浏览数:17
我选中多项, 进行拖动的时候. 只有鼠标拖动的那一个item有 效果.

如何构造拖动多个item拖动时候的cimagelist 实现类似资源管理器中拖动多项的效果

hyfang6673回复于24日22点18分  在BEGINDRAG是创建一个 CImageList,然后调用哪个BeginDrag就可以了,然后在拖动完毕是自己处理一下就可以了
CImageList* CAptFileZillaDlg::CreateDragImageEx(CListCtrl *pList, LPPOINT lpPoint)
{
if (pList->GetSelectedCount() <= 0)
return NULL; // no row selected


DWORD dwStyle = GetWindowLong(pList->m_hWnd, GWL_STYLE) & LVS_TYPEMASK;

CRect rectComplete(0, 0, 0, 0);

// Determine List Control Client width size
CRect rectClient;
pList->GetClientRect(rectClient);
int nWidth = rectClient.Width() + 50;

// Start and Stop index in view area
int nIndex = pList->GetTopIndex() - 1;
int nBottomIndex = pList->GetTopIndex() + pList->GetCountPerPage();
if (nBottomIndex > (pList->GetItemCount() - 1))
nBottomIndex = pList->GetItemCount() - 1;

// Determine the size of the drag image (limited for rows visibled and client width)
while ((nIndex = pList->GetNextItem(nIndex, LVNI_SELECTED)) != -1)
{
if (nIndex > nBottomIndex)
break;

CRect rectItem;
pList->GetItemRect(nIndex, rectItem, LVIR_BOUNDS);

if (rectItem.left < 0)
rectItem.left = 0;

if (rectItem.right > nWidth)
rectItem.right = nWidth;

rectComplete.UnionRect(rectComplete, rectItem);
}

// Create memory device context
CClientDC dcClient(this);
CDC dcMem;
CBitmap Bitmap;

if (!dcMem.CreateCompatibleDC(&dcClient))
return NULL;

if (!Bitmap.CreateCompatibleBitmap(&dcClient, rectComplete.Width(), rectComplete.Height()))
return NULL;

CBitmap *pOldMemDCBitmap = dcMem.SelectObject(&Bitmap);
// Use green as mask color
dcMem.FillSolidRect(0, 0, rectComplete.Width(), rectComplete.Height(), RGB(0,255,0));

// Don't use antialiased font for the dragimages
CFont *pFont = pList->GetFont();
LOGFONT lf;
pFont->GetLogFont(&lf);
lf.lfQuality = NONANTIALIASED_QUALITY;
CFont newFont;
newFont.CreateFontIndirect(&lf);

CFont *oldFont = dcMem.SelectObject(&newFont);

// Paint each DragImage in the DC
nIndex = pList->GetTopIndex() - 1;
while ((nIndex = pList->GetNextItem(nIndex, LVNI_SELECTED)) != -1)
{
if (nIndex > nBottomIndex)
break;

TCHAR buffer[1000];
LVITEM item = {0};
item.mask = LVIF_TEXT | LVIF_IMAGE;
item.iItem = nIndex;
item.pszText = buffer;
item.cchTextMax = 999;

pList->GetItem(&item);

// Draw the icon
CImageList* pSingleImageList = pList->GetImageList((dwStyle == LVS_ICON)?LVSIL_NORMAL:LVSIL_SMALL);
if (pSingleImageList)
{
CRect rectIcon;
pList->GetItemRect(nIndex, rectIcon, LVIR_ICON);

IMAGEINFO info;
pSingleImageList->GetImageInfo(item.iImage, &info);
CPoint p((rectIcon.left - rectComplete.left + rectIcon.right - rectComplete.left) / 2 - (info.rcImage.right - info.rcImage.left) / 2,
(rectIcon.top - rectComplete.top + rectIcon.bottom - rectComplete.top) / 2 - (info.rcImage.bottom - info.rcImage.top) / 2 + ((dwStyle == LVS_ICON)?2:0));

pSingleImageList->Draw( &dcMem, item.iImage,
p,
ILD_TRANSPARENT);
}

// Draw the text
CString text;
text = item.pszText;
CRect textRect;
pList->GetItemRect( nIndex, textRect, LVIR_LABEL );
textRect.top -= rectComplete.top - 2;
textRect.bottom -= rectComplete.top + 1;
textRect.left -= rectComplete.left - 2;
textRect.right -= rectComplete.left;

DWORD flags = DT_END_ELLIPSIS | DT_MODIFYSTRING;
if (dwStyle == LVS_ICON)
flags |= DT_CENTER | DT_WORDBREAK;
dcMem.DrawText(text, -1, textRect, flags);
}

dcMem.SelectObject(oldFont);

dcMem.SelectObject(pOldMemDCBitmap);

// Create drag image(list)
CImageList* pCompleteImageList = new CImageList;
pCompleteImageList->Create(rectComplete.Width(), rectComplete.Height(), ILC_COLOR32 | ILC_MASK, 0, 1);
pCompleteImageList->Add(&Bitmap, RGB(0, 255, 0)); // Green is used as mask color
Bitmap.DeleteObject();

if (lpPoint)
{
lpPoint->x = rectComplete.left;
lpPoint->y = rectComplete.top;
}

return pCompleteImageList;
}
 
chenhua回复于24日22点30分 



就是这个效果 ,,,
 
南方-1996回复于24日22点44分 
IDropSource
IDropTarget

要继承这两个类来协助完成,详细的情况那么需要找相关的例子来完成。


(###)


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
卓为VC——界面/窗口——VC界面/窗口的一些小技巧
教你自己做xp精美登录界面
MFC背景图像加载
android imageView释放内存
背景设置
对话框加载背景
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服