Chinaunix首页 | 论坛 | 博客
  • 博客访问: 120537
  • 博文数量: 95
  • 博客积分: 316
  • 博客等级: 二等列兵
  • 技术积分: 635
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-23 17:41
文章分类

全部博文(95)

文章存档

2014年(1)

2013年(1)

2012年(93)

我的朋友

分类:

2012-08-17 09:47:16

Clistctrl实现了缩略图效果,为什么  
  缩略图项目获得焦点之后缩略图消失了??  如题所问,  
   
  我已经实现了缩略图列出指定文件加的图片项目,  
  可是当我选取项目,及项目获得焦点之后,缩略图消失了,文字部分还在,  
  失去焦点后,又可以正常显示  
   
   
  请教各位高手,到底是什么原因?? 问题点数:50、回复次数:20

codewarrior(会思考的草)回复于 2006-05-15 16:44:43 得分 13

OnPaint的那部分代码贴出来看看。

lixiaosan(小三)回复于 2006-05-15 16:56:25 得分 5

com/Cpp/controls/listview/  
   
  Using   images

dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-15 17:00:24 得分 0

//初始化对话框  
   
  BOOL   CImageTabDlg::OnInitDialog()  
  {  
          CDialog::OnInitDialog();  
   
  //指定listctrl样式  
  //m_ListCtrlView.ModifyStyle(LVS_REPORT|LVS_SMALLICON|LVS_LIST|LVS_ICON,WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_SINGLESEL|LVS_EDITlabel1S   ,SWP_NOSIZE);  
  //m_ListCtrlView.ModifyStyle(WS_HSCROLL|LVS_EDITlabel1S,WS_VSCROLL);  
  UINT   style=::GetWindowLong(m_ListCtrlView.m_hWnd,GWL_STYLE);  
          style=style|WS_VSCROLL|LVS_ICON|LVS_SINGLESEL;  
  style=style&~WS_HSCROLL;  
  ::SetWindowLong(m_ListCtrlView.m_hWnd,GWL_STYLE,style);  
   
  //CRect   rect;  
  //m_ListCtrlView.GetWindowRect(&rect);  
  //m_ListCtrlView.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_SINGLESEL|WS_VSCROLL,rect,this,IDC_LISTVIEW);  
   
   
  //初始化标签页  
  for(int   i=0;i  TC_ITEM   TabCtrlItem;  
  TabCtrlItem.mask   =   TCIF_TEXT;  
  TabCtrlItem.pszText   =label1[i].GetBuffer();  
  m_TabCtrlView.InsertItem(i,   &TabCtrlItem);  
   
          }  
   
          //隐藏增加删除按钮  
  ((CButton*)GetDlgItem(IDC_ADD))->ShowWindow(false);  
  ((CButton*)GetDlgItem(IDC_DEL))->ShowWindow(false);  
   
            ShowATab();  
            DrawThumbnails();  
   
   
  //   TODO:     Add   ext1ra   initialization   here  
   
  return   TRUE;     //   return   TRUE   unless   you   set   the   focus   to   a   control  
  //   EXCEPTION:   OCX   Property   Pages   should   return   FALSE  
  }  
 

dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-15 17:02:49 得分 0

