I'm working on an IRC client. I've hit a majors snag which, up until not I've been able to work around. I'll show code below. What's I'm having a problem with is creating MDI child windows within the event handlers of idIRC.
For example, if I want to create a new channel form (FrmChannel), I can accomplish this easily by calling it's create procedure when I catch the '/join' command.
However, if I want to do it the right way, and wait until I've actually joined the channel, and receive confirmation of this from the server (by handling it in the onjoin event handler) then my call to my form creation procedure causes the application to hang.
The same goes for status windows. For example, if I put my status window creation procedure call on a TButton's onclick event, fine. Child form created. However, if I try the same thing when I actually receive a private message, by checking the event handler... Application hangs, no exception, and no MDI Child.
Here's the relevant code (for the sake of solving this I'll deal with the query window only).
First, the actual MDI Child creation goes like this. I have a TComponentList in here to manage a list of this class of form (in case you're wondering). There are some other things in here that keep track of the form as well, though commenting them out doesn't prevent the hang (I've tried).
procedure TFrmMain.NewQuery(const Server, MsgFrom: String);
var
Child: TFrmMessage;
TN: TTreeNode;
begin
///
/// Create form, set some data so we can reference it later.
///
///
Child := TFrmMessage.Create(Application);
// QueryManager.Add(Child); //TComponent List -- Used to find the Form Later On
with Child do
begin
MyServer := Server; {What server this PM window is on}
QueryWith := MsgFrom; {nickaname of the other person}
Caption := MsgFrom; {Asthetic}
end;
Child.Echo('*** Conversation with ' + MsgFrom); //Herro World
///
/// The following code is working.
/// I'm pretty sure it's not causing the hangs.
///
TN := GetNodeByText(ChanServTree, Server, True); {Find our parent node}
with ChanServTree.Items.AddChild(TN, MsgFrom) do
begin
Selected := True;
Tag := 2; {TYPE OF QUERY}
Data := Pointer(Integer(Child)); //Pointer to Form we created
end;
end;
Here's the event handler for my IRC component:
procedure TFrmMain.IRCPrivateMessage(ASender: TIdContext; const ANicknameFrom,
AHost, ANicknameTo, AMessage: string);
var
CheckVr: String;
aThread: TNQThread;
begin
//DEBUG:
(StatusManager[0] as TFrmStatus).Echo('From: ' + ANickNameFrom + 'AMESSAGE: ' + '''' +AMessage + '''');
///
/// Handle Drone Version Requests!
/// This is REQUIRED on servers like irc.blessed.net - or they won't let you join
/// channels! - It's part of the Registration proccess
///
{The Drones on some server's don't follow specifications, so we need to search
hard for their presence}
CheckVr := AMessage;
StringReplace(CheckVr,' ','',[rfReplaceAll, rfIgnoreCase]);
StringReplace(CheckVr,#1,'',[rfReplaceAll, rfIgnoreCase]);
(StatusManager[0] as TFrmStatus).Echo('Message was: ' + '''' + CheckVr + '''');
if Trim(CheckVr) = 'VERSION' then
begin
IRC.CTCPReply(ANickNameFrom,'VERSION','mIRC v6.01 Khaled Mardam-Bey');
(StatusManager[0] as TFrmStatus).Echo('*** Sent Version Reply to ' + ANickNameFrom);
exit; {Because if we don't, this could mess things up}
end;
///
/// The Following code sends the PM to the appropriate window.
/// If that window does not exist, we will create one first.
///
if Pos('#',Amessage) = 1 then
begin
//Handled Elsewhere
end else {is PM}
begin
if FindQueryFrm(ANickNameTo,IRC.Host) = nil then
begin
NewQuery(IRC.Host, ANickNameFrom);
exit;
end;
end;
// FindChannelFrm(ANickNameTo,IRC.Host).ChannelMessage(ANicknameFrom, AMessage);
end;
I've tried commenting out various parts of the code to try to track down the cause of the hanging. The hang is caused by the Child := TFrmMessage.Create(Application); call specifically. What gives?
I've tried implementing threads to see if that might be an issue. If that's what you're thinking the problem is, I'll need help with my threading because apparently though the code is compiling, I'm still calling something wrong (because even my threaded version hangs).
Thanks in advance.