C++Builder制作记事本程序的几点补充

台州 林华锋

    C++Builder提供了极其丰富的组件,使我们的编程工作变得轻松而愉快,其中可直接用于编写记事本程序有Memo组件和RichEdit组件两个。这两个组件的区别在于Memo组件开发的应用程序类似Windows下的文本编辑器,而RichEdit组件开发的类似于微软的Word软件,两者在文本的处理方式上也有所区别。由于RichEdit组件提供了比Memo组件更多、更强大的功能,因此建议读者使用RichEdit组件进行开发此类程序。现在我就以编写过程中会遇到的要点、难点来简要介绍记事本程序的开发过程。

1.命令行参数的获取

关于Windows下的文本编辑器大家肯定很熟悉吧。当双击一个文本文件时,系统就会自动调出文本编辑器并把它打开。这一过程包含了文件关联及使用命令行参数传递文件名两部分。现在我们就来介绍一下命令行参数的使用,C++Builder获取命令行参数的方法是调用VCL的 ParaStr()函数,再调用ParamCount()函数来确定命令行参数个数。ParamStr返回一个AnsiString对象,若参数为0,ParamStr 将返回可执行文件的全称路径。若参数为1,返回程序名及第一个命令行参数,参数为2,返回第二个参数,以此类推。我们通过第一个命令行参数带回被点击文件的全称路径,从而实现以上功能。在程序中加入以下代码实现:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

if(ParamCount()>0)// 返回第一个命令行参数

{

fn=ParamStr(1);

this->Caption="LC记事本 - "+fn;//更改窗口标题内容

RichEdit1->Lines->LoadFromFile(fn);// 打开文本内容

}

}

2.正确判断输入文本的状态

RichEdit组件的Modified属性和CanUndo属性都可以判断文本是否产生变化。区别在于Modified属性判断组件所包含的文本是否变化,CanUndo属性则判断输入的文本是否产生变化、是否可以Undo操作。这里要注意的是当程序用传递命令行参数打开文本,并且WordWrap属性设为false时,用Modified属性判断输入文本的状态就会有麻烦(不管你有没有修改过文本内容,判断的返回值都是tuue,有兴趣的朋友不妨去试一下)。因此在编写判断文本状态代码时一定要使用CanUndo属性来判断。

例如:

void __fastcall TForm1::RichEdit1Change(TObject *Sender)

{

if(RichEdit1->CanUndo)

{

//加入具体的代码

}

}

3.动态控制菜单、工具按钮的显示

    加入菜单、工具按钮的动态显示功能,会使程序的操作变的更生动、更明了。C++Builder使我们很容易的实现此项功能。例如,当按下“撤消”菜单按钮时,先执行撤消操作,然后“撤消”菜单按钮变成“重做”菜单按钮。按下“重做”菜单按钮时,执行重做操作,然后“重做”菜单按钮又变成“撤消”菜单按钮。

void __fastcall TForm1::N1Click(TObject *Sender)

{

static int flag=1;

if(flag==1)

{

RichEdit1->Undo();//执行撤消操作

N3->Caption="重做";//“撤消”菜单按钮变成“重做”菜单按钮

}

else

{

RichEdit1->Undo();//执行重做操作

N3->Caption="撤消";//“重做”菜单按钮变成“撤消”菜单按钮

}

flag=-flag;

}

4.增加时间/日期盖章

这是Windows文本编辑器中一项挺实用的功能,我们用C++Builder实现此功能非常的简单,代码如下:

void __fastcall TForm1::N2Click(TObject *Sender)

{

//在文本中插入时间/日期

RichEdit1->SetSelTextBuf(DateTimeToStr(Now()).c_str());

}

5.增加搜寻、查找功能

一个完整的记事本程序是少不了这一项功能的。C++Builder提供了FindDialog组件帮助我们完成此项功能,具体代码如下:

//对查找按钮的事件响应

void __fastcall TForm1::FindButtonClick(TObject *Sender)

{

FindDialog1->Execute();

}

//对FindDialog组件的OnFind事件的响应及查找操作的实现

void __fastcall TForm1::FindDialog1Find(TObject *Sender)

{

TSearchTypes ft;

static int fpos,atpos=0;

if(FindDialog1->Options.Contains(frMatchCase))

ft<<stMatchCase;

if(FindDialog1->Options.Contains(frWholeWord))

ft<<stWholeWord;

RichEdit1->SelStart=atpos;

fpos=RichEdit1->FindText(FindDialog1->FindText,RichEdit1->SelStart,

RichEdit1->Text.Length(),ft);

if(fpos!=-1)

{

RichEdit1->SetFocus();

RichEdit1->SelStart=fpos;

RichEdit1->SelLength=FindDialog1->FindText.Length();

}

else

{

Application->MessageBox("搜寻完毕!","LC记事本",MB_OK+MB_ICONINFORMATION);

RichEdit1->SelStart=0;

}

if(FindDialog1->Options.Contains(frDown))

atpos=RichEdit1->SelStart+FindDialog1->FindText.Length();

else

atpos-=FindDialog1->FindText.Length();

}

6.程序退出时检查文本是否被修改

用户在辛辛苦苦的完成一篇文章后,很有可能忘记存盘就退出程序,因此在程序退出时检查文本状态是十分有必要的。具体代码如下:

void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)

{

int lc;

String lcstr;

lcstr=fn+"内容已经被更改,\n你是否要保存?" ;

lc=Application->MessageBox(lcstr.c_str(),"LC记事本",

MB_YESNOCANCEL+MB_ICONINFORMATION);//弹出对话框提醒用户是否要保存修改

if(lc==IDYES)

RichEdit1->Lines->SaveToFile(fn);//保存修改的内容

else if(lc==IDCANCEL)

CanClose=false;//取消退出程序操作

}

    以上的程序段在中文Windows98,C++Builder4.0专业版中调试通过。

返回