Clistctrl实现了缩略图效果,为什么
缩略图项目获得焦点之后缩略图消失了?? 如题所问,
我已经实现了缩略图列出指定文件加的图片 项目, 可是当我选取项目,及项目获得焦点之后,缩略图消失了,文字部分还在,
失去焦点后,又可以正常显示
请教各位高手,到底是什么原因??
问题 点数:50、回复次数:20Top
1 楼 codewarrior(会思考的草)回复于 2006-05-15 16:44:43 得分 13
OnPaint的那部分代码贴出来看看。Top
2 楼 lixiaosan(小三)回复于 2006-05-15 16:56:25 得分 5
http://www.codeguru.com /Cpp/controls/listview/ Using imagesTop
3 楼 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<IMAGEPAGES;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 } Top
4 楼 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.GetImageCount(); 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<m_FileNames.GetCount();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(); } Top
5 楼 dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-15 17:04:09 得分 0
onpaint中没有代码 Top
6 楼 lzfly(梦想成真)回复于 2006-05-15 17:13:26 得分 1
收藏... onpaint中没有代码? 会不会是onpaint没有执行相关操作啊?Top
7 楼 dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-15 17:20:49 得分 0
不是,好郁闷,我在新的工程 中运行时没有问题, 移植到一个更大的工程中就出现了这个问题, 我快抓狂了Top
8 楼 codewarrior(会思考的草)回复于 2006-05-15 17:23:49 得分 0
OnPaint中没有代码?我!@#$%^&*(),无语了…… 没有代码你画什么?OnInitDialog只执行一次,以后重绘的时候还是调用MFC提供的OnPaint,谁来替你画缩略图?Top
9 楼 codewarrior(会思考的草)回复于 2006-05-15 17:24:45 得分 0
WM_PAINT必须要自己写!可以另开一个线程来画,在OnPaint里通知这个线程重绘。Top
10 楼 dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-15 17:30:52 得分 0
我在其他的方法 里面调用 DrawThumbnails 来绘制, 只是执行的速度慢一些,可是没有什么问题呀, ,我只是不明白,为什么缩略图会消失, 获得焦点之后默认应该是灰色亚?Top
11 楼 dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-15 17:32:07 得分 0
to codewarrior(会思考的草) 另外,能否提供点参考资料 , 我市菜鸟 Top
12 楼 codewarrior(会思考的草)回复于 2006-05-15 17:39:30 得分 0
第一,从CListCtrl派生出一个类,把DrawThumbnail所做的动作移植到你的派生类的OnPaint中。 然后,在CImageTabDlg中创建一个你这个派生类的对象(别创建成CListCtrl了!)。个么就ok了。 进一步改进: 显示大量图片的时候UI会卡住,建议 你用一个单独的线程进行DrawThumbnails的动作,并使用虚列表。 Top
13 楼 codewarrior(会思考的草)回复于 2006-05-15 17:40:55 得分 0
对于获得焦点后的OnPaint,你参考一下ACDSee吧,它是在缩略图外面画了一个粗的框。具体什么效果你可以自定义。Top
14 楼 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<GetItemCount(); ++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(); } }Top
15 楼 onestation(新手)回复于 2006-05-15 17:51:56 得分 1
我以前遇到过这个问题,记不清了,好像是CImageList的参数设置问题,很容易就搞定了。 不过你的实现代码也太麻烦了点。Top
16 楼 ccaccbccc(好吃的雪糕)回复于 2006-05-21 14:43:18 得分 30
这个问题我也遇到了,至今还没有解决。原来的工程在vc6下好用,但在vs2005下 采用Unicode编码就不好用,更奇怪的是采用多字节编码就好用,快要郁闷死了。我采用的代码和你的差不多,是从codeproject上找到的。 现在初步认定 是 HIMAGELIST hImageList=ImageList_Create(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT 这个函数出了问题,但不知道如何解决。 ps:不指导楼主发现了没有,采用不同的字符集(unicode,多字节),绘制出来的图标位置是不一样的,具体原因不明。 Top
17 楼 codewarrior(会思考的草)回复于 2006-05-21 18:24:21 得分 0
这个现象我们早就发现了。之前我参与的项目要做多国化,在繁体,简体,英语,俄语,韩语,西班牙语等十几个版本的windows上做过测试,有些语种的windows本身的图标之间的间隔就很大,不是程序的原因。我记得原因是这些国家的人种的瞳距不一样,所以图标的间隙要大一点。Top
18 楼 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 就应该可以正常显示了。 Top
19 楼 dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-22 12:50:53 得分 0
ccaccbccc(好吃的雪糕) 真强,果然是这个问题 感谢大家的鼓励和支持,我会在再散100分给大家. 本贴留给大家继续发言 过两天总结并揭帖Top
20 楼 dream2013(每个人都有魔鬼的一面( http://blog.sina.com.cn/u/1422260677 ))回复于 2006-05-29 12:21:33 得分 0
揭帖, 请大家到 http://community.csdn.net/Expert/TopicView3.asp?id=4785704 继续接分