接着上一讲,我们继续我们的ScratchPad程序的继续编写。
编写代码
有了所有这些菜单项但没有代码使它工作。要有大量工作来完成这些,实际上很容易。大多数所需代码使TMemo类已有的部分。所要做的是在菜单处理程序中调用TMemo方法。还要做一些其他的事情,但增加的大部分代码是以前见过的。
1、增加组件到窗体
在编写代码之前,需要在增加OpenDialog与SaveDialog组件到窗体:
(1)把OpenDialog组件放到窗体上,将其Name属性改为OpenDialog。
(2)把SaveDialog组件放到窗体上,将其Name属性改为SaveDialog。
(3)把MainMenu、OpenDialog与SaveDialog图标在窗体上排成一行。
2、写主菜单项的代码
上面的添加组件非常简单。现在继续给菜单项写代码。开始,我先编写【File | Exit】菜单项代码(这是最容易的!)。要保证Menu Designer已经关闭,不至于混淆Menu Designer和Form Designer。
(1)从Form Designer主菜单选择【File | Exit】,Code Editor会出现在前端,并且显示FileExitClick事件处理程序。
(2)光标已经定位在FileExitClick事件处理程序中,在光标处键入代码:
procedure TMainForm.FileExitClick(Sender: TObject);
begin
Close;
end;
Note
上面的2步里面用了Close来关闭窗体。因为这是应用程序的主窗体,它是有效的。若想从程序的任意地方中断应用程序,应使用:
Application.Terminate;
这个代码保证程序是中断的,不管当前哪个窗体是开的。
就是这样容易。在做一个,让读者自己完成其余部分。
(1)从主菜单选择【Edit | Cut】,Code Editor出现在顶端,并显示EditCutClick事件处理程序。
(2)输入以下代码:
procedure TMainForm.EditCutClick(Sender: TObject);
begin
Memo.CutToClipboard;
end;
对于Cut菜单就是这样一句话就搞定了,也许没有全部意识到这点,VCL在幕后做了许多工作。框架的整个思想使程序员避免低水平的细节负担。
3、结尾工作
像Delphi那样的程序有趣的一个方面是很少看到整个程序。Delphi方面地提供了自理具体事件的代码段,因此通常看到的是程序小块。下面的清单中显示ScratchPad程序到此为止的主窗体单元。类声明完全由Delphi产生。遵循刚做的例子来写其余的菜单项代码。
4、详细解释和说明
【File | New】菜单项代码
procedure TMainForm.FileNewClick(Sender: TObject);
var
Res: Integer;
begin
{ 新建一个文件,先检查当前文件是否已经保存,如果没有保存
怎提示消息是否保存,选择“是”则保存当前文件
选择“否”则忽略保存当前文件 }
if Memo.Modified then
begin
Res := Application.MessageBox('The current file has changed. Save changes?',
'ScratchPad Message', MB_YESNOCANCEL);
{ 如果点击“是”则先保存当前的文件}
if Res = IDYES then
FileSaveClick(Sender);
{ 如果点击“取消”则什么也不做}
if Res = IDCancel then
Exit;
end;
{ 删除Memo已有的字符}
if Memo.Lines.Count > 0 then
Memo.Clear;
{ 设置SaveDialog的FileName属性为空字符串,
为的是让我们知道文件还没有存储 }
SaveDialog.FileName := '';
end;
【File | Open…】菜单项代码
procedure TMainForm.FileOpenClick(Sender: TObject);
var
Res: Integer;
begin
{ 打开一个文件,先检查当前文件是否已经保存,如果没有保存
怎提示消息是否保存,选择“是”则保存当前文件
选择“否”则忽略保存当前文件 }
if Memo.Modified then
begin
Res := Application.MessageBox('The current file has changed. Save changes?',
'ScratchPad Message', MB_YESNOCANCEL);
if Res = IDYES then
FileSaveClick(Sender);
if Res = IDCANCEL then
Exit;
end;
{ 执行打开文件对话框选择要打开的文件
点击“确定”后,用LoadFromFile方法打开文件,
首先,清楚FileName属性}
OpenDialog.FileName := '';
if OpenDialog.Execute then
begin
if Memo.Lines.Count > 0 then
Memo.Clear;
Memo.Lines.LoadFromFile(OpenDialog.FileName);
SaveDialog.FileName := OpenDialog.FileName;
end;
end;
【File | Save…】
procedure TMainForm.FileSaveClick(Sender: TObject);
begin
{ 先判断SaveDialog.FileName属性是否为空,
如果不为空,则直接调用SaveToFile方法,否则调用SaveDialog对话框保存}
if SaveDialog.FileName <> '' then
begin
Memo.Lines.SaveToFile(SaveDialog.FileName);
{ 设置Memo.Modified为False,一旦保存完成的话}
Memo.Modified := False;
end else
{ 如果FileName属性为空,则调用另存为对话框}
FileSaveAsClick(Sender);
end;
【File | Save As…】
procedure TMainForm.FileSaveAsClick(Sender: TObject);
begin
{ 显示SaveDialog对话框保存文件,
并且设置Memo.Modified为False,一旦保存完成}
SaveDialog.Title := 'Save As...';
if SaveDialog.Execute then
begin
Memo.Lines.SaveToFile(SaveDialog.FileName);
Memo.Modified := False;
end;
end;
【Edit | Undo】
procedure TMainForm.EditUndoClick(Sender: TObject);
begin
{ TMemo组件没有提供Undo撤销方法,
因此只能通过发送WM_UNDO消息来实现}
SendMessage(Memo.Handle, WM_UNDO, 0, 0);
end;
【Edit | Select All】
procedure TMainForm.EditSelectAllClick(Sender: TObject);
begin
{ 调用Memo.SelectAll方法实现全选功能}
Memo.SelectAll;
end;
【Edit | Copy】
procedure TMainForm.EditCopyClick(Sender: TObject);
begin
{ 调用Memo.CopyToClipboard方法}
Memo.CopyToClipboard;
end;
【Edit | Paste】
procedure TMainForm.EditPasteClick(Sender: TObject);
begin
{ 调用Memo.PasteFromClipboard方法}
Memo.PasteFromClipboard;
end;
【Edit | Word Wrap】
procedure TMainForm.EditWordWrapClick(Sender: TObject);
begin
{ 设置Memo.WordWrap属性来实现自动换行功能。}
Memo.WordWrap := not Memo.WordWrap;
EditWordWrap.Checked := Memo.WordWrap;
if Memo.WordWrap then
Memo.ScrollBars := ssVertical
else
Memo.ScrollBars := ssBoth;
end;
现在是等待已久的时刻
在为菜单项目建立了事件处理程序后,准备 运行程序。点击Run按钮,程序就编译并运行。如果出现了编译错误,请仔细比较上面的代码进行修改,也许会进行多次修改处理,最终使它能成功运行。
当程序运行时,会发现程序并不是非常精美,大部分像Windows Notepad。尽管在完成前有一些东西要加上去,还是有了相当好的开始。下图显示了正在运行的ScratchPad程序。
以上代码均在Delphi7中测试通过,本节示例代码下载:ScratchPad(菜单设计器之二).rar