So,
ich habs mal einkreisen können.
Hier kommt das CPU-Fenster:
Delphi-Quellcode:
procedure TJvHookInfos.WindowProc(
var Msg: TMessage);
var
TmpHookInfo: PJvHookInfo;
{ FStack[Index] is used to travel through the hook infos;
FStack[Index] points to the current hook info (and might be nil)
Note that the address of FStack may change due to ReallocMem calls in
IncDepth; thus we can't assign FStack[Index] to a local var.
}
Index: Integer;
begin
{ An object can now report for every possible message that he has
handled that message, thus preventing the original control from
handling the message; this is probably not a good idea in the case
of WM_DESTROY, WM_CLOSE etc. But that's the users responsibility,
I think }
Msg.Result := 0;
IncDepth;
// (rb) Don't know what the performance impact of a try..finally is.
try
{ The even members in the stack are hoBeforeMsg hooks }
Index := 2 * (FStackCount - 1);
FStack[
Index] := FFirst[hoBeforeMsg];
while Assigned(FStack[
Index])
do
begin
{ We retrieve the next hook info *before* the call to Hook(), because,
see (I) }
TmpHookInfo := FStack[
Index];
FStack[
Index] := FStack[
Index].Next;
if TmpHookInfo.Hook(Msg)
or FControlDestroyed
then
Exit;
{ FStack[Index] may now be changed because of register/unregister calls
inside HookInfo.Hook(Msg). }
end;
{ Maybe only exit here (before the original control handles the message),
thus enabling all hooks to respond to the message? Otherwise if you
have 2 components of the same class, that hook a control, then only 1 will
get the message }
if TMethod(FOldWndProc).Data <>
nil then //<-- DA DA DA!!! Er wars!
FOldWndProc(Msg)
else
if TMethod(FOldWndProc).Code <>
nil then
Msg.Result := CallWindowProc(TMethod(FOldWndProc).Code,
Handle, Msg.Msg,
Msg.WParam, Msg.LParam);
if FControlDestroyed
then
Exit;
{ The odd members in the list are hoAftermsg hooks }
Index := 2 * FStackCount - 1;
FStack[
Index] := FFirst[hoAfterMsg];
while Assigned(FStack[
Index])
do
begin
TmpHookInfo := FStack[
Index];
FStack[
Index] := FStack[
Index].Next;
if TmpHookInfo.Hook(Msg)
or FControlDestroyed
then
Exit;
end;
finally
DecDepth;
if (Control =
nil)
and (Msg.Msg = WM_DESTROY)
then
// Handle is being destroyed: remove all hooks on this window
ControlDestroyed;
end;
{ (I)
HookInfos before HookInfos after
call to Hook() call to Hook()
|----------| If FStack[Index] point to A |----------|
-->| hook A | (arrow) and hook A deletes itself | hook B |<--
|----------| then after the call to Hook, |----------|
| hook B | FStack[Index] points to B. If we | hook C |
|----------| then call Next, FStack[Index] |----------|
| hook C | points to C (should be B)
|----------|
}
end;
[edit] Andere Frage: Warum taucht das Fenster auf? Was muss passieren damit das Fenster angezeigt wird?
Achso, wenn ich das Fenster schließe und wieder auf F9 drücke, kann ich das Programm trotzdem starten. [/edit]