//这个函数绘制缩略图  
   
  void   CImageTabDlg::DrawThumbnails(void)  
  {  
   
  //目前支持jpg,gif,ico,bmp  
  //==================================================  
   
    //定义缩略图的画布的大小  
    const   THUMBNAIL_WIDTH=100;                
    const   THUMBNAIL_HEIGHT=100;  
   
      //   Create   Brushes   for   Border   and   BackGround  
    HBRUSH   hBrushBorder=::CreateSolidBrush(RGB(0,   0,   0));          
    HBRUSH   hBrushBk=::CreateSolidBrush(RGB(255,   255,   255));          
   
   
   
    if(m_ImageList   &&   m_ImageList.GetImageCount()){  
            //   reset   our   image   list  
            for(int   i=0;   i            m_ImageList.Remove(i);    
    }    
    if(m_ListCtrlView){  
  m_ListCtrlView.DeleteAllItems();  
    }  
   
  //创建imagelist  
    HIMAGELIST   hImageList=ImageList_Create(THUMBNAIL_WIDTH,   THUMBNAIL_HEIGHT,   ILC_COLOR32,   0,(int)m_FileNames.GetCount());  
    m_ImageList.Attach(hImageList);  
   
  //   Use   the   image   list   in   the   list   view  
  m_ListCtrlView.SetImageList(&m_ImageList,   LVSIL_NORMAL);  
  m_ListCtrlView.SetImageList(&m_ImageList,   LVSIL_SMALL);  
   
   
   
    //   Border   Size  
    RECT   rcBorder;  
    rcBorder.left=rcBorder.top=0;  
    rcBorder.right=THUMBNAIL_WIDTH;  
    rcBorder.bottom=THUMBNAIL_HEIGHT;  
   
    const   float   fRatio=(float)THUMBNAIL_HEIGHT/THUMBNAIL_WIDTH;  
    int   XDest,   YDest,   nDestWidth,   nDestHeight;  
   
   
      //m_ListCtrlView.SetRedraw(FALSE);  
      for(int   i=0;i   
  CBitmap   dummy;  
  dummy.LoadBitmap(IDB_BITMAPDEFAULT);  
  m_ImageList.Add(&dummy,   RGB(0,   0,   0));  
  m_ListCtrlView.InsertItem(i,m_FileNames[i],i);      
                           
  CString   imagePath(m_strCurrentPath+m_FileNames[i]);  
   
  CxImage   image(imagePath.GetBuffer(),   getImageTypeFromName(m_FileNames[i]));             //CxImage   image(path,   nimagetype1);  
   
  //   Calculate   Rect   to   fit   to   canvas  
  const   float   fImgRatio=(float)image.GetHeight()/image.GetWidth();  
  if(image.GetWidth()>THUMBNAIL_WIDTH   ||   image.GetHeight()>THUMBNAIL_HEIGHT){        
  if(fImgRatio   >   fRatio)  
  {  
  nDestWidth=(int)(THUMBNAIL_HEIGHT/fImgRatio);  
  XDest=(THUMBNAIL_WIDTH-nDestWidth)/2;  
  YDest=0;  
  nDestHeight=THUMBNAIL_HEIGHT;  
  }  
  else  
  {  
  XDest=0;  
  nDestWidth=THUMBNAIL_WIDTH;  
  nDestHeight=(int)(THUMBNAIL_WIDTH*fImgRatio);  
  YDest=(THUMBNAIL_HEIGHT-nDestHeight)/2;  
  }  
  }else{  
  XDest=(THUMBNAIL_WIDTH-image.GetWidth())/2;  
  nDestWidth=image.GetWidth();  
  nDestHeight=image.GetHeight();  
  YDest=(THUMBNAIL_HEIGHT-image.GetHeight())/2;  
   
  }  
   
  CClientDC   cdc(this);  
  HDC   hDC=::CreateCompatibleDC(cdc.m_hDC);  
  HBITMAP   bm   =   CreateCompatibleBitmap(cdc.m_hDC,   THUMBNAIL_WIDTH,    
  THUMBNAIL_HEIGHT);  
  HBITMAP   pOldBitmapImage   =   (HBITMAP)SelectObject(hDC,bm);  
  //   Draw   Background  
  ::FillRect(hDC,   &rcBorder,   hBrushBk);  
   
  //   Draw   Image  
  image.Stretch(hDC,   XDest,   YDest,   nDestWidth,   nDestHeight);  
   
  //   Draw   Border  
  ::FrameRect(hDC,   &rcBorder,   hBrushBorder);  
   
  SelectObject(hDC,   pOldBitmapImage);  
   
  //   Attach   to   Bitmap   and   Replace   image   in   CImageList  
  CBitmap   bitmap;  
  bitmap.Attach(bm);  
  m_ImageList.Replace(i,   &bitmap,   NULL);  
   
  //   Redraw   only   a   current   item   for   removing   flickering   and   fast   speed.  
  m_ListCtrlView.RedrawItems(i,   i);    
   
  //   Release   used   DC   and   Object  
  DeleteDC(hDC);  
  DeleteObject(bm);  
  DeleteObject(dummy);  
    }  
      //m_ListCtrlView.SetRedraw(TRUE);  
   
    DeleteObject(hBrushBorder);  
    DeleteObject(hBrushBk);  
    m_ImageList.Detach();          
   
    m_ListCtrlView.Invalidate();  
  }  
   
 

dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-15 17:04:09 得分 0

onpaint中没有代码  
 

lzfly(梦想成真)回复于 2006-05-15 17:13:26 得分 1

收藏...  
  onpaint中没有代码?  
  会不会是onpaint没有执行相关操作啊?

dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-15 17:20:49 得分 0

不是,好郁闷,我在新的工程中运行时没有问题,  
  移植到一个更大的工程中就出现了这个问题,  
  我快抓狂了

codewarrior(会思考的草)回复于 2006-05-15 17:23:49 得分 0

OnPaint中没有代码?我!@#$%^&*(),无语了……  
  没有代码你画什么?OnInitDialog只执行一次,以后重绘的时候还是调用MFC提供的OnPaint,谁来替你画缩略图?

codewarrior(会思考的草)回复于 2006-05-15 17:24:45 得分 0

WM_PAINT必须要自己写!可以另开一个线程来画,在OnPaint里通知这个线程重绘。

dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-15 17:30:52 得分 0

我在其他的方法里面调用     DrawThumbnails   来绘制,  
   
  只是执行的速度慢一些,可是没有什么问题呀,  
   
  ,我只是不明白,为什么缩略图会消失,  
   
  获得焦点之后默认应该是灰色亚?

dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-15 17:32:07 得分 0

to   codewarrior(会思考的草)  
   
          另外,能否提供点参考资料,  
   
          我市菜鸟  
 

codewarrior(会思考的草)回复于 2006-05-15 17:39:30 得分 0

第一,从CListCtrl派生出一个类,把DrawThumbnail所做的动作移植到你的派生类的OnPaint中。  
  然后,在CImageTabDlg中创建一个你这个派生类的对象(别创建成CListCtrl了!)。个么就ok了。  
   
  进一步改进:  
  显示大量图片的时候UI会卡住,建议你用一个单独的线程进行DrawThumbnails的动作,并使用虚列表。

codewarrior(会思考的草)回复于 2006-05-15 17:40:55 得分 0

对于获得焦点后的OnPaint,你参考一下ACDSee吧,它是在缩略图外面画了一个粗的框。具体什么效果你可以自定义。

codewarrior(会思考的草)回复于 2006-05-15 17:42:43 得分 0

这是我的缩略图列表类的OnPaint函数,完全模仿ACDSee   6.0,你姑且作个参考吧:  
  void   CThumbnailListCtrl::OnPaint()  
  {  
  Dump();  
  if(IsThumbnailView())  
  {  
  BOOL   bFocused   =   (GetFocus()==this);  
  CFont   fontLabel;  
  CRect   rectIcon(0,0,0,0);  
  CRect   rectLabel(0,0,0,0);  
  CPaintDC   dc(this);   //   device   context   for   painting  
   
  //创建标签字体  
  // fontLabel.CreateFont(13,0,0,0,9,   FALSE,   FALSE,   0,   GB2312_CHARSET,   OUT_DEFAULT_PRECIS,  
  // CLIP_DEFAULT_PRECIS,   DEFAULT_QUALITY,   DEFAULT_PITCH|FF_SWISS,   "Tahoma");  
  LOGFONT   LogFont   =   {0};  
  ::SystemParametersInfo(SPI_GETICONTITLELOGFONT,   sizeof(LOGFONT),   &LogFont,   0);  
  fontLabel.CreateFontIndirect(&LogFont);  
   
  for(int   i=0;   i  {  
  GetItemRect(i,   &rectIcon,   LVIR_ICON);  
  rectIcon.DeflateRect(WIDTH_STEP,WIDTH_STEP,HEIGHT_STEP,HEIGHT_STEP);   //向内缩  
   
  //涂底色  
  dc.FillSolidRect(rectIcon,   COLOR_THUMBNAIL_BACKGROUND);  
   
  //画焦点  
  if(GetItemState(i,   LVIS_SELECTED)==   LVIS_SELECTED)  
  {  
  if(bFocused)  
  {  
  rectIcon.InflateRect(3,3,3,3);  
  dc.Draw3dRect(&rectIcon,   COLOR_THUMBNAIL_DBLUEFRAME,   COLOR_THUMBNAIL_DBLUEFRAME);  
  rectIcon.InflateRect(1,1,1,1);  
  dc.Draw3dRect(&rectIcon,   COLOR_THUMBNAIL_DBLUEFRAME,   COLOR_THUMBNAIL_DBLUEFRAME);  
  rectIcon.InflateRect(1,1,1,1);  
  dc.Draw3dRect(&rectIcon,   COLOR_THUMBNAIL_DBLUEFRAME,   COLOR_THUMBNAIL_DBLUEFRAME);  
  rectIcon.DeflateRect(5,5,5,5);  
   
  dc.Draw3dRect(rectIcon,   COLOR_THUMBNAIL_FRAME,   COLOR_THUMBNAIL_FRAME);  
  }  
  else  
  {  
  dc.Draw3dRect(&rectIcon,   COLOR_THUMBNAIL_CBLUEFRAME,   COLOR_THUMBNAIL_CBLUEFRAME);  
  rectIcon.InflateRect(1,1,1,1);  
  dc.Draw3dRect(&rectIcon,   COLOR_THUMBNAIL_CBLUEFRAME,   COLOR_THUMBNAIL_CBLUEFRAME);  
  rectIcon.DeflateRect(2,2,2,2);  
  }  
  }  
   
  //画缩略图  
  LVITEM   lvItem   =   {0};  
  lvItem.iItem   =   i;  
  lvItem.mask   =   LVIF_IMAGE|LVIF_PARAM|LVIF_STATE;  
  GetItem(&lvItem);  
  PLVITEM_EXINFO   pItemInfo   =   (PLVITEM_EXINFO)lvItem.lParam;  
   
  CPoint   ptTopleft(0,0);  
  IMAGEINFO   ImgInfo   =   {0};  
  if(pItemInfo->hThumbnail   ==   NULL)//尚未读取缩略图,我们用大图标代替  
  {  
  m_imglstLargeIcon.GetImageInfo(lvItem.iImage,   &ImgInfo);  
   
  DWORD   dwWidth   =   ImgInfo.rcImage.right-ImgInfo.rcImage.left;  
  DWORD   dwHeight   =   ImgInfo.rcImage.bottom-ImgInfo.rcImage.top;  
  ptTopleft.x   =   rectIcon.left   +   ((rectIcon.Width()-dwWidth)/2);  
  ptTopleft.y   =   rectIcon.top   +   ((rectIcon.Height()-dwHeight)/2);  
   
  if(GetItemState(i,   LVIS_CUT)   ==   LVIS_CUT)  
  {  
  ImageList_DrawEx(  
  m_imglstLargeIcon.GetSafeHandle(),   lvItem.iImage,   dc.m_hDC,  
  ptTopleft.x,   ptTopleft.y,   dwWidth,   dwHeight,  
  COLOR_THUMBNAIL_BACKGROUND, //背景色  
  COLOR_THUMBNAIL_BACKGROUND, //前景色  
  ILD_BLEND //和前景色混合50%  
  );  
  }  
  else  
  {  
  m_imglstLargeIcon.Draw(&dc,   lvItem.iImage,   ptTopleft,   ILD_TRANSPARENT);  
  }  
  }  
  else  
  {  
  CRect   TmpRect(0,   0,   THUMBNAIL_WIDTH,   THUMBNAIL_HEIGHT);  
  TmpRect.DeflateRect(WIDTH_STEP,WIDTH_STEP,HEIGHT_STEP,HEIGHT_STEP);  
   
  ptTopleft.x   =   rectIcon.left   +   ((rectIcon.Width()-TmpRect.Width())/2);  
  ptTopleft.y   =   rectIcon.top   +   ((rectIcon.Height()-TmpRect.Height())/2);  
   
  HDC   hMemDC   =   CreateCompatibleDC(dc.m_hDC);  
  ::SelectObject(hMemDC,   pItemInfo->hThumbnail);  
  StretchBlt(dc.m_hDC,   ptTopleft.x,   ptTopleft.y,   TmpRect.Width(),   TmpRect.Height(),  
  hMemDC,   0,   0,   TmpRect.Width(),   TmpRect.Height(),   SRCCOPY);  
  ::DeleteDC(hMemDC);  
  }  
   
  //右上角画小图标  
  ZeroMemory(&ImgInfo,   sizeof(IMAGEINFO));  
  m_imglstSmallIcon.GetImageInfo(lvItem.iImage,   &ImgInfo);  
  ptTopleft.x   =   rectIcon.right   -   (ImgInfo.rcImage.right-ImgInfo.rcImage.left)   -   11;  
  ptTopleft.y   =   rectIcon.top   +   3;  
  m_imglstSmallIcon.Draw(&dc,   lvItem.iImage,   ptTopleft,   ILD_TRANSPARENT);  
   
  //画边框  
  dc.Draw3dRect(rectIcon,   COLOR_THUMBNAIL_FRAME,   COLOR_THUMBNAIL_FRAME);  
   
  GetItemRect(i,   &rectLabel,   LVIR_LABEL);  
  rectLabel.left   =   rectIcon.left;  
  rectLabel.right   =   rectIcon.right;  
  rectLabel   -=   CSize(0,   3);  
  CFont*   pOldFont   =   dc.SelectObject(&fontLabel);  
  UINT   nOldMode   =   dc.SetBkMode(TRANSPARENT);  
   
  dc.DrawText(GetItemText(i,0),   rectLabel,   DT_CENTER|DT_VCENTER|DT_WORDBREAK|DT_END_ELLIPSIS);  
  dc.SelectObject(pOldFont);  
  dc.SetBkMode(nOldMode);  
  }  
   
  fontLabel.DeleteObject();  
   
  if(m_bDragStart   &&   m_nLandPos!=-1)  
  {  
  CPen     RedPen(PS_SOLID,   1,   RGB(255,   0,   0));  
  CPen*   pOldPen   =   dc.SelectObject(&RedPen);  
  CRect   SpcRect(0,0,0,0);  
   
  //计算分割条所在的矩形  
  CalcInsMarkRect(m_nLandPos,   SpcRect);  
   
  CPoint   pt1(SpcRect.TopLeft());     //取左上角  
  CPoint   pt2(SpcRect.BottomRight());//取右下角  
   
  pt2.x   =   pt1.x   =   (pt1.x+pt2.x)/2;     //计算上边中点和下边中点  
  pt1.y   +=   3;  
  pt2.y   -=   5;  
   
  if(m_nLandPos   <   GetItemCount())   //靠右画  
  {  
  //中垂线  
  dc.MoveTo(pt1.x+2,   pt1.y);  
  dc.LineTo(pt2.x+2,   pt2.y);  
  dc.MoveTo(pt1.x+3,   pt1.y);  
  dc.LineTo(pt2.x+3,   pt2.y);  
   
  //上横边  
  dc.MoveTo(pt1.x,       pt1.y);  
  dc.LineTo(pt1.x+6,   pt1.y);  
  dc.MoveTo(pt1.x,       pt1.y+1);  
  dc.LineTo(pt1.x+6,   pt1.y+1);  
   
  //下横边  
  dc.MoveTo(pt2.x,       pt2.y);  
  dc.LineTo(pt2.x+6,   pt2.y);  
  dc.MoveTo(pt2.x,       pt2.y-1);  
  dc.LineTo(pt2.x+6,   pt2.y-1);  
  }  
  else   //靠左画  
  {  
  //中垂线  
  dc.MoveTo(pt1.x-1,   pt1.y);  
  dc.LineTo(pt2.x-1,   pt2.y);  
  dc.MoveTo(pt1.x-2,   pt1.y);  
  dc.LineTo(pt2.x-2,   pt2.y);  
   
  //上横边  
  dc.MoveTo(pt1.x-4,   pt1.y);  
  dc.LineTo(pt1.x+2,   pt1.y);  
  dc.MoveTo(pt1.x-4,   pt1.y+1);  
  dc.LineTo(pt1.x+2,   pt1.y+1);  
   
  //下横边  
  dc.MoveTo(pt2.x-4,   pt2.y);  
  dc.LineTo(pt2.x+2,   pt2.y);  
  dc.MoveTo(pt2.x-4,   pt2.y-1);  
  dc.LineTo(pt2.x+2,   pt2.y-1);  
  }  
  dc.SelectObject(pOldPen);  
  }  
  }  
  else  
  {  
  SetIconSpacing(-1,   -1);  
  CListCtrl::OnPaint();  
  }  
  }

onestation(新手)回复于 2006-05-15 17:51:56 得分 1

我以前遇到过这个问题,记不清了,好像是CImageList的参数设置问题,很容易就搞定了。  
  不过你的实现代码也太麻烦了点。

ccaccbccc(好吃的雪糕)回复于 2006-05-21 14:43:18 得分 30

这个问题我也遇到了,至今还没有解决。原来的工程在vc6下好用,但在vs2005下   采用Unicode编码就不好用,更奇怪的是采用多字节编码就好用,快要郁闷死了。我采用的代码和你的差不多,是从codeproject上找到的。  
   
  现在初步认定   是   HIMAGELIST   hImageList=ImageList_Create(THUMBNAIL_WIDTH,   THUMBNAIL_HEIGHT    
  这个函数出了问题,但不知道如何解决。  
   
  ps:不指导楼主发现了没有,采用不同的字符集(unicode,多字节),绘制出来的图标位置是不一样的,具体原因不明。  
 

codewarrior(会思考的草)回复于 2006-05-21 18:24:21 得分 0

这个现象我们早就发现了。之前我参与的项目要做多国化,在繁体,简体,英语,俄语,韩语,西班牙语等十几个版本的windows上做过测试,有些语种的windows本身的图标之间的间隔就很大,不是程序的原因。我记得原因是这些国家的人种的瞳距不一样,所以图标的间隙要大一点。

ccaccbccc(好吃的雪糕)回复于 2006-05-22 09:29:40 得分 0

哈哈     我好像找到问题了     搂主代码中这一句  
  HIMAGELIST   hImageList=ImageList_Create(THUMBNAIL_WIDTH,   THUMBNAIL_HEIGHT,   ILC_COLOR32,   0,(int)m_FileNames.GetCount());  
  第三个参数改为ILC_COLOR24   就应该可以正常显示了。  
 

dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-22 12:50:53 得分 0

ccaccbccc(好吃的雪糕)    
  真强,果然是这个问题  
   
  感谢大家的鼓励和支持,我会在再散100分给大家.  
   
  本贴留给大家继续发言  
   
  过两天总结并揭帖

dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-29 12:21:33 得分 0

揭帖,  
   
   
  请大家到  
   
   
  继续接分

阅读(629) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~