Notification is called during the destructor - see TComponent.Destroy.
You should check for nil, and in your destructor after a .Free assign nil to the local
object variable if it is being referenced in Notification.
Myles.
-----Original Message-----
From: Chris Crowe [SMTP:[EMAIL PROTECTED]]
Sent: Thursday, May 27, 1999 8:02 AM
To: Multiple recipients of list Delphi
Subject: [DUG]: Very Intermitent Access Violations during Notification message.
HI,
I have a set of controls which just allow you to add a label to the main edit
control by using a class I wrote called TAdrockWhenFocused. When the control gets the
input focus, it changes the background color of itself, and it sets the label's font
to bold (by Default). Very simple.
I have an install of an application which is on a large number of computers, but on a
couple of computers which I have never seen, when the application is terminated it
stops with an access violation.
I am told it does it all the time on these two computers.
The message from the AV states this:
Exception EAccessViolation in module CALLCENTRAL.EXE at 0016751b.
Access Violation at address 0056751b in module 'CALLCENTRAL.EXE'. Read of address
00f40010
Now I used the Delphi Debugger to goto 0056751b and I get this in the CPU window (I
wish you could copy and paste from there)
push ebx
push esi
push edi
mov ebx, ecx
mov esi, edx
mov edi, eax
mov ecx, ebx
mov edx, esi
mov eax, edi
Call TControl.Notification
bmp bl,$01
jnz TAdrockCustomCheckBox.Notification + $3d
mov eax, [edi+$00000204]
cmp dword ptr [eax+$28],$00 <------- Point of AV
jz TAdrockCustomCheckBox.Notification + $3d
mov eax, [edi+$00000204]
cmp esi, [eax+$28]
jnz TAdrockCustomCheckBox.Notification + $3d
xor edx, edx
mov eax, [edi+$00000204]
Call TAdrockWhenFocused.SetFocusLabel
pop edi
pop esi
pop ebx
ret
Which is the assembler for the code below.
procedure TAdrockCustomCheckBox.Notification(AComponent: TComponent; Operation:
TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (WhenFocused.FocusLabel <> nil) and
(AComponent = WhenFocused.FocusLabel) then
WhenFocused.FocusLabel := nil;
end;
Can anyone see where this problem might arise from?. I am thinking maybe the
WhenFocused class is nil at the point when the WhenFocused.FocusLabel code is being
checked, as it looks to be there from the ASM above.
Does the Notification code get called duration a destructor?, if so that could point
to the fact that the WhenFocused is nil, and cause an AV. But if that was the case,
you would expect it to be causing AV's all the time.
The WhenFocused class is actually configured as a property in the particular edit
control, so it is declared as
fWhenFocused : TAdrockWhenFocused
Property WhenFocused : TAdrockWhenFocused
Read fWhenFocused
Write fWhenFocused;
Constructor TAdrockCustomCheckBox.Create(Aowner : TComponent);
begin
Inherited Create(AOwner);
{$ifdef WIN32}
ControlStyle := ControlStyle + [csReplicatable];
{$endif}
fWhenFocused := TAdrockWhenFocused.Create(Self);
Width := 133;
end;
Destructor TAdrockCustomCheckBox.Destroy;
begin
fWhenFocused.Free;
Inherited Destroy;
end;
So maybe I need to change the code to this, which checks for the WhenFocused class
being nil.
procedure TAdrockCustomCheckBox.Notification(AComponent: TComponent; Operation:
TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (WhenFocused <> nil) and (WhenFocused.FocusLabel <>
nil) and
(AComponent = WhenFocused.FocusLabel) then
WhenFocused.FocusLabel := nil;
end;
Should I change the destroy class to force the label to be NIL, when the WhenFocused
class is being freed?
Destructor TAdrockCustomCheckBox.Destroy;
begin
fWhenFocused.FocusLabel := NIL; { Do I need to do this? }
fWhenFocused.Free;
Inherited Destroy;
end;
This problem with the TAdrockCustomCheckBox has never come up for me
application/ms-tnef