VC++实现显示透明的256色以上的图标

来源:岁月联盟 编辑:zhu 时间:2008-11-13
 在学习Visual C++编程的过程中,有很多朋友可能会问Visual C++中如何保证256色以上的图标加载后不失真。虽然有介绍如何实现256色以上的工具栏的文章,但是方法中大都采用加载一幅256色以上的工具栏位图的方法。这样的方法存在一个麻烦就是用什么简便好用的制图工具来做这样的位图呢?相信读者朋友都希望能有更直接的方法来使用256色以上的图标,并且能够以透明的效果不失真地将图标显示出来。本实例介绍了实现上述目标的方法,实现了在工具条上显示透明的256色位图。

  一、透明显示256色的图标

  一、实现方法

  一般情况下,我们如果碰到需要在程序中使用图标的问题,首先要想到要用图像列表CimlageList类,该类是相同尺寸的图像或图标的集合,每个图像或图标用以"0"为基准的索引号来表征,因此它能有效地管理大量图标或位图。CimageList类常与列表控件ClistCtrl、树控件CtreeCtrl或标签控件CtabCtrl一起使用,在本实例中,该类与CtoobBarCtrl类一起使用。

  CimageList类的成员函数Create()初始化图像列表并且将它附加到一个CimageList对象上,该函数原型为:

  BOOL Create(int cx,int cy,BOOL bMask,int nInitial,int nGrow);

  函数中前两个参数cx、cy指定了图标/图像的宽度和高度,即:图标/图像的尺寸定义。 第三个参数bMask为掩模标志,它指定何如显示图标/图像。如果该值等于ILC_ COLOR8说明以256色的调色板来显示图标/图像。而等于值"TRUE"则指明了以透明方式来显示图标/图像。那么如果两者进行"按位或"运算后的意义就变为:以透明方式来显示256色图标。 函数中的第四和第五个参数则分别表示为:初始图标个数和新增图标时对象自动申请内存空间的步长。如果在大批量操作图标,并且需要不断的增删图标时,设置第五个参数可以改变程序的性能,如果第五个参数设置的比较适中则可以避免程序反复的申请和释放内存空间。

 创建过CImageList类后,还需要将各个图标装载到该类的对象中去,具体实现过程可以先用Windows的API函数LoadImage()装载图标资源,然后用CImageList类的Add(HICON hIcon)函数加将装载后的图表添加到CImageList类对象中去。其中LoadImage()的函数原型如下:

  HANDLE LoadImage(
   HINSTANCE hinst, // handle of the instance containing the image
   LPCTSTR lpszName, // name or identifier of image
   UINT uType, // type of image
   int cxDesired, // desired width
   int cyDesired, // desired height
   UINT fuLoad // load flags
  );

  上述函数用来装载图标、图像或光标资源,如果调用成功,函数返回装载的资源的句柄,否则返回"NULL"。其中参数hinst为包含图标/图像资源的应用程序句柄;lpszName为资源的名字,该资源名字的获取可以使用MAKEINTRESOURCE()函数将资源ID转换得到;参数uType说明当前资源的类型,是图标、图像还是光标;cxDesired和cyDesired为希望的目标尺寸;最后一个参数是装载标志,在处理图标资源时,一般情况下设置为"0"。

  最后,需要调用CToolBarCtrl类的CImageList* SetImageList( CImageList* pImageList )函数将图标列表对象与工具条对象关联起来,从而在工具条上显示出装载的图标。

  二、编程步骤

  1、 启动Visual C++6.0,建立一个单文档工程(多文档也可)的应用程序,命名为"TB";

  2、 在程序的主框架CMainFrame类的头中定义一个CImageList对象,代码如下:CImageList m_ilTB;

  3、 在应用程序中添加256色的彩色图标,具体方法是启动程序中图标资源编辑器,点击资源编辑器上的"New Device Image"按钮,在弹出的对话框中选择"自定义"就可以了,实例程序中采用的图标大小为32*32,颜色为256色;

 4、 添加代码,编译运行程序;

  三、程序代码

  //////////////////////////////////////////////////////////////////////////////////////
  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  {
   if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
    return -1;
   if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE |
    CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY |
    CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
   {
    TRACE0("Failed to create toolbarn");
    return -1; // fail to create
   }
   if (!m_wndStatusBar.Create(this) ||
    !m_wndStatusBar.SetIndicators(indicators,
    sizeof(indicators)/sizeof(UINT)))
   {
    TRACE0("Failed to create status barn");
    return -1; // fail to create
   }
   //设置ToolBar的图标列表
   m_ilTB.Create(32, 32, TRUE | ILC_COLOR8, 4, 0);
   HICON hIcon = NULL;
   hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 32, 32, 0);
  m_ilTB.Add(hIcon);
   hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON2), IMAGE_ICON, 32, 32, 0);
  m_ilTB.Add(hIcon);
   hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),
  MAKEINTRESOURCE(IDI_ICON3), IMAGE_ICON, 32, 32, 0);
   m_ilTB.Add(hIcon);
   hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON4), IMAGE_ICON, 32, 32, 0);
  m_ilTB.Add(hIcon);
   m_wndToolBar.GetToolBarCtrl().SetImageList(&m_ilTB);
   // TODO: Delete these three lines if you don't want the toolbar to be dockable
   m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
   EnableDocking(CBRS_ALIGN_ANY);
   DockControlBar(&m_wndToolBar);
   return 0;
  }

  四、小结

  本实例通过灵活的使用CImageList类的Create()函数实现了透明的256色位图的显示,其实Visual C++中的CImageList类远比我们想象的强大的多,例如通过图标的掩模操作也能实现包括透明显示的各种效果,只是没有我们这里介绍的方法简单而已。有兴趣的读者朋友可以仔细研究研究,相信一定会获益匪浅。