我在我的項目中使用了PNGImage庫,其中整個GUI由.png圖片組成,我在運行時加載到TImage。出於某些目的,我必須動態地創建大量相互類似的組件組。每個組由一些TImages組成,並有一個按鈕,讓用戶可以進入另一個頁面,瞭解更多有關點擊項目的詳細信息。程序結束時出現PNGImage「訪問衝突」錯誤
我使用的代碼:在(1)
發生
procedure TMain_Frame.selection_click(Sender: TObject);
var id: string;
begin
id := StringReplace(TLabel(sender).Name, 'label_item_select_', '', [rfReplaceAll]);
hide_created_components; // It does Free all components
show_details(id);
end; // (1)
Access violation
錯誤。奇怪的是,它發生的是完全隨機的:錯誤可能發生在第一次點擊或可能不會發生10次點擊。如果沒有錯誤發生,F8會讓我在PNGImage庫裏面完成一些工作。然而,當發生錯誤時,F7/8會立即拋出它,而不會做它必須做的事情。只有當我從dynamicaly創建的對象到靜態時,這個問題纔會發生。
CPU窗口顯示錯誤在此ASM代碼發生:
movzx ecx, [edi]
ECX值755A2E09,EDI是00000000
是否正確.Free
所有動態創建的組件?或者應該用.Destroy
代替?爲什麼PNGImage在程序end;
中進入內部?
演示:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, pngimage, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
procedure selection_click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure create_label;
var Button: TLabel;
begin
Button := TLabel.Create(Form1);
with Button do
begin
Name := 'dynamic_label_1';
Parent := Form1;
Autosize := false;
Left := 100;
Top := 100;
Width := 150;
Height := 20;
Caption := 'Dynamic Label: Click Me';
BringToFront;
Cursor := crHandPoint;
end;
Button.OnClick := Form1.selection_click;
end;
procedure hide_dyn_label(L: TLabel; mode: boolean);
begin
if mode then
begin
L.Free;
Form1.Image1.Picture.LoadFromFile(PAnsiChar('button_close.png'));
Form1.Image1.Visible := true;
end
else
create_label;
end;
procedure TForm1.selection_click(Sender: TObject);
var id: string;
begin
id := StringReplace(TLabel(Sender).Name, 'dynamic_label_', '', [rfReplaceAll]);
Form1.Button1.Visible := true;
hide_dyn_label(Form1.FindComponent('dynamic_label_1') as TLabel, true);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
create_label;
Form1.Image1.Visible := false;
Form1.Button1.Visible := false;
end;
end.
調用'免費'是好的。你的代碼有缺陷,但我們不能告訴你它是什麼。請製作一個MCVE。 –
演示代碼(您的MCVE)應該在*問題本身中,而不是在某個場外位置。 –
@ moskito-x nope,我只在項目中使用1個表單 – lolbas