【转】如何在VC++下动态调整水晶报表图片的大小

本文转自:http://blog.csdn.net/memory_xj/archive/2008/04/24/2322071.aspx ,原作者:青蛙王子


我用的是VS2005中的内嵌水晶报表,在采用拉模式下,我们可以将数据库中的大字段(Access是ole,Oracle是blob,SQL Server是image)直接拉至水晶报表相应位置并显示出来。
但是这种方法有一个很严重的缺陷,那就是预设大小是无法改变的。
在对象格式中,“图片大小”选项卡中图片宽、高是没有公式可以编辑的,这样如果数据库中保存的图片和预设大小不相同,就产生变形,
为了解决这个问题,我在网上找了很长时间,也没有好的简单办法,在运行时动态改变图片大小看来是唯一解决途径了。

       软件环境:WinXP\VS2005 VC++\内嵌水晶报表\SQL Server

       解决步骤:
       一、VC++中使用水晶报表的一般步骤,如不会请看:http://blog.csdn.net/memory_xj/archive/2008/04/16/2296970.aspx

       二、再增加一个类成员变量:
      ISectionsPtr m_Sections;       //水晶报表的节接口

       三、增加一个类成员函数:
ISectionPtr CRptDialog::GetReportSection(int SectionNum)
      // 函数名:GetReportSection
      //用途:通过节下标,得到相应的节接口ISectionPtr
      //SectionNum为节下标,从1(报表布眉)开始,以此类推,得到节接口
      //作者:青蛙王子
{
   ISectionPtr pSection = NULL;

    VARIANT var;
    VariantInit (&var);
    var.vt = VT_I2;
    var.lVal = SectionNum;

    HRESULT hr = m_Sections->get_Item(var, (ISection**) &pSection);

    ASSERT(SUCCEEDED(hr));
    VariantClear(&var);
    return pSection;
}

      四、添加以下代码,我们的目标是动态改变第3节(即详细资料a节)中的一个对象名为xjaaagzimage1的数据库图片的宽和高。
      try{
  this->m_Application.CreateInstance(__uuidof(Application));
  m_Report = m_Application->OpenReport("d:\\zjA4.rpt");
  //m_Report->SetReportVariableValue(_bstr_t("xjID"), _variant_t((m_pView->GetDocument()->ReadXjID()))); //这种方法无效,控件不能显示

  //向水晶报表中传递参数xjID
  m_Report->ParameterFields->GetItemByName("xjID")->AddCurrentValue(_variant_t((short)10));   
  
  //因为小结管柱图是直接从数据库图像字段中显示,长宽是设计时预设固定的,也没有公式编辑,没有天理哪!
  HRESULT hr = m_Report->get_Sections((ISections**) &m_Sections);
  ASSERT(SUCCEEDED(hr));
  ISectionPtr pSection = GetReportSection(3);  //得到第三节(即详细资料a)的接口指针
  IReportObjectsPtr pReportObjects = NULL;
  IReportObjectPtr pReportObject = NULL;
  hr = pSection->get_ReportObjects((IReportObjects**)&pReportObjects); //得到详细资料a节内所有对象接口
  ASSERT(SUCCEEDED(hr));

  VARIANT var;
  VariantInit(&var);
  var.vt = VT_I2;

  long objCount = 0;
  pReportObjects->get_Count(&objCount); //得到对象数目
  for (long i = 1; i <= objCount; i++)  //水晶报表对象数组下标是从1开始(应该是普遍现象),不能想当然地从0开始,否则会有异常
  {
   var.lVal = i;
   pReportObjects->get_Item(var, (IDispatch**)&pReportObject);
   //得到对象名称,如果是管柱图xjaaagzimage1,就将长宽进行设置
   BSTR objNameBSTR;
   pReportObject->get_Name(&objNameBSTR);  //得到对象名称
   CString sObjName(objNameBSTR);
   SysFreeString(objNameBSTR);
   if (sObjName == "xjaaagzimage1")     
//找到对象(用CompareNoCase是否更好?),就设置其宽和高,
//注意它好象是用VC++编写的,模式是MM_HIMETRIC即1mm=100
//水晶报表的度量单位是缇,缇(1厘米=567缇,1英寸=1440缇,1磅=20缇,1像素=15缇)
   {
    pReportObject->put_Width(576);   //1cm宽
    pReportObject->put_Height(576); //1cm高
   }
   else
   {
    continue;
   }
  }
 //设置完毕,继续水晶报表操作的一般步骤

//设置数据源,注意jbServer是我的ODBC中的DSN名称。  
m_Report->Database->Tables->Item[1]->SetLogOnInfo("jbServer","jianbong","jb_designer","zcgys");
  m_Report->put_ReportAuthor((_bstr_t)"青蛙王子");
  m_pRptViewer.put_ReportSource(m_Report);
  m_pRptViewer.put_EnableGroupTree(FALSE);
  m_pRptViewer.Refresh();
  m_pRptViewer.ViewReport(); 
 }
 catch(...)
 {
 }

好了,按下F5运行一把吧,祝你成功!

posted @ 2008-11-02 10:06  阿泰  阅读(847)  评论(0编辑  收藏  举报