我试图在与服务器断开连接后关闭与客户端相关的所有表单
此操作将在服务器端。
我(在运行时为我所知)每个客户端的部分唯一标题,例如
表格标题1:
ServiceA - ClientABC
表格标题2:
ServiceB - ClientABC
我所知道的仅是- ClientABC
部分。
因此,当客户端ClientABC
与我的服务器断开连接时,我想关闭服务器端所有相关的已打开表单。
procedure TIdServer.ClientRemove(const AContext: TIdContext);
var
sTitle: string;
function CloseChildForm(Wnd: HWND; Param: LPARAM): BOOL; stdcall;
begin
if Pos(sTitle, _GetWindowTitle(Wnd)) <> 0 then
PostMessage(Wnd, WM_CLOSE, 0, 0);
Result := True;
end;
begin
sTitle := TMyContext(AContext).Uniquename {ClientABC}
if Assigned(FListView) then begin
TThread.Queue(nil,
procedure
var
i: Integer;
begin
EnumWindows(@CloseChildForm, 0);
.......
end;
end
);
end;
end;
我的问题是sTitle
函数中的字符串CloseChildForm
始终为空。
我在ClientRemove
程序
IdServerDisconnect
procedure TIdServer.IdServerDisconnect(AContext: TIdContext);
begin
TMyContext(AContext).Queue.Clear;
........
ClientRemove(AContext);
end;
有谁能告诉我有什么不对吗?
答案 0 :(得分:4)
这里有很多不妥之处:
EnumWindows
的RTL声明使用无类型指针作为回调参数。 TThread.Queue
进行异步执行意味着可以在调用EnumWindows
之前完成封闭堆栈帧。 如果我遇到这个问题,我会使用Screen.Forms[]
来解决它。像这样:
for i := Screen.FormCount-1 downto 0 do
if CaptionMatches(Screen.Forms[i]) then
Screen.Forms[i].Close;
这只是一个大纲。我相信你能理解这个概念。关键是不要使用EnumWindows
而是使用VCL自己的机制来枚举表单。