richview中的行高改变有点特别。必须在AfterData 事件执行的时候才能修改;

也就是说,如果简单的放一个按钮,去发送消息给richView->RichEdit ,然后调用frxReport1->ShowReport 是没有用的

正确的做法如下

  • 在C++ BUILDER 中增加一个函数SetLineSpace,用来修改RichView的行高
  • 在Form的Create事件中,调用frxReport->AddFunction 方法注册一个函数SetLineSpace
  • 在Form的Create时间中,调用frxReport->ScriptText 添加AfterData 响应脚本 (这不是必须的,如果直接编辑脚本固定死,也可以)
  • 在AfterData的脚本中,调用SetLineSpace
  • 在frxReport1->frxReport1UserFunction 响应事件中,调用SetLineSpace 函数。完成设置

下面是实现的代码

 

头文件

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "frxClass.hpp"
#include "frxDBSet.hpp"
#include "frxPreview.hpp"
#include <ADODB.hpp>
#include <DB.hpp>
#include "frxRich.hpp"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TfrxReport *frxReport1;
    TfrxPreview *frxPreview1;
    TfrxDBDataset *frxDBDataset1;
    TADOConnection *ADOConnection1;
    TADOQuery *ADOQuery1;
    TButton *Button1;
    TfrxRichObject *frxRichObject1;
    TEdit *Edit1;
    TEdit *Edit2;
    TLabel *Label1;
    TLabel *Label2;
    void __fastcall FormCreate(TObject *Sender);
    Variant __fastcall frxReport1UserFunction(const AnsiString MethodName,
          Variant &Params);
    void __fastcall frxReport1EndDoc(TObject *Sender);
    void __fastcall Button1Click(TObject *Sender);
private:    // User declarations
    bool d_flag;

public:        // User declarations
    __fastcall TForm1(TComponent* Owner);
    void TForm1::SetLineSpace(AnsiString name);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "frxClass"
#pragma link "frxDBSet"
#pragma link "frxPreview"
#pragma link "frxRich"
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    d_flag = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    ADOQuery1->Open();
//add event notify function
    frxReport1->AddFunction("void SetLineSpace(name:String)",
                        "SetLineSpace","change the linspace");
//add script for event handle
    frxReport1->ScriptLanguage = "C++Script";
    frxReport1->ScriptText->Clear();
    frxReport1->ScriptText->Add(
        "void richOnAfterData(TfrxComponent sender)"
        "{"
        "   SetLineSpace(Sender.Name); "
        "}" );
//don't forget it
    frxReport1->ScriptText->Add("{}");
//set the event handle for richview's onAfterData
    TfrxRichView* rich = dynamic_cast<TfrxRichView*>(
        frxReport1->FindObject("Rich1"));
    rich->OnAfterData = "richOnAfterData";
}
//---------------------------------------------------------------------------
void TForm1::SetLineSpace(AnsiString name)
{
    TfrxRichView* rich = (TfrxRichView*)frxReport1->FindObject(name);
    rich->RichEdit->SelectAll();
    PARAFORMAT2 Para;
    Para.cbSize = sizeof(Para);
    Para.dwMask = PFM_LINESPACING;
    Para.bLineSpacingRule = 4;
    Para.dyLineSpacing  = Edit1->Text.ToIntDef(200);
    SendMessage(rich->RichEdit->Handle, EM_SETPARAFORMAT, 0, LPARAM(&Para));

    rich->RichEdit->SelAttributes->Size = Edit2->Text.ToIntDef(20);
}

Variant __fastcall TForm1::frxReport1UserFunction(
      const AnsiString MethodName, Variant &Params)
{
    if (MethodName.UpperCase() == AnsiString("SetLineSpace").UpperCase())
    {
        SetLineSpace(Params.GetElement(0));
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::frxReport1EndDoc(TObject *Sender)
{
    d_flag = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//if click quickly ,the d_flag'll protect the thread synchrolized
//otherwise your may get an error
    if (d_flag)
    {
     d_flag = false; //这句一定要放在前面 frxReport1
->ShowReport(); } } //---------------------------------------------------------------------------

 

实现的效果

 

此时文字重叠了

 

除了上述方法之外,还有一个更简单的办法。

 

在frxReport的OnBeginDoc事件中,调用下面的代码来修改行距,关键点是,给RichView发送消息,必须在BeginOnDoc事件或者是RichView的RTF被赋值之后调用修改行距的函数。

void TDataMod_T::SetRichEditLineSpace()
{

    TfrxRichView* rich = dynamic_cast <TfrxRichView *> (frxReport1->FindObject("Rich1"));

    if (rich != NULL && rich->Tag > 0)
    {
        rich->RichEdit->SelectAll();
        PARAFORMAT2 Para;
        Para.cbSize = sizeof(Para);
        Para.dwMask = PFM_LINESPACING;
        Para.bLineSpacingRule = 4;
        Para.dyLineSpacing  = rich->Tag*4;
        SendMessage(rich->RichEdit->Handle, EM_SETPARAFORMAT, 0, LPARAM(&Para));
    }


}

除了OnBeginDoc,还可以使用frxReport组件的OnBeforePrint 

void __fastcall TForm1::frxReport1BeforePrint(TfrxReportComponent *Sender)
{
    TfrxRichView* rich = dynamic_cast<TfrxRichView*>(Sender);
    if (rich == NULL)
    {
        return;
    }
    rich->Tag = 20;
    if (rich != NULL && rich->Tag > 0)
    {
        rich->AllowExpressions = false;
        AnsiString text = rich->RichEdit->Text;
        rich->RichEdit->SelectAll();
        PARAFORMAT2 Para;
        Para.cbSize = sizeof(Para);
        Para.dwMask = PFM_LINESPACING;
        Para.bLineSpacingRule = 4;
        Para.dyLineSpacing  = rich->Tag*40;
        SendMessage(rich->RichEdit->Handle, EM_SETPARAFORMAT, 0, LPARAM(&Para));
    }
}

 

posted on 2016-07-03 16:20  zooz  阅读(1753)  评论(2编辑  收藏  举报