对话框显示图片

来源:互联网 发布:数据库防护系统 编辑:程序博客网 时间:2024/05/05 23:15
在用VC开发应用程序的时候,经常要在对话框上显示位图。如果把位图加入资源中,当然是省时省力,但程序却也增肥不少,并且失去了灵活性。而如果你要动态地显示一大堆图片,各个图片大小不一,这岂不…本文就是介绍如何在对话框上显示位图,并且如何让对话框自动适应位图的大小的。

---- VC对位图的操作比较烦琐,要显示一个位图到对话框上去,很麻烦。我在开发的过程中走通了两条路:一是使用Kodak图象编辑控件;二是利用Microsoft提供的例子中的一个类,并稍加改造。两种方法各有优缺点。我把它写下来,以避免其他人多走弯路。

一、利用控件

利用WINDOWS98中带的Kodak图象编辑控件来在对话框上显示一个位图,虽然有点儿杀鸡用牛刀的感觉,但却不失为一个极方便快捷的方法。顾名思义,这个控件不但可以显示,它更强大的功能还是在编辑图象,它可以对图象进行放大、缩小、标注等操作。而且,使用起来很方便。但它毕竟是别人的东东,不太清楚它的底细,用起来就不免…我就吃了它的苦头。在本机上调试通过,安装了其他几台机器也很正常,但是有一台却颜色失真了,变成了水粉画。不知是不是那台机器的显卡有问题。还有就是据我初步实验,在95下好象行不通。不过现在大家都是WIN98,这似乎已经不算一个问题了。下面就把我的过程写下来:

首先应该保证系统中有这个控件。注意,它不能单独使用,必须和其他几个控件(特别是Imgcmn.dll)一同使用。如果没有,从别的机器上copy过来即可。这几个文件是Imgadmin.ocx,Imgcmn.dll,Imgedit.ocx,Imgscan.ocx,Imgshl.dll,Imgthumb.ocx,Imgutil.dll,把它们copy到windows/system目录下,然后用regsvr32.exe将它们分别注册。

打开VC,新建一个基于对话框的工程(主要是为了说明方便),删除掉对话框上其他的东西(按钮和LABEL),在对话框上单击右键,单击Insert Activex control… 选择Kodak图象编辑控件,大小任意。

在对话框上选中该控件,打开view|classwizard,单击Member Variables,点击Add Variable…按钮,系统会弹出一个对话框,大体上是提示你它要把控件加入工程中了,确定即可。在接下来的对话框上继续点击OK,此时,会出现一个对话框,提示你输入变量名,输入你想要的名字即可。我们输入m_ctrlPicture。单击确定。

此时你的工程中已经有了一个名字为m_ctrlPicture的控件,接下来就可以利用它来显示图片了,我们把它加到对话框的初始化中。单击ClassWizard,选择OnInitDialog,单击Edit Code按钮。

在OnInitDialog中,找到// TODO: Add extra initialization here,在下面加入如下代码:
m_ctrlPicture.SetImage("c://windows/Clouds.bmp");
m_ctrlPicture.Display();


编译运行,看到了吗?就这么简单。

但是它的大小却是固定的,要看全图只能利用滚动条。下面我们再来得到图象的尺寸,然后使对话框自动适应图象的大小。还是在初始化中,代码如下:
m_ctrlPicture.SetImage("c://windows//Clouds.bmp");
const int nAddConst=40;
//图象尺寸不会正合适,需要加点增量。
long lPictureWidth=m_ctrlPicture.GetImageWidth();
long lPictureHeight=m_ctrlPicture.GetImageHeight();
MoveWindow(0,0,lPictureWidth,lPictureHeight,true);
//改变对话框大小

//改变控件的大小
m_ctrlPicture.MoveWindow(0,0,lPictureWidth,
lPictureHeight+nAddConst,true);
m_ctrlPicture.Display();

成功了。
注意,这个控件不但只能显示bmp,还可显示许多其他的格式,你可以自己试一下。


二、利用Cdib类

这个方法比较烦琐,并且只能显示bmp,但它不依赖特定的系统,也比较实用。这个类在MSDN提供的例子中有,名字为ex10c.dsw,找到cdib.cpp和cdib.h,加入你的工程即可。如果你找不到,也可以到我的网页去看看或者给我写信ytdl@263.net。

---- 下面是过程:

新建一个基于对话框的工程,单击Add Files to Project,加入上面所说的两个文件。

在对话框的头文件中加入#include "cdib.h",然后给对话框类加入一个成员变量,代码如下: Cdib m_dibFile;

