窗体上只有一个按钮和一个Image控件,实现窗体装载时图象控件显示图a.jpg,点按钮后运行一个线程,该线程只是简单地把图象改为b.jpg。但是出错,请高手指点....在Delphi里运行时,按下按钮后提示出错:
Project D:\.........\MuTh.exe faulted with message: 'access violation at 0x00463d70: read of address 0x000002f8'. Process Stopped. Use Step or Run to continue.
错误指向代码(下面代码清单是的倒数第3行那):Image1.Picture.LoadFromFile('b.jpg');
在Windows中直接运行生成的EXE,按下按钮后提示出错:
Muth.exe遇到问题需要关闭。(Windows常见的“发送错误报告”的错误提示)
代码如下:
-----------------------------
unit main;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, jpeg, ExtCtrls;type
  TForm1 = class(TForm)
    Image1: TImage;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);    
    procedure Button1Click(Sender: TObject);
    procedure proPic();
  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;
implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
begin
  Image1.Picture.LoadFromFile('a.jpg');
end;procedure TForm1.Button1Click(Sender: TObject);
var
  ID: THandle;
begin
  CreateThread(nil,0,@TForm1.proPic,nil,0,ID);
end;procedure TForm1.proPic();
begin
  Image1.Picture.LoadFromFile('b.jpg');
end;end.

解决方案 »

  1.   

    proPic有一个隐含的参数:this:TForm1
      

  2.   

    提醒:多线程中操作VCL控件时,注意使用Synchronize同步过程.
      

  3.   


    procedure proPic(); 
    begin 
      Form1.Image1.Picture.LoadFromFile('b.jpg'); 
    end; procedure TForm1.Button1Click(Sender: TObject); 
    var 
      ID: THandle; 
    begin 
      CreateThread(nil,0,@proPic,nil,0,ID); 
    end; 
    不过不推荐用CreateThread
      

  4.   

    另外这样也可以public 
        { Public declarations }
      class procedure proPic1(); class procedure proPic1(); 
    begin 
      Form1.Image1.Picture.LoadFromFile('b.jpg'); 
    end; procedure TForm1.Button1Click(Sender: TObject); 
    var 
      ID: THandle; 
    begin 
      CreateThread(nil,0,@TForm1.proPic1,nil,0,ID); 
    end; @TForm1.proPic 编译后是@TForm1.proPic(Form1)
    @TForm1.proPic1 编译后是 @TForm1.proPic1
      

  5.   

    谢谢“sanguomi”的指点,用第一种方法改后可在通过。
    再将线程里加了循环,让两张图动态切换,循环运行到一定次数时也会类似第一个问题的错误,而且从执行到出错的循环次数不同。procedure proPic();
    begin
      while isThreadRun do  begin
        if pica then begin
          Form1.Image1.Picture.LoadFromFile('b.jpg');
          pica:=false;
        end else begin
          Form1.Image1.Picture.LoadFromFile('a.jpg');
          pica:=true;
        end;
        sleep(40);
        couThread:=couThread+1;
        Form1.Label1.Caption:='循环执行了:'+IntToStr(couThread)+'次';
      end;
    end;
      

  6.   

    改用TThread后,线程units里的代码是:
    unit ThrdU;interfaceuses Classes,SysUtils,MainForm;type
      TTestThread = class(TThread)
      private
        { Private declarations }
      protected
        { Public declarations }
        procedure Execute;override;
        procedure MyAction;
      end;
    var
      isDisA: boolean;implementationprocedure TTestThread.Execute;
    var
      i:integer;
    begin
      isDisA:=true;
      FreeOnTerminate:=True;
      for i:=1 to 100 do begin
        if Terminated then Break;
        Synchronize(MyAction);
        sleep(100);
      end;
    end;procedure TTestThread.MyAction;
    begin
      if isDisA then begin
        Form1.Image1.Picture.LoadFromFile('b.jpg');
        isDisA:=false;
      end else begin
        Form1.Image1.Picture.LoadFromFile('a.jpg');
        isDisA:=true;
      end;
    end;end.