I am posting my Stack Overflow problem on StackOverflow.com. Irony at its best!
Anyways. I am calling this procedure on my SkypeReply event handler, which gets fired a lot:
Procedure OnCategoryRename;
Var
CategoryID : Integer;
sCtgName : String;
Begin
if (AnsiContainsStr(pCommand.Reply,'GROUP')) and (AnsiContainsStr(pCommand.Reply,'DISPLAYNAME')) then
begin
sCtgName := pCommand.Reply;
Delete(sCtgName,1,Pos('GROUP',sCtgName)+5);
CategoryID := StrToInt(Trim(LeftStr(sCtgName,Pos(' ',sCtgName))));
sCtgName := GetCategoryByID(CategoryID).DisplayName; // Removing THIS line does not produce a Stack Overflow!
ShowMessage(sCtgName);
end;
The idea of this is to loop thru my list of Skype Groups, to see what group has been renamed. AFAIK thats of no importance, as my S.O has been traced to appear here
Function GetCategoryByID(ID : Integer):IGroup;
Var
I : Integer;
Category : IGroup;
Begin
// Make the default result nil
Result := nil;
// Loop thru the CUSTOM CATEGORIES of the ONLY SKYPE CONTROL used in this project
// (which 100% positive IS attached ;) )
for I := 1 to frmMain.Skype.CustomGroups.Count do
Begin
// The Category Variable
Category := frmMain.Skype.CustomGroups.Item[I];
// If the current category ID returned by the loop matches the passed ID
if Category.Id = ID then
begin
// Return the Category as Result (IGroup)
Result := Category;
// Exit the function.
Exit;
end;
End;
End;
When I set a breakpoint at Result := Category; and Single Step thru, those 2 lines get executed over and over, right after each other!
And when I comment out the sCtgName := GetCategoryByID(CategoryID).DisplayName;
in the first code snippet, there is no Overflow, the message gets shown that one time it is supposed to. However, the GetCategoryByID
is a function I wrote, and I wrote one similar, too, which works just fine (GetCategoryByName), so I don't get why it decided to repeat the
// Return the Category as Result (IGroup)
Result := Category;
// Exit the function.
Exit;
over and over again.
EDIT: Here is how you can reproduce it: https://gist.github.com/813389
EDIT: Here is my CallStack, as requested:
Edit2: More info:
OnCategoryRename
sounds like an event to me. If there are something inGetCategoryByID
that triggersOnCategoryRename
you will get a recursion that never ends. You can see if this is happening by looking at the call-stack when stepping through your code. – ArtimaExit
are you using (I had a client that hadprocedure Exit;
in a truckload of units). – GreenhouseResult := Category
and when it reaches there press F7 and see where you go. Also make use of the Call Stack. Do you know what the call stack is? – AdrellShowMessage
inOnCategoryRename
? – ArtimaResult := Category
recursion. – AdrellfrmMain.Skype.CustomGroups.Item[I]
? Can calling it cause theSkypeReply
handler to fire? Or can casting it toCategory
's type causeSkypeReply
to fire? I can see that you are checking whetherpCommand.Reply
contains'GROUP'
, but I don't see the latter being removed from the former (though maybe it's done in the handler's code, if it's needed anyway). If for some reason the handler gets fired before the proc is done (or because the proc causes the handler to fire), is it possible that by that timepCommand.Reply
still contains'GROUP'
in it? – Tyrelltyrian