OpenDialog没有出现在Delphi MultiThreaded应用程序中

Rai*_*ain 2 delphi multithreading delphi-2009 fileopendialog topendialog

我试图在新线程中使用openDialog,但它做了如此奇怪的行为..

如果我把if opendialog.execute然后放在create构造函数中,如下所示:

constructor TChatMemberThread.Create(Name: string);
begin
  inherited Create(True);
  FName := Name;
  FreeOnTerminate := True;
  Opendialog := TOpenDialog.create(nil);
  if opendialog.execute then
    for 0 to opendialog.filescount do
      somecodeishere
    end;
end;
Run Code Online (Sandbox Code Playgroud)

opendialog正常打开但是当我把它放在线程的执行生成器中时它根本没有打开!!

我是线程的初学者,所以任何人都可以向我解释发生了什么?

提前致谢 .

[编辑]

unit Unit1;

interface

uses
  Classes,Dialogs,ComCtrls,SysUtils,DCPcrypt2, DCPmd5;

type
  TOpenThread = class(TThread)
  private
    { Private declarations }
    OpenDlG : TOpenDialog;
    LI : TListItem;
    Procedure Openit;
    Function MD5it(Const filename : string ):String;
  protected
    procedure Execute; override;
  Public
    Constructor Create;
    Destructor Destroy;Override;
  end;

implementation
uses Main;

{ TOpenThread }

Constructor TOpenThread.Create;
begin
 inherited Create(True);
 opendlg := Topendialog.Create(nil);
 opendlg.Filter := 'All Files | *.*';
 openDlg.Options := [OfAllowMultiSelect];
 openDlg.InitialDir := GetCurrentDir;
end;

Destructor TOpenThread.Destroy;
begin
  OpenDlg.Free;
  inherited;
end;

Function TOpenThread.MD5it(Const filename : string ):String;
var
hash : TDCP_MD5 ;
Digest: array[0..15] of byte;
Source: TFileStream;
i: integer;
s: string;
begin
  Source:= nil;
    try
      Source:= TFileStream.Create(filename,fmOpenRead);  // open the file specified by Edit1
    except
      MessageDlg('Unable to open file',mtError,[mbOK],0);
    end;
    if Source <> nil then
    begin
      Hash:= TDCP_MD5.Create(nil);         // create the hash
      Hash.Init;                                   // initialize it
      Hash.UpdateStream(Source,Source.Size);       // hash the stream contents
      Hash.Final(Digest);                          // produce the digest
      Source.Free;
      s:= '';
      for i:= 0 to 15 do
        s:= s + IntToHex(Digest[i],2);
    Result := s;
    end;
    Hash.Free;
end;

Procedure TOpenThread.Openit;
var
I: Integer;
begin
 if opendlg.Execute then
 begin
   for I := 0 to openDlg.Files.Count - 1 do begin
      LI := Form1.LV1.Items.Add;
      LI.Caption := ExtractFileName(openDlg.Files[i]);
      LI.SubItems.Add(MD5it(openDlg.Files[i]));
      LI.SubItems.add(openDlg.Files[i]);
   end;
  //SB.Panels[0].Text := ' '+IntToStr(LV1.Items.Count)+' File(s)';
  OpenDlg.Free;
end;end;

procedure TOpenThread.Execute;
begin
  { Place thread code here }
  Synchronize(OpenIt);
end;

end.
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 7

它在构造函数中调用它时有效,因为构造函数在调用线程(即主线程)的上下文中运行,而Execute()在工作线程的上下文中运行.VCL不是线程安全的,特别是UI组件,如果在主线程之外正常工作,则很少.如果要在线程中显示打开的对话框,请使用以下TThread.Execute()方法:

1)调用TThread.Synchronize()访问TOpenDialog主线程的上下文.

2)GetOpenFileName()直接调用Win32 API 函数.正确使用时,可以在线程中安全地使用API​​对话框.

  • @Tattah - 在编辑中,只有'Execute'中的'Synchronize',所有代码都在主线程中运行.你可能会在主线程中显示对话框,MD5在线程中显示文件,然后同步列表视图. (2认同)