在对话框的初始化函数中,加入如下代码:
#ifdef MEMORY_MAPPED_FILES
if (m_dibFile.AttachMapFile
("c://windows//clouds.bmp",TRUE)==TRUE)
{ // share
Invalidate();
}
#else
CFile file;
file.Open("c://windows//clouds.bmp",
Cfile::modeRead);
if (m_dibFile.Read(&file) == TRUE)
{
Invalidate();
}
#endif // MEMORY_MAPPED_FILES
CClientDC dc(this);
m_dibFile.SetSystemPalette(&dc);


在OnPaint函数中,找到else,然后在里面加入如下代码:
BeginWaitCursor();
m_dibFile.UsePalette(GetDC());
CSize sizeFileDib = m_dibFile.GetDimensions();
m_dibFile.Draw(GetDC() ,CPoint(0,0), sizeFileDib);
EndWaitCursor();

运行程序,是不是看到蓝天白云了?!下面继续加入让对话框自动适应图片大小的代码,还是在初始化中,紧接这上一次的代码,加入如下两行:
CSize sizeFileDib = m_dibFile.GetDimensions();
MoveWindow(0,0,sizeFileDib.cx,sizeFileDib.cy,true);

完全显示了吗?也许不完全合适,你可以细微地调整cx,cy两个参数,使之适应。
 
 

三:

1、在BMP的类bmpDlg.h中定义一个刷子,CBrush m_brBk;
2、在bmpDlg.cpp中,装载BMP图片,并把图片与m_brBk绑定在一起。
BOOL CBmpDlg::OnInitDialog()
{
    CBitmap bmp;

    bmp.LoadBitmap(IDB_BITMAP2);

    m_brBk.CreatePatternBrush(&bmp);

    bmp.DeleteObject();
}
3、利用CLASS WIZARD添加WM_CTRCOLOR消息的响应函数HBRUSH CBmpDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);并在该函数中添加如下代码:
{
  if (pWnd == this)
  {
      return m_brBk;
  }
  {
       return hbr;
  }
}
4、编译、运行即可。

 

四: 通过CBitmap,HBITMAP,直接用OnPaint()绘制

首先在CTestDlg类中声明一个变量: CBitmap m_bmp;

然后我们在对话框中加入一个picture 标签,名为IDC_STATIC1

然后:

BOOL CDisplayPic::OnInitDialog()

{

CDialog::OnInitDialog();

if( m_bmp.m_hObject != NULL )//判断

m_bmp.DeleteObject();

/////////载入图片

HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),

c://aaa.bmp, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);

if( hbmp == NULL )

return FALSE;

///////////////////////该断程序用来取得加载的BMP的信息////////////////////////

m_bmp.Attach( hbmp );

DIBSECTION ds;

BITMAPINFOHEADER &bminfo = ds.dsBmih;

m_bmp.GetObject( sizeof(ds), &ds );

int cx=bminfo.biWidth; //得到图像宽度

int cy=bminfo.biHeight; //得到图像高度

/////////////////// ////////////////////////////////

/////////////得到了图像的宽度和高度后,我们就可以对图像大小进行适应,即调整控件的大小,让它正好显示一张图片///////////////////////////

CRect rect;

GetDlgItem(IDC_STATIC1)->GetWindowRect(&rect);

ScreenToClient(&rect);

GetDlgItem(IDC_STATIC1)->MoveWindow(rect.left,rect.top,cx,cy,true);//调整大小

 

return TRUE; // return TRUE unless you set the focus to a control

// EXCEPTION: OCX Property Pages should return FALSE

}

图片加载成功了,标签大小也适应了,下面就是绘制绘制图像了,打开类向导,重载WM_PAINT消息

void CDisplayPic::OnPaint()

{

//////////////以下三种情况任选一种会是不同效果(只能一种存在)///////////

//CPaintDC dc(this); //若用此句,得到的是对话框的DC,图片将被绘制在对话框上.

CPaintDC dc(GetDlgItem(IDC_STATIC1)); //用此句,得到picture控件的DC,图像将被绘制在控件上

// CDC dc;

// dc.m_hDC=::GetDC(NULL); //若用此两句,得到的是屏幕的DC,图片将被绘制在屏幕上///////////////////////////////////////////////////////

CRect rcclient;

GetDlgItem(IDC_STATIC1)->GetClientRect(&rcclient);

CDC memdc;

memdc.CreateCompatibleDC(&dc);

CBitmap bitmap;

bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());

memdc.SelectObject( &bitmap );

 

CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0);

 

CDC maskdc;

maskdc.CreateCompatibleDC(&dc);

CBitmap maskbitmap;

maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);

maskdc.SelectObject( &maskbitmap );

maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc,

rcclient.left, rcclient.top, SRCCOPY);

 

CBrush brush;

brush.CreatePatternBrush(&m_bmp);

dc.FillRect(rcclient, &brush);

 

 

dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(),

&memdc, rcclient.left, rcclient.top,SRCPAINT);

brush.DeleteObject();

 

// Do not call CDialog::OnPaint() for painting messages

}

原创粉丝点击