Я хотел бы добавить корни в VirtualTreeView http://www.delphi-gems.com/index.php/controls/virtual-treeview с резьбой, как это:VirtualTreeView добавить корни Нити
function AddRoot (p : TForm1) : Integer; stdcall;
begin
p.VirtualStringTree1.AddChild(NIL);
end;
var
Dummy : DWORD;
i : Integer;
begin
for i := 0 to 2000 do begin
CloseHandle(CreateThread(NIL,0, @ADDROOT, Self,0, Dummy));
end;
end;
Причина этого заключается в том, что я хочу, чтобы добавить все соединения с моего INDY сервера в TreeView , Indx's onexecute/onconnect get называют потоком. Поэтому, если одновременно появляются 3+ соединения, приложение вылетает из-за TreeView. То же самое, если клиент отключается, и я хочу удалить узел.
Я использую Delphi7 и Indy9
Любая идея, как исправить это?
EDIT:
procedure TForm1.IdTCPServer1Disconnect(AThread: TIdPeerThread);
begin
VirtualStringTree1.DeleteNode(PVirtualNode(Athread.Data)); // For Disconnection(s)
end;
procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
Athread.Data := TObject(VirtualStringTree1.AddChild(NIL)); // For Connection(s);
end;
Он отлично работает с ListView (по крайней мере, тем лучше).
EDIT: Вот мой полный код:
Сервер:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, IDSync, IdBaseComponent, IdComponent, IdTCPServer,
VirtualTrees;
type
TForm1 = class(TForm)
IdTCPServer1: TIdTCPServer;
VirtualStringTree1: TVirtualStringTree;
procedure FormShow(Sender: TObject);
procedure IdTCPServer1Connect(AThread: TIdPeerThread);
procedure IdTCPServer1Disconnect(AThread: TIdPeerThread);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TAddRemoveNodeSync = class(TIdSync)
protected
procedure DoSynchronize; override;
public
Node : PVirtualNode;
Adding : Boolean;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TAddRemoveNodeSync.DoSynchronize;
begin
if Adding then
Node := Form1.VirtualStringTree1.AddChild(nil)
else
Form1.VirtualStringTree1.DeleteNode(Node);
end;
procedure TForm1.FormShow(Sender: TObject);
begin
IDTCPServer1.DefaultPort := 8080;
IDTCPServer1.Active := TRUE;
end;
procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
with TAddRemoveNodeSync.Create do
try
Adding := True;
Synchronize;
AThread.Data := TObject(Node);
finally
Free;
end;
end;
procedure TForm1.IdTCPServer1Disconnect(AThread: TIdPeerThread);
begin
with TAddRemoveNodeSync.Create do
try
Adding := False;
Node := PVirtualNode(AThread.Data);
Synchronize;
finally
Free;
AThread.Data := nil;
end;
end;
end.
Client (Stresser):
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows,
Winsock;
Const
// Connection Vars
Port = 8080;
Host = '127.0.0.1';
StressDelay = 1; // Miliseconds!
var
WSA : TWSADATA;
MainSocket : TSocket;
Addr : TSockAddrIn;
begin
if WSAStartup($0202, WSA) <> 0 then exit;
Addr.sin_family := AF_INET;
Addr.sin_port := htons(Port);
Addr.sin_addr.S_addr := INET_ADDR(Host);
while true do begin
MainSocket := Socket(AF_INET, SOCK_STREAM, 0);
Connect(MainSocket, Addr, SizeOf(Addr));
CloseSocket(MainSocket); // Disconnect!
sleep (StressDelay);
end;
end.
Почему бы вам не запустить весь код пользовательского интерфейса в основном потоке? –
Причина Indy вызывает OnConnect в потоке. Не в главной теме. –
И что? Запустите код пользовательского интерфейса в основном потоке. Для достижения этого используйте механизм передачи сообщений. –