为什么在线程里使用输入框“InputBox”,Win98下不会出错,在win2000下会出错!(100分)

  • 主题发起人 主题发起人 paf
  • 开始时间 开始时间
P

paf

Unregistered / Unconfirmed
GUEST, unregistred user!
下面是一例子!
//在uses 里加入ShellAPI
uses ShellAPI;
//---------------------------------------
procedure ThRun;
//自定义函数
var
str: string;
begin
str := InputBox('请输入要运行的命令!', ' ', '');
//在Win98下不会出错,在Win2000下出错!
if str <> '' then
ShellExecute(form1.Handle, nil, pchar(str), nil, nil, SW_NORMAL);
//运行命令
end;

procedure TForm1.Button1Click(Sender: TObject);
var
thid: dword;
begin
begin
thread(nil, 0, @ThRun, nil, 0, thid);
//线程
end;

为什么在win98下可以通过,但在win2000下就会出错!
如果在自定义函数里加入的是“ShowMessage”也会出错,为什么啊!
 
VCL是非线程安全的,要使用TThread和Synchronize(),否则确实ShowMessage也会出错的。
 
我好多地要用到线程啊,如果每一个都要在TTHread 里用"Synchronize()" 那不是很烦!
有没有别的解决方法啊!
 
因为不管是你的 ShellExecute(form1.Handle...) 还是 ShowMessage 都是用到了
你的主窗口的句柄,就会和主线程发生冲突。
同意 zw84611,使用 TThread 以及其 Synchronize()
 
我好多地要用到线程啊,如果每一个都要在TTHread 里用"Synchronize()" 那不是很烦!
有没有别的解决方法啊!!!!!
win98下没事啊!
 
Win98下的内存管理没Win2000那么严格,看起来没事,但是是有隐患的。
 
写程序就不要怕麻烦嘛:)
其实只要你稍微封装一下,也不会很麻烦的:)
 
在 TTHread 里的"Synchronize()" 是怎得到主窗口句柄的啊?
可以说说怎样封装才方便啊!可以说说吗?
 
我举个例子:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, OleCtrls, SHDocVw;
type
TMainForm = class(TForm)
Button1: TButton;
WebBrowser1: TWebBrowser;
OpenDialog1: TOpenDialog;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure WebBrowser1DocumentComplete(Sender: TObject;
const pDisp: IDispatch;
var URL: OleVariant);
private
{ Private declarations }
public
{ Public declarations }
end;

TConvertThread=class(TThread)
private
Index: integer;
protected
procedure Execute;
override;
Procedure Convert;
Procedure ShowFinish;
end;

var
MainForm: TMainForm;
FinishEvent: Thandle;
TemList, FileNameList: TStringList;
CurFileName: string;
implementation
uses MSHTML;
{$R *.DFM}
procedure TConvertThread.Convert;
begin
with MainFormdo
begin
CurFileName := FileNameList.Strings[index];
WebBrowser1.Navigate(CurFileName);
end;
end;

procedure TConvertThread.ShowFinish;
begin
ShowMessage('Convert has finished.');
end;

procedure TConvertThread.Execute;
var
i: integer;
begin
for i:=1 to FileNameList.Countdo
begin
Index := i-1;
ReSetEvent(FinishEvent);
Synchronize(Convert);
WaitForSingleObject(FinishEvent,5000{INFINITE});
end;
Synchronize(ShowFinish);
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
FinishEvent := CreateEvent(nil,True,False,nil) ;
ReSetEvent(FinishEvent);
TemList := TStringList.Create;
FileNameList := TStringList.Create;
end;

procedure TMainForm.Button1Click(Sender: TObject);
var
ConvertThread: TConvertThread;
begin
WebBrowser1.Offline := true;
if OpenDialog1.Execute then
begin
FileNameList.Assign(OpenDialog1.Files);
ConvertThread := TConvertThread.Create(true);
ConvertThread.Resume;
end;
end;

procedure TMainForm.WebBrowser1DocumentComplete(Sender: TObject;
const pDisp: IDispatch;
var URL: OleVariant);
begin
TemList.Clear;
TemList.Add(IHtmlDocument2(WebBrowser1.Document).Body.OuterText);
TemList.SaveToFile(ExTractFileName(CurFileName)+'.txt');
SetEvent(FinishEvent);
end;

end.
 
我今天试了一下,在 TTHread 里的"Synchronize()"
使用“ShowMessage”也会出错啊!怎么办!
 
ShowMessage是application里的,换成messagebox看看。
 
不好意思,在 TTHread 里的"Synchronize()"
使用“ShowMessage”没有出错!是我自己搞错了!
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部