关于TreeView和线程结合出现的有关问题
关于TreeView和线程结合出现的问题
刚开始学习线程和TreeView。。尝试着做了以下测试,但是出现了我无法解决的问题,故请教之。
我尝试在模块左边用一个DBGridEh存放用户名列表,右侧用两个TreeView分别显示已拥有权限,全部权限,其中全部权限TreeView上能用红色标记已拥有权限。在选择到不同用户时刷新两个TreeView。而两个TreeView的生成我分别放在两个Thread中执行。
问题:在我快速滚动用户列表时导致Thread多次触发执行。弹出了错误提示:unable to insert an item
或者没有提示错误却出现TreeView显示的结果比预期结果要多了一些节点,估计是已经在产生TreeView时再度执行Thread导致的。
而如果我等待Thread完全执行完毕然后选择其他用户则不出现错误。
请问该如何解决?
***********************代码部分************************************
Thread1:
procedure right1.Execute;
var s: string; p: ^string;
mt, t, ct: TTreeNode;
ADO0, ADO1, ADO2, ADO3, ADO4, ADO5: TADOQuery;
begin
FreeOnTerminate := True;
//创建所需ADOQ控件
ADO0 := TADOQuery.Create(nil);
ADO0.Connection := Fmdm.ADOConnection1;
ADO1 := TADOQuery.Create(nil);
ADO1.Connection := Fmdm.ADOConnection1;
ADO2 := TADOQuery.Create(nil);
ADO2.Connection := Fmdm.ADOConnection1;
ADO3 := TADOQuery.Create(nil);
ADO3.Connection := Fmdm.ADOConnection1;
ADO4 := TADOQuery.Create(nil);
ADO4.Connection := Fmdm.ADOConnection1;
ADO3.Close;
ADO3.SQL.Clear;
s := 'select m_code from ts_group_right where kind= ' '1 ' ' and group_code= ' ' ' + group_code + ' ' ' ';
ADO3.SQL.Add(s);
ADO3.Open;
ADO4.Close;
ADO4.SQL.Clear;
s := 'select right_code from ts_group_right where kind= ' '2 ' ' and group_code= ' ' ' + group_code + ' ' ' ';
ADO4.SQL.Add(s);
ADO4.Open; // 取得已拥有权限
Fmrightset.TreeView1.Items.Clear; //删除树
Fmrightset.TreeView1.Items.BeginUpdate; //加快树创建速度
ADO0.Close;
ADO0.SQL.Clear;
s := 'select menu_name,menu_code,state from ts_right_m order by menu_code desc ';
ADO0.SQL.Add(s);
ADO0.Open;
ADO0.First;
while not ADO0.Eof do
begin
mt := Fmrightset.TreeView1.Items.AddFirst(nil,ADO0.Fields[0].AsString);
New(p); //分配内存
p^ := ADO0.Fields[1].AsString; //内存赋值
mt.Data := p; //写入data
ADO1.Close;
ADO1.SQL.Clear;
s := 'select m_name,m_code,state from ts_right_z where menu_code= ' ' ' + ADO0.Fields[1].AsString + ' ' ' order by m_code ';
ADO1.SQL.Add(s);
ADO1.Open; //对该节点查询子节点
ADO1.First;
while not ADO1.Eof do
begin
t := Fmrightset.TreeView1.Items.AddChild(mt,ADO1.Fields[0].AsString);
if ADO3.Locate( 'm_code ',ADO1.Fields[1].AsString,[]) = True then
t.StateIndex := 1;
//将编号转化为指针存入该节点data中
New(p);
p^ := ADO1.Fields[1].AsString;
t.Data := p;
刚开始学习线程和TreeView。。尝试着做了以下测试,但是出现了我无法解决的问题,故请教之。
我尝试在模块左边用一个DBGridEh存放用户名列表,右侧用两个TreeView分别显示已拥有权限,全部权限,其中全部权限TreeView上能用红色标记已拥有权限。在选择到不同用户时刷新两个TreeView。而两个TreeView的生成我分别放在两个Thread中执行。
问题:在我快速滚动用户列表时导致Thread多次触发执行。弹出了错误提示:unable to insert an item
或者没有提示错误却出现TreeView显示的结果比预期结果要多了一些节点,估计是已经在产生TreeView时再度执行Thread导致的。
而如果我等待Thread完全执行完毕然后选择其他用户则不出现错误。
请问该如何解决?
***********************代码部分************************************
Thread1:
procedure right1.Execute;
var s: string; p: ^string;
mt, t, ct: TTreeNode;
ADO0, ADO1, ADO2, ADO3, ADO4, ADO5: TADOQuery;
begin
FreeOnTerminate := True;
//创建所需ADOQ控件
ADO0 := TADOQuery.Create(nil);
ADO0.Connection := Fmdm.ADOConnection1;
ADO1 := TADOQuery.Create(nil);
ADO1.Connection := Fmdm.ADOConnection1;
ADO2 := TADOQuery.Create(nil);
ADO2.Connection := Fmdm.ADOConnection1;
ADO3 := TADOQuery.Create(nil);
ADO3.Connection := Fmdm.ADOConnection1;
ADO4 := TADOQuery.Create(nil);
ADO4.Connection := Fmdm.ADOConnection1;
ADO3.Close;
ADO3.SQL.Clear;
s := 'select m_code from ts_group_right where kind= ' '1 ' ' and group_code= ' ' ' + group_code + ' ' ' ';
ADO3.SQL.Add(s);
ADO3.Open;
ADO4.Close;
ADO4.SQL.Clear;
s := 'select right_code from ts_group_right where kind= ' '2 ' ' and group_code= ' ' ' + group_code + ' ' ' ';
ADO4.SQL.Add(s);
ADO4.Open; // 取得已拥有权限
Fmrightset.TreeView1.Items.Clear; //删除树
Fmrightset.TreeView1.Items.BeginUpdate; //加快树创建速度
ADO0.Close;
ADO0.SQL.Clear;
s := 'select menu_name,menu_code,state from ts_right_m order by menu_code desc ';
ADO0.SQL.Add(s);
ADO0.Open;
ADO0.First;
while not ADO0.Eof do
begin
mt := Fmrightset.TreeView1.Items.AddFirst(nil,ADO0.Fields[0].AsString);
New(p); //分配内存
p^ := ADO0.Fields[1].AsString; //内存赋值
mt.Data := p; //写入data
ADO1.Close;
ADO1.SQL.Clear;
s := 'select m_name,m_code,state from ts_right_z where menu_code= ' ' ' + ADO0.Fields[1].AsString + ' ' ' order by m_code ';
ADO1.SQL.Add(s);
ADO1.Open; //对该节点查询子节点
ADO1.First;
while not ADO1.Eof do
begin
t := Fmrightset.TreeView1.Items.AddChild(mt,ADO1.Fields[0].AsString);
if ADO3.Locate( 'm_code ',ADO1.Fields[1].AsString,[]) = True then
t.StateIndex := 1;
//将编号转化为指针存入该节点data中
New(p);
p^ := ADO1.Fields[1].AsString;
t.Data := p;