OpenDialog不显示在Delphi

OpenDialog不显示在Delphi

本文介绍了OpenDialog不显示在Delphi MultiThreaded应用程序中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

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

i tried to use the openDialog in new thread but it made so strange behavior ..

如果我将if opendialog.execute放在这样的create构造函数中:

if i put the if opendialog.execute then in the create constructor like this :

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;

opendialog正常打开,但是当我将其放入线程的执行生产器中时,它根本没有打开!!

the opendialog open normally but when i put it in the execute producer of the thread it didn't open at all !!

我是线程的初学者,所以谁能为我解释发生了什么事?

i'm so beginner in threads so can any one explain for me what happened ?

谢谢.

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.

推荐答案

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

It works when you call it in the constructor because the constructor runs in the context of the calling thread (ie the main thread), whereas Execute() runs in the context of the worker thread. The VCL is not thread-safe, and UI components in particular rarely if ever work correctly outside of the main thread. If you want to display an open dialog in a thread, then have your TThread.Execute() method either:

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

1) call TThread.Synchronize() to access the TOpenDialog within the context of the main thread.

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

2) call the Win32 API GetOpenFileName() function directly instead. API dialogs can be safely used in threads when used properly.

这篇关于OpenDialog不显示在Delphi MultiThreaded应用程序中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 19:26