正如其他人所说,您显示的代码只有这么多可能出错的地方:
1)TMenuItem.Tag
可能包含错误的值。
2)TempResultFile
可能没有分配一个有效的TEdit
指针。不管其他人怎么说,保持变量未初始化并不能保证会发生访问冲突,尽管它很可能发生。还有一种可能性是,如果TEdit
没有正确创建或已被释放,则分配的指针可能为 nil。如果您尝试使用它,那将导致 AV。
3)SaveDialog1.Execute()
可能返回 False。如果您取消对话框,就会发生这种情况,但如果对话框有内部错误,也会发生这种情况。在某些情况下,您可以使用CommDlgExtendedError()
来检查该情况。
4)SaveDialog1.FileName
为空,如果SaveDialog1.Execute()
返回 true,则不会发生这种情况,但是如果您使用的是相当现代的 Delphi 版本,在 Windows Vista 或更高版本上运行您的应用程序,并选择非文件系统文件,则可能会发生这种情况。
在调试期间,请确保您正在检查所有这些条件,例如:
var
Item: TMenuItem;
TempResultFile : TEdit;
S: String;
begin
Item := Sender as TMenuItem;
case Item.Tag of
1: TempResultFile := ResultTFile1;
2: TempResultFile := ResultTFile2;
3: TempResultFile := ResultTFile3;
else
raise Exception.CreateFmt('%s.Tag (%d) is not an expected value!', [Item.Name, Item.Tag]);
end;
if TempResultFile = nil then
raise Exception.Create('TempResultFile is nil!');
if not SaveDialog1.Execute then
raise Exception.CreateFmt('SaveDialog1.Execute returned false! Possible CommDlg error? (%d)', [CommDlgExtendedError()]);
S := SaveDialog1.FileName;
if S = '' then
raise Exception.Create('SaveDialog1.FileName is empty!');
TempResultFile.Text := S;
end;
作为使用 的替代方法TMenuItem.Tag
,该TPopupMenu.PopupComponent
属性将告诉您哪个 Button 显示了 PopupMenu。您可以将TButton.Tag
属性设置为指向TEdit
与该按钮对应的组件,然后您不必再使用该TMenuItem.Tag
属性来寻找TEdit
组件,例如:
procedure TForm1.FormCreate(Sender: TObject);
begin
ResultTButton1.Tag := NativeInt(ResultTFile1);
ResultTButton2.Tag := NativeInt(ResultTFile2);
ResultTButton3.Tag := NativeInt(ResultTFile3);
end;
procedure TForm1.MenuItemClick(Sender: TObject);
var
ResultTButton : TButton;
TempResultFile : TEdit;
begin
ResultTButton := PopupMenu.PopupComponent as TButton;
TempResultFile := TEdit(ResultTButton.Tag);
if TempResultFile <> nil then begin
if SaveDialog1.Execute then
TempResultFile.Text := SaveDialog1.FileName;
end;
end;