
用Picture Control显示CBitmap的位图
我的代码是这样的voidCaaDlg::OnBnClickedButton1(){CBitmap*pcBmp;pcBmp=newCBitmap;pcBmp->LoadBi...
我的代码是这样的
void CaaDlg::OnBnClickedButton1()
{
CBitmap *pcBmp;
pcBmp=new CBitmap;
pcBmp->LoadBitmap(_T("f:\\a.bmp"));
HBITMAP phBmp=(HBITMAP)(pcBmp);
Show.SetBitmap(phBmp);
UpdateData(false);
UpdateWindow();
}
其中Show是PictureControl控件的CStatic类型的Control变量。该程序没有任何反应。PictureControl的Type已经改成了Bitmap。
请高手指点迷津。
另外,网上能搜到的程序我全试了一遍,都是没反应。所以请不要从别的地方拷贝来答案。
如果答案正确,能追加多少分就追加多少分。 展开
void CaaDlg::OnBnClickedButton1()
{
CBitmap *pcBmp;
pcBmp=new CBitmap;
pcBmp->LoadBitmap(_T("f:\\a.bmp"));
HBITMAP phBmp=(HBITMAP)(pcBmp);
Show.SetBitmap(phBmp);
UpdateData(false);
UpdateWindow();
}
其中Show是PictureControl控件的CStatic类型的Control变量。该程序没有任何反应。PictureControl的Type已经改成了Bitmap。
请高手指点迷津。
另外,网上能搜到的程序我全试了一遍,都是没反应。所以请不要从别的地方拷贝来答案。
如果答案正确,能追加多少分就追加多少分。 展开
2个回答
展开全部
CBitmap类的LoadBitmap是不能从文件中加载位图的。
要从文件中加载位图,并得到HBITMAP句柄需要调用 LoadImage 函数:
HBITMAP phBmp = (HBITMAP)LoadImage(NULL, _T("f:\\a.BMP"),
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
然后,如果句柄有效,就可以使用图片控件加载位图了。
if (phBmp)
{
Show.SetBitmap(phBmp);
}
题外话就是:
1、楼主代码中使用 new 操作符创建了一个 CBitmap 类。但学C++的,都知道 new 一定要 delete 。楼主没有 delete 造成了内存泄露。
2、CBitmap 的 LoadBitmap 只能从资源中加载位图。因此,楼主首先要将磁盘中的位图文件导入到工程中,可以通过VS的资源编辑器导入(这个大家都会的)。
3、如果 LoadBitmap 成功后,CBitmap 的内部就维护了一个 HBITMAP ,这个 HBITMAP 在CBitmap 的析构函数中会被销毁,因此,如果调用了 delete 销毁 CBitmap ,这个HBITMAP 就不存在了。
4、需要获得CBitmap中的HBITMAP句柄,可以使用HBITMAP phBmp= (HBITMAP)pcBmp。一楼说的这行代码是错的,其实这行代码是正确的。因为 CBitmap 重载了类型操作符 HBITMAP 。
函数原型是:operator HBITMAP( ) const;
5、如果将提取出来的HBITMAP用于其它地方,譬如将HBITMAP关联到了图片控件,那么必须清楚,CBitmap 在析构函数被调用时,这个 HBITMAP 会被销毁,因此图片控件中的HBITMAP也会不存在,因为它们指向的是同一个资源。
6、如果不想让CBitmap 析构函数销毁 HBITMAP,可以先调用 CBitmap 类的基类的一个函数:HGDIOBJ Detach( );通过该函数,HBITMAP 将会从 CBitmap 中分离出来,这样 CBitmap 就不会销毁 HBITMAP 了,分离的时候注意它返回的是一个 HGDIOBJ ,需要将该句柄强制转换成 HBITMAP。还有要明白,一旦分离了, HBITMAP 的销毁工作就要由我们自己来负责了,否则又造成了资源泄露!
7、当通过图片控件的 SetBitmap将HBITMAP 关联到图片控件后,我们就不需要销毁 HBITMAP 了。因为,图片控件在销毁时(DestroyWindow),它会自行销毁 HBITMAP 的。
8、调用 SetBitmap 函数,图片控件自己会重绘的。不太明白 UpdateData(false) 和UpdateWindow() 的用意。
9、由于楼主是在按钮中来更新图片的,因此注意每次点击该按钮,都可能会分配一个全新的 HBITMAP ,在调用 SetBitmap 后,SetBitmap 会返回前一张图片的 HBITMAP,返回的目的,当然是便于我们自己来销毁前一张图片的 HBITMAP 。这一点也需要注意的,否则还是存在资源不断泄露的问题。销毁 HBITMAP ,使用 DeleteObject(phBitmap) 。
要从文件中加载位图,并得到HBITMAP句柄需要调用 LoadImage 函数:
HBITMAP phBmp = (HBITMAP)LoadImage(NULL, _T("f:\\a.BMP"),
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
然后,如果句柄有效,就可以使用图片控件加载位图了。
if (phBmp)
{
Show.SetBitmap(phBmp);
}
题外话就是:
1、楼主代码中使用 new 操作符创建了一个 CBitmap 类。但学C++的,都知道 new 一定要 delete 。楼主没有 delete 造成了内存泄露。
2、CBitmap 的 LoadBitmap 只能从资源中加载位图。因此,楼主首先要将磁盘中的位图文件导入到工程中,可以通过VS的资源编辑器导入(这个大家都会的)。
3、如果 LoadBitmap 成功后,CBitmap 的内部就维护了一个 HBITMAP ,这个 HBITMAP 在CBitmap 的析构函数中会被销毁,因此,如果调用了 delete 销毁 CBitmap ,这个HBITMAP 就不存在了。
4、需要获得CBitmap中的HBITMAP句柄,可以使用HBITMAP phBmp= (HBITMAP)pcBmp。一楼说的这行代码是错的,其实这行代码是正确的。因为 CBitmap 重载了类型操作符 HBITMAP 。
函数原型是:operator HBITMAP( ) const;
5、如果将提取出来的HBITMAP用于其它地方,譬如将HBITMAP关联到了图片控件,那么必须清楚,CBitmap 在析构函数被调用时,这个 HBITMAP 会被销毁,因此图片控件中的HBITMAP也会不存在,因为它们指向的是同一个资源。
6、如果不想让CBitmap 析构函数销毁 HBITMAP,可以先调用 CBitmap 类的基类的一个函数:HGDIOBJ Detach( );通过该函数,HBITMAP 将会从 CBitmap 中分离出来,这样 CBitmap 就不会销毁 HBITMAP 了,分离的时候注意它返回的是一个 HGDIOBJ ,需要将该句柄强制转换成 HBITMAP。还有要明白,一旦分离了, HBITMAP 的销毁工作就要由我们自己来负责了,否则又造成了资源泄露!
7、当通过图片控件的 SetBitmap将HBITMAP 关联到图片控件后,我们就不需要销毁 HBITMAP 了。因为,图片控件在销毁时(DestroyWindow),它会自行销毁 HBITMAP 的。
8、调用 SetBitmap 函数,图片控件自己会重绘的。不太明白 UpdateData(false) 和UpdateWindow() 的用意。
9、由于楼主是在按钮中来更新图片的,因此注意每次点击该按钮,都可能会分配一个全新的 HBITMAP ,在调用 SetBitmap 后,SetBitmap 会返回前一张图片的 HBITMAP,返回的目的,当然是便于我们自己来销毁前一张图片的 HBITMAP 。这一点也需要注意的,否则还是存在资源不断泄露的问题。销毁 HBITMAP ,使用 DeleteObject(phBitmap) 。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询