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

Reply via email to