我想在单文档里用ClistCtrl贴图,但CListCtrl::SetBkImage都需要路径才加载背景位图。
我想从资源里加载IDB_BITMAP,应该要重载ClistCtrl吧,但怎么弄啊???有实现的源代码和例子最好,有的直接发我邮箱吧[email protected]
谢谢啦,up有分
我想从资源里加载IDB_BITMAP,应该要重载ClistCtrl吧,但怎么弄啊???有实现的源代码和例子最好,有的直接发我邮箱吧[email protected]
谢谢啦,up有分
调试欢乐多
//#include "stdafx.h"
#include "practise.h"
#include "ListImage.h"
#define THUMWIDTH 75
#define THUMHEIGHT 55// ListImage dialogIMPLEMENT_DYNAMIC(ListImage, CDialog)ListImage::ListImage(CWnd* pParent /*=NULL*/)
: CDialog(ListImage::IDD, pParent)
{}ListImage::~ListImage()
{
}void ListImage::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, m_List);
DDX_Control(pDX, IDC_EDIT2, m_edit2);
}
BEGIN_MESSAGE_MAP(ListImage, CDialog)
ON_BN_CLICKED(IDC_BUTTON1, &ListImage::OnBnClickedButton1)
ON_BN_CLICKED(IDOK, &ListImage::OnBnClickedOk)
END_MESSAGE_MAP()
// ListImage message handlers
BOOL ListImage::OnInitDialog()
{
CDialog::OnInitDialog();// TODO: Add extra initialization herereturn TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void ListImage::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
//文件对话框 CString FilePath;
CFileDialog FileDialog(true, _T(""), _T(""), OFN_EXPLORER,
_T("所有文件(*.*)|*.*||"), this); //显示对话框
if(FileDialog.DoModal() == IDOK)
{
FilePath = FileDialog.GetPathName();
int g=FilePath.ReverseFind('\\');
FilePath=FilePath.Left(g+1);
m_edit2.SetWindowText(FilePath);}
else
{
return;
}
//清楚m_ImageList对象和m_List
if (m_ImageList!=NULL)
{
for(int kk=0;kk<m_ImageList.GetImageCount();kk++)
m_ImageList.Remove(kk);
m_List.DeleteAllItems();
}
else
{
m_ImageList.Create(THUMWIDTH,THUMHEIGHT, ILC_COLORDDB|ILC_MASK, 20, 1);
m_List.SetImageList(&m_ImageList, LVSIL_NORMAL);
m_List.SetImageList(&m_ImageList, LVSIL_SMALL);
}
m_List.SetRedraw(false);
CString strDir=FilePath+_T("*.*");
//strDir.Format("%s%s",FilePath,L"*.*");
//_T("D:\\happiness\\风景桌面\\*.*"); int i=0,cn=0,j=0;
SHFILEINFO finfo;
CString fileName;
CString filePath2;
HANDLE hFind;
WIN32_FIND_DATA fd ;
hFind=::FindFirstFile((LPCTSTR)strDir,&fd);
if(hFind==INVALID_HANDLE_VALUE)return;
do
{
if ( !wcscmp(fd.cFileName, _T(".")) || !wcscmp(fd.cFileName, _T("..")))continue;
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)continue;
fileName=fd.cFileName;
filePath2=FilePath+fileName;
i=fileName.Find(_T(".jpg"),0);
//加载jpg,jpeg,gif格式的图片
if (i==-1)
i=fileName.Find(_T(".jpeg"),0);
if (i==-1)
i=fileName.Find(_T(".JPG"),0);
if (i==-1)
i=fileName.Find(_T(".JPEG"),0);
if (i==-1)
i=fileName.Find(_T(".gif"),0);
if (i==-1)
i=fileName.Find(_T(".GIF"),0);
if (i==-1)
i=fileName.Find(_T(".BMP"),0);
if (i==-1)
i=fileName.Find(_T(".bmp"),0);
if (i!=-1)
{
//Creating thumbnail image for the file
HBITMAP bitm=LoadPicture(filePath2);
if (bitm!=NULL)
{ CBitmap* pImage = NULL;
pImage = new CBitmap();
pImage->Attach(bitm);
int imgP=m_ImageList.Add(pImage,RGB(0,0,0));
//Link to the added listview item
m_List.InsertItem(cn,fileName,imgP);
}
}
//加载icon图片
i=fileName.Find(_T(".ico"),0);
if (i==-1)
i=fileName.Find(_T(".ICO"),0);
if (i==-1)
i=fileName.Find(_T(".rc"),0);
if (i==-1)
i=fileName.Find(_T(".rc2"),0);
if (i!=-1)
{
::SHGetFileInfo(filePath2,0,&finfo,sizeof(SHFILEINFO),SHGFI_ICON);
m_ImageList.Add(finfo.hIcon);//加入图标
m_List.InsertItem(cn,fileName,cn);
}
cn++;
}while(::FindNextFile(hFind,&fd));
FindClose(hFind);
m_List.SetRedraw(true);
Invalidate();
UpdateWindow();
}
HBITMAP ListImage::LoadPicture(CString mFile)
{
CString pFSize;
WCHAR wpath[MAX_PATH];
// MultiByteToWideChar(CP_ACP, 0,lpszBuf, -1, wpath, MAX_PATH);
IPicture* pPic;
OleLoadPicturePath(T2OLE((LPTSTR)(LPCTSTR)mFile), NULL, NULL, NULL, IID_IPicture,(LPVOID*)&pPic);if (pPic==NULL) return NULL;
HBITMAP hPic = NULL;
pPic->get_Handle((UINT*)&hPic);long nWidth=THUMWIDTH;
long nHeight=THUMHEIGHT;long mWid,mHei;
pPic->get_Height(&mHei);
pPic->get_Width(&mWid);HBITMAP hPicRet = (HBITMAP)CopyImage(hPic, IMAGE_BITMAP, nWidth, nHeight , LR_COPYDELETEORG);// Create Brushes for Border and BackGround
HBRUSH hBrushBorder=::CreateSolidBrush(RGB(192, 192, 192));
HBRUSH hBrushBk=::CreateSolidBrush(RGB(255, 255, 255));// Border Size
RECT rcBorder;
rcBorder.left=rcBorder.top=0;
rcBorder.right=THUMWIDTH;
rcBorder.bottom=THUMHEIGHT;const float fRatio=(float)THUMHEIGHT/THUMWIDTH;int XDest, YDest, nDestWidth, nDestHeight;
// Calculate Rect to fit to canvas
const float fImgRatio=(float)mHei/mWid;
if(fImgRatio > fRatio)
{
nDestWidth=(THUMHEIGHT/fImgRatio);
XDest=(THUMWIDTH-nDestWidth)/2;
YDest=0;
nDestHeight=THUMHEIGHT;
}
else
{
XDest=0;
nDestWidth=THUMWIDTH;
nDestHeight=(THUMWIDTH*fImgRatio);
YDest=(THUMHEIGHT-nDestHeight)/2;
}CClientDC cdc(this);
HDC hDC=::CreateCompatibleDC(cdc.m_hDC);
HBITMAP bm = CreateCompatibleBitmap(cdc.m_hDC, THUMWIDTH, THUMHEIGHT);
HBITMAP pOldBitmapImage = (HBITMAP)SelectObject(hDC,bm);
// Draw Background
::FillRect(hDC, &rcBorder, hBrushBk);// Draw Border
::FrameRect(hDC, &rcBorder, hBrushBorder);HBITMAP hBmReturn= (HBITMAP)::SelectObject(hDC, pOldBitmapImage);CDC hdcSrc, hdcDst;hdcSrc.CreateCompatibleDC(NULL);
hdcDst.CreateCompatibleDC(NULL);// Load the bitmaps into memory DC
CBitmap* hbmSrcT = (CBitmap*) hdcSrc.SelectObject(hPicRet);
CBitmap* hbmDstT = (CBitmap*) hdcDst.SelectObject(hBmReturn);// This call sets up the mask bitmap.
hdcDst.BitBlt(XDest,YDest,nDestWidth, nDestHeight, &hdcSrc,0,0,SRCCOPY);
//hdcDst.StretchBlt(XDest,YDest,nDestWidth, nDestHeight, &hdcSrc,0,0,48,48,SRCCOPY);pOldBitmapImage = (HBITMAP)SelectObject(hdcDst.m_hDC,bm);// Release used DC and Object
DeleteDC(hDC);
DeleteObject(hBrushBorder);
DeleteObject(hBrushBk);return pOldBitmapImage;}void ListImage::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
OnOK();
}
----------------------------------------------------------------------------------------------------ListImage.h代码如下#pragma once
#include "afxcmn.h"
#include "afxwin.h"
// ListImage dialogclass ListImage : public CDialog
{
DECLARE_DYNAMIC(ListImage)public:
ListImage(CWnd* pParent = NULL); // standard constructor
virtual ~ListImage();
CImageList m_ImageList;
HBITMAP ListImage::LoadPicture(CString mFile);// Dialog Data
enum { IDD = IDD_DIALOG1 };protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnInitDialog();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
CListCtrl m_List;
CEdit m_edit2;
afx_msg void OnBnClickedOk();
};
BOOL SetBkImage( LPTSTR pszUrl, BOOL fTile = TRUE, int xOffsetPercent = 0, int yOffsetPercent = 0 );可以使用
m_ListCtrl.SetBkImage(MAKEINTRESOURCE(IDB_BMP));
使用ASSERT(AfxOleInit() != FALSE ); //Initialize COM libraries
m_List.SetBkImage("c:\\background2.bmp");
m_List.SetTextBkColor(CLR_NONE); //设置背景透明
BOOL CListBkImageDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // Set the icon for this dialog. The framework does this
// automatically when the application's main window is not
// a dialog.
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon // START HERE
// Insert Columns in the List Control m_List1.InsertColumn(0,"HEADER_1",LVCFMT_LEFT,180,1);
m_List1.InsertColumn(1,"HEADER_2",LVCFMT_LEFT,180,1);
m_List1.InsertColumn(2,"HEADER_3",LVCFMT_LEFT,193,1);
ListView_SetExtendedListViewStyle(m_List1.m_hWnd,
LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|
LVS_EX_FLATSB|LVS_EX_HEADERDRAGDROP );// Insert Background Image into the ListControl LVBKIMAGE bki; if (m_List1.GetBkImage(&bki) && (bki.ulFlags ==
LVBKIF_SOURCE_NONE))
{
m_List1.SetBkImage(TEXT("C:\\mahi.bmp"),TRUE);
// Use your own Image Address Here
}
// END HERE return TRUE; // return TRUE unless you set the focus to
// a control
}
BOOL CListBkImageApp::InitInstance()
{
AfxEnableControlContainer(); CoInitialize(NULL); // Initialize COM libraries......
....... return FALSE;
}红色的是重点 CSDN里面以前都有的东西 你自己不去好好找
这个就可以了实现了
从资源加载位图,给出的答案都是从外部路径加载的,这个我会。
另外其他答案真的都不行,要不你们自己尝试下吧,成功了再发我邮箱[email protected]
2.初始化 CoInitialize(NULL); // Initialize COM libraries
3.加载位图(失败,不报错,但没有图!)
HBITMAP hBmp=::LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_BITMAP1));
m_list.SetBkImage( hBmp);
这个是自绘的,去看一下
LoadBitmap是在什么时候执行?成功了吗?
http://www.codeguru.com/cpp/controls/listview/backgroundcolorandimage/article.php/c983/
这个网页我之前见过,不过他没有源码下载,我又太笨......回cnzdgs:
CListCtrl m_list手动添加的,在ListBkImageDlg.h里
LoadBitmap是在BOOL CListBkImageDlg::OnInitDialog()里添加的。
要不我把代码发给你瞧瞧?
结果会很明显,根本不行!!貌似03年的时候csdn上就有人提出了这个问题,不过提问者很牛,别人没给出合适的方法后,自己重载解决了。
我很笨,自己做不来,所以求高手......
我那天在网吧上网到时间了。。所以回不了你的问题了。
你把代码传到CSDN上吧,我看看
其实我不太明白xp风格按钮什么意思,不过我想显示图片和这个关系不大吧
回LaoWu:
实际自己创个对话框,加幅位图,然后定义个CListCtrl变量,就成了。1分钟。
都不用我贴代码,早先的回复都有详细步骤。
回XQGbearingob:
我这个星期至少下了20-30个实例了,都是背景色,或者用路径的.......
// 初始化
BOOL CXXApp::InitInstance()
{
::CoInitialize(NULL);
return TRUE;
}// 反初始化
int CXXApp::ExitInstance()
{
::CoUninitialize();
return CWinApp::ExitInstance();
}你的对话框程序部分
void CXXDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
// 控件与对象关联
DDX_Control(pDX, IDC_LIST_BK_IMAGE, m_lsBkImage);
}BOOL CXXDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CBitmap bitmap;
// 加载你需要的背景资源,这里是bmp位图
if ( bitmap.LoadBitmap(IDB_XX) )
{
m_lsBkImage.SetBkImage((HBITMAP)bitmap.GetSafeHandle());
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}上面应该是你需要的实现部分,你可以试试
程序是否使用XP控件风格很容易看出来,用程序显示一个对话框和系统中显示的对话框对比一下就知道的。
如果是VS2005,创建项目时使用默认设置,也不要修改字符集,这样创建出来的项目就是使用XP控件风格的。
如果是VC6,需要使用manifest文件,具体做法在网上搜索一下“XP控件风格”就可以找到。
{
int i=0;
int i_count=1;
HICON icon[1];
icon[0]=AfxGetApp()->LoadIcon (IDI_ICON2);
m_imagelist=new CImageList;
m_imagelist->Create(16,16,0,7,7);
m_imagelist->SetBkColor (RGB(255,255,255));
for(int n=0;n<i_count;n++)
{
m_imagelist->Add(icon[n]);
}
m_tree.SetImageList(m_imagelist,TVSIL_NORMAL);
}
楼主,你不就是要在CListCtrl里面用加载个资源的背景图么??
内容如下:<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>保存该文件,同时将文件重新命名,我这里假设命名为Style.manifest,同时将该文件放到你工程目录下的res文件夹中
然后打开你的工作,在添加资源的位置ResourceView中的工程上名右键选择insert插入选项,然后在弹出的对话框中选择custom自定义按钮,在弹出对话框的Resource Type下的编辑框中填入24,这个必须要添24,表示资源类型,然后点确定,这时会在ResourceView上出现一个24类型的资源节点,同时该节点展开的下面会出现一个默认的资源ID,一定要将该资源ID修改为1,然后右键该资源选择Properties会弹出一个资源属性对话框,在File name右边的编辑框中将原有的名称该为之前的那个Style.manifest,要带上路径即
res\Style.manifest,然后关闭重新编辑你的工程,然后看看你的可执行程序是否已经加载你设置的背景图片,如果没有设置成功,那么你再到res文件夹下找到res\Style.manifest文件,然后通过记事本或者UltraEdit打开该文件,在把上面的xml内容重新复制到这个文件中重新保存,然后再重新编译一下工程,再 看看,如果还不行,那我也没有什么办法了。呵呵
vc6不支持xp的风格,那么listCtrl不能使用位图资源的方式设置背景,2005可以,以后用2005或者2008,比vc6要方便。
// CSkinListCtrl 头的声明
class CSkinListCtrl : public CListCtrl
{
DECLARE_DYNAMIC(CSkinListCtrl)public:
CSkinListCtrl();
virtual ~CSkinListCtrl();protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
};// CSkinListCtrl 类的实现
IMPLEMENT_DYNAMIC(CSkinListCtrl, CListCtrl)CSkinListCtrl::CSkinListCtrl()
{}CSkinListCtrl::~CSkinListCtrl()
{
}
BEGIN_MESSAGE_MAP(CSkinListCtrl, CListCtrl)
ON_WM_PAINT()
END_MESSAGE_MAP()// CSkinListCtrl 消息处理程序void CSkinListCtrl::OnPaint()
{
CBitmap bmp;
bmp.LoadBitmapA(IDB_BITMAP1);
BITMAP bmpInfo;
bmp.GetBitmap(&bmpInfo); CPaintDC dc(this);
CDC memdc;
memdc.CreateCompatibleDC(&dc);
memdc.SelectObject(&bmp); dc.BitBlt(0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,&memdc,0,0,SRCCOPY); bmp.DeleteObject();
memdc.DeleteDC();
__super::OnPaint();
}
那还不如自己重载后实现一个listCtrl呢
先膜拜!!!
方法有效,已解决问题!
现有三个残留小case问题:
1.这个没有BUG隐患吧?发表时用带Style.manifest一起吗?我做的是半商业化的项目,只能用VC做,要发布的,所以我才找不从外部路径加载的方法。
2.“如果没有设置成功,那么你再到res文件夹下找到res\Style.manifest文件,然后通过记事本或者UltraEdit打开该文件,在把上面的xml内容重新复制到这个文件中重新保存,然后再重新编译一下工程”,这些问题都是你预料到的,呵呵。这个方法是基于什么原理的?
请简要解释下,或者给个网页链接吧
3.用2008 为什么VC经典的m_list.SetBkImage(_T("C:\\0.bmp"),TRUE);却不行?
而只能 CBitmap bitmap;
// 加载你需要的背景资源,这里是bmp位图
if ( bitmap.LoadBitmap(IDB_BITMAP1) )
{
m_List1.SetBkImage((HBITMAP)bitmap.GetSafeHandle());
}
或者: HBITMAP hBmp=::LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_BITMAP1));
m_List1.SetBkImage( hBmp);
2.因为你直接在工程中修改路径可能会将资源自己的描述信息重新写入到Style.manifest中,因为你创建这个自定义资源时,右边是空内容,你直接执行build或者保存可能会重写这个文件,为防止这种情况发生,自己还是再保存一次,以防万一。
3.vc6.0、vc2005都可以使用
BOOL SetBkImage(_In_z_ LPTSTR pszUrl, _In_ BOOL fTile = TRUE,_In_ int xOffsetPercent = 0, _In_ int yOffsetPercent = 0);
vc2008不能使用,可能微软看那么使用太麻烦了??
这个我就不太清楚了
记得给分哦,要不又白回答了。。