ヤマダです。
宜しくお願いします。
D7 + windows vistaです。
簡単に書きますがあるスレッドオブジェクトから
フォームオブジェクトの(fileList:TStringList)にアクセスします。
*Synchronizeメソッドで
threadCreate(false)する直前では、frmMain.fileList.count = 8です。
しかしなぜかスレッドオブジェクトからアクセスすると
frmMain.stringlist.count = 0になっています。
ただstringlist.clearをするようなコードは、存在していません。
なぜなのでしょうか?
宜しくお願いいたします。
再現しません。
# Delphi7+XP
どういうコードを書いているのでしょうか。
# 再現しないサンプル
unit uMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TMyThread=class(TThread)
protected
procedure Execute; override;
public
procedure DoRefresh;
end;
TForm1 = class(TForm)
AddButton: TButton;
StartButton: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure AddButtonClick(Sender: TObject);
procedure StartButtonClick(Sender: TObject);
private
{ Private 宣言 }
MyThread: TMyThread;
public
{ Public 宣言 }
fileList: TStringList;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
fileList := TStringList.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if Assigned(MyThread) then
begin
MyThread.Terminate;
MyThread.Free;
end;
fileList.Free;
end;
procedure TForm1.AddButtonClick(Sender: TObject);
begin
fileList.Add('Flie' + IntToStr(fileList.Count));
end;
procedure TForm1.StartButtonClick(Sender: TObject);
begin
MyThread := TMyThread.Create(true);
MyThread.Resume;
end;
procedure TMyThread.Execute;
begin
while not Self.Terminated do
begin
Sleep(1000);
Synchronize(DoRefresh);
end;
end;
procedure TMyThread.DoRefresh;
var
text: String;
begin
text := DateTimeToStr(Now);
text := text + ' ' + IntToStr(Form1.fileList.Count);
Form1.Label1.Caption := text;
end;
end.
ヤマダです。
にしのさん、ご返信ありがとうございます。
下記にソースを抜粋して添付いたします。
抜粋の仕方が悪かった場合は、お手数ですが
ツッコミお願い致します。
unit MAIN;
TMainForm = class(TForm)
miImportClick(Sender: TObject);
procedure miImportClick(Sender: TObject);
private
{ Private declarations }
FThreadImport:TImportFileThread;
//対象ディレクトリのjpgファイルを取得
procedure getImportList(var sList:TStringList;dir:String);
//Import対象のファイル名でtreeNodeを作成しtreeviewに登録する。
procedure addNodeforPic();
procedure importDone(sender:TObject);
public
{ Public declarations }
fileList:TStringList;
end;
procedure TMainForm.miImportClick(Sender: TObject);
begin
AppInfo.ImportDir := BrowseForFolder('ディレクトリ選択','',true);
if AppInfo.ImportDir <> '' then begin
self.getImportList(fileList,appInfo.ImportDir);
self.addNodeforPic;
ShowMessage(IntToStr(self.fileList.Count)); //ここで8を出力
self.FThreadImport := TImportFileThread.Create(false);
self.FThreadImport.Priority := tpLowest;
self.FThreadImport.OnTerminate := self.importDone;
self.FThreadImport.FreeOnTerminate := true;
self.StatusBar.Panels[0].Text := 'Import中です・・・・';
end;
end;
//対象ディレクトリのjpgファイルを取得
procedure TMainForm.getImportList(var sList: TStringList;dir:String);
var
rec:TSearchRec;
begin
self.fileList.Clear;
if (FindFirst(dir + '\*.jpg', faAnyFile, Rec) = 0) then begin
repeat
if ( (Rec.Name <> '.') and (Rec.Name <> '..')
and ((rec.Attr and faDirectory) = 0))
then fileList.Add(rec.Name);
until (FindNext(Rec) <> 0);
end;
end;
//Import対象のファイル名でtreeNodeを作成しtreeviewに登録する。
procedure TMainForm.addNodeforPic;
var
i:Integer;
Node:TTreeNode;
childNode:TTreeNode;
begin
Node := self.treeView.Selected;
repeat
if Node.Parent <> nil then Node := Node.Parent;
until (Node.Parent = nil);
for i := 0 to self.sList.Count - 1 do begin
childNode := Self.treeView.Items.AddChild(Node.getFirstChild,Self.fileList.Strings[i]);
childNode.ImageIndex := 3;
end;
self.treeView.SaveToFile(AppInfo.workSpaceDir+'app.conf');
end;
procedure TMainForm.importDone(sender: TObject);
begin
self.StatusBar.Panels[0].Text := 'Import完了';
end;
***************************************************
unit UThreadImport;
interface
uses
Classes,UAppClass,Windows,Dialogs;
type
TImportFileThread = class(TThread)
private
{ Private declarations }
FSourceDir:TStringList;
FDistiDir:String;
protected
procedure SetDir();
procedure Execute; override;
end;
implementation
uses SysUtils,Main;
{ TImportFileThread }
procedure TImportFileThread.Execute;
var
i:Integer;
begin
{ Place thread code here }
self.Synchronize(self.SetDir);
end;
procedure TImportFileThread.SetDir;
begin
ShowMessage(MainForm.fileList); //ここではなぜか0
end;
以上 宜しくお願いします。
お世話になっております。
ヤマダです。
その後も調査し続けた結果どうやらThreadが関係していなことが
わかりました。
ShowMessage(InTToStr(self.sList.count)); //こちらだと8
ShowMessage(InTToStr(MainForm.sList.count)); //こちらだと0
self(:TMainForm)経由とMainForm変数(:TMainForm)経由で
結果が変わっていたみたいです。
何かものすごい勘違いをしているのかもしれません。
いったんこれで解決とさせていただきます。
にしの様、検証までしていただいたのに申し訳ございませんでした。
以上 宜しくお願いいたします。
procedure TMainForm.miImportClick(Sender: TObject);
begin
AppInfo.ImportDir := BrowseForFolder('ディレクトリ選択','',true);
if AppInfo.ImportDir <> '' then begin
self.getImportList(fileList,appInfo.ImportDir);
self.addNodeforPic;
ShowMessage(IntToStr(self.fileList.Count)); //ここで8を出力
ShowMessage(InTToStr(MainForm.sList.count)); //こちらだと0
self.FThreadImport := TImportFileThread.Create(false);
self.FThreadImport.Priority := tpLowest;
self.FThreadImport.OnTerminate := self.importDone;
self.FThreadImport.FreeOnTerminate := true;
self.StatusBar.Panels[0].Text := 'Import中です・・・・';
end;
end;
ShowMessage(InTToStr(self.sList.count));
ShowMessage(InTToStr(MainForm.sList.count));
解決!です!
編集 削除