Clistctrl实现了缩略图效果,为什么缩略图项目获得焦点之后缩略图消失了

xiaosong8584 2006-05-15 03:56:46
Clistctrl实现了缩略图效果,为什么
缩略图项目获得焦点之后缩略图消失了??

如题所问,

我已经实现了缩略图列出指定文件加的图片项目,
可是当我选取项目,及项目获得焦点之后,缩略图消失了,文字部分还在,
失去焦点后,又可以正常显示


请教各位高手,到底是什么原因??
...全文
733 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaosong8584 2006-05-29
  • 打赏
  • 举报
回复
揭帖,


请大家到
http://community.csdn.net/Expert/TopicView3.asp?id=4785704

继续接分
xiaosong8584 2006-05-22
  • 打赏
  • 举报
回复
ccaccbccc(好吃的雪糕)
真强,果然是这个问题

感谢大家的鼓励和支持,我会在再散100分给大家.

本贴留给大家继续发言

过两天总结并揭帖
ccaccbccc 2006-05-22
  • 打赏
  • 举报
回复
哈哈 我好像找到问题了 搂主代码中这一句
HIMAGELIST hImageList=ImageList_Create(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, ILC_COLOR32, 0,(int)m_FileNames.GetCount());
第三个参数改为ILC_COLOR24 就应该可以正常显示了。
会思考的草 2006-05-21
  • 打赏
  • 举报
回复
这个现象我们早就发现了。之前我参与的项目要做多国化,在繁体,简体,英语,俄语,韩语,西班牙语等十几个版本的windows上做过测试,有些语种的windows本身的图标之间的间隔就很大,不是程序的原因。我记得原因是这些国家的人种的瞳距不一样,所以图标的间隙要大一点。
ccaccbccc 2006-05-21
  • 打赏
  • 举报
回复
这个问题我也遇到了,至今还没有解决。原来的工程在vc6下好用,但在vs2005下 采用Unicode编码就不好用,更奇怪的是采用多字节编码就好用,快要郁闷死了。我采用的代码和你的差不多,是从codeproject上找到的。

现在初步认定 是 HIMAGELIST hImageList=ImageList_Create(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT
这个函数出了问题,但不知道如何解决。

ps:不指导楼主发现了没有,采用不同的字符集(unicode,多字节),绘制出来的图标位置是不一样的,具体原因不明。
onestation 2006-05-15
  • 打赏
  • 举报
回复
我以前遇到过这个问题,记不清了,好像是CImageList的参数设置问题,很容易就搞定了。
不过你的实现代码也太麻烦了点。
会思考的草 2006-05-15
  • 打赏
  • 举报
回复
这是我的缩略图列表类的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();
}
}
会思考的草 2006-05-15
  • 打赏
  • 举报
回复
对于获得焦点后的OnPaint,你参考一下ACDSee吧,它是在缩略图外面画了一个粗的框。具体什么效果你可以自定义。
会思考的草 2006-05-15
  • 打赏
  • 举报
回复
第一,从CListCtrl派生出一个类,把DrawThumbnail所做的动作移植到你的派生类的OnPaint中。
然后,在CImageTabDlg中创建一个你这个派生类的对象(别创建成CListCtrl了!)。个么就ok了。

进一步改进:
显示大量图片的时候UI会卡住,建议你用一个单独的线程进行DrawThumbnails的动作,并使用虚列表。
xiaosong8584 2006-05-15
  • 打赏
  • 举报
回复
to codewarrior(会思考的草)

另外,能否提供点参考资料,

我市菜鸟
xiaosong8584 2006-05-15
  • 打赏
  • 举报
回复
我在其他的方法里面调用 DrawThumbnails 来绘制,

只是执行的速度慢一些,可是没有什么问题呀,

,我只是不明白,为什么缩略图会消失,

获得焦点之后默认应该是灰色亚?
会思考的草 2006-05-15
  • 打赏
  • 举报
回复
WM_PAINT必须要自己写!可以另开一个线程来画,在OnPaint里通知这个线程重绘。
会思考的草 2006-05-15
  • 打赏
  • 举报
回复
OnPaint中没有代码?我!@#$%^&*(),无语了……
没有代码你画什么?OnInitDialog只执行一次,以后重绘的时候还是调用MFC提供的OnPaint,谁来替你画缩略图?
xiaosong8584 2006-05-15
  • 打赏
  • 举报
回复
不是,好郁闷,我在新的工程中运行时没有问题,
移植到一个更大的工程中就出现了这个问题,
我快抓狂了
AmyLin_2001 2006-05-15
  • 打赏
  • 举报
回复
收藏...
onpaint中没有代码?
会不会是onpaint没有执行相关操作啊?
xiaosong8584 2006-05-15
  • 打赏
  • 举报
回复
onpaint中没有代码
xiaosong8584 2006-05-15
  • 打赏
  • 举报
回复
//这个函数绘制缩略图

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();
}

xiaosong8584 2006-05-15
  • 打赏
  • 举报
回复
//初始化对话框

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
}
lixiaosan 2006-05-15
  • 打赏
  • 举报
回复
http://www.codeguru.com/Cpp/controls/listview/

Using images
会思考的草 2006-05-15
  • 打赏
  • 举报
回复
OnPaint的那部分代码贴出来看看。

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