1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
|
{ $Id: lclclasses.pp 59201 2018-09-30 22:45:40Z maxim $}
{
*****************************************************************************
* lclclasses.pp *
* ------------- *
* *
* *
*****************************************************************************
*****************************************************************************
This file is part of the Lazarus Component Library (LCL)
See the file COPYING.modifiedLGPL.txt, included in this distribution,
for details about the license.
*****************************************************************************
Defines the base class for all LCL TComponents including controls.
}
unit LCLClasses;
{$mode objfpc}{$H+}
interface
uses
Classes, WSLCLClasses, WSReferences, LCLType, LCLProc;
type
// SysUtils.LongRec has unsigned Word for Lo and Hi,
// we need a similar record with signed SmallInt
LazLongRec = packed record
{$ifdef FPC_LITTLE_ENDIAN}
Lo,Hi : SmallInt;
{$else FPC_LITTLE_ENDIAN}
Hi,Lo : SmallInt;
{$endif FPC_LITTLE_ENDIAN}
end;
{ TLCLComponent }
TLCLComponent = class(TComponent)
private
FWidgetSetClass: TWSLCLComponentClass;
FLCLRefCount: integer;
protected
class procedure WSRegisterClass; virtual;
class function GetWSComponentClass(ASelf: TLCLComponent): TWSLCLComponentClass; virtual;
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
class function NewInstance: TObject; override;
procedure RemoveAllHandlersOfObject(AnObject: TObject); virtual;
procedure IncLCLRefCount;
procedure DecLCLRefCount;
property LCLRefCount: integer read FLCLRefCount;
property WidgetSetClass: TWSLCLComponentClass read FWidgetSetClass;
end;
{ TLCLReferenceComponent }
// A base class for all components having a handle
TLCLReferenceComponent = class(TLCLComponent)
private
FReferencePtr: PWSReference;
FCreating: Boolean; // Set if we are creating the handle
function GetHandle: THandle;
function GetReferenceAllocated: Boolean;
protected
procedure CreateParams(var AParams: TCreateParams); virtual;
procedure DestroyReference;
function GetReferenceHandle: THandle; virtual; abstract;
procedure ReferenceCreated; virtual; // gets called after the Handle is created
procedure ReferenceDestroying; virtual; // gets called before the Handle is destroyed
procedure ReferenceNeeded;
function WSCreateReference(AParams: TCreateParams): PWSReference; virtual;
procedure WSDestroyReference; virtual;
protected
public
destructor Destroy; override;
property HandleAllocated: Boolean read GetReferenceAllocated;
property ReferenceAllocated: Boolean read GetReferenceAllocated;
end;
implementation
uses
InterfaceBase;
class procedure TLCLComponent.WSRegisterClass;
begin
//
end;
// This method allows descendents to override the FWidgetSetClass
class function TLCLComponent.GetWSComponentClass(ASelf: TLCLComponent): TWSLCLComponentClass;
begin
Result := FindWSComponentClass(Self);
if Result = nil then
begin
{$IFDEF VerboseLCL}
DebugLn(['TLCLComponent.NewInstance WARNING: missing FWidgetSetClass ',ClassName]);
{$ENDIF}
Result := TWSLCLComponent;
end;
end;
constructor TLCLComponent.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
{$IFDEF DebugLCLComponents}
//DebugLn('TLCLComponent.Create ',DbgSName(Self));
DebugLCLComponents.MarkCreated(Self,DbgSName(Self));
{$ENDIF}
end;
destructor TLCLComponent.Destroy;
begin
{$IFNDEF DisableChecks}
if FLCLRefCount>0 then begin
DebugLn(['WARNING: ' + ClassName + '.Destroy with LCLRefCount>0. Hint: Maybe the component is processing an event?']);
{$IFDEF DebugTLCLComponentDestroy}
DumpStack;
{$ENDIF}
end;
{$ENDIF}
{$IFDEF DebugLCLComponents}
//DebugLn('TLCLComponent.Destroy ',DbgSName(Self));
DebugLCLComponents.MarkDestroyed(Self);
{$ENDIF}
inherited Destroy;
end;
class function TLCLComponent.NewInstance: TObject;
begin
Result := inherited NewInstance;
WSRegisterClass;
TLCLComponent(Result).FWidgetSetClass := GetWSComponentClass(TLCLComponent(Result));
end;
procedure TLCLComponent.RemoveAllHandlersOfObject(AnObject: TObject);
begin
end;
procedure TLCLComponent.IncLCLRefCount;
begin
inc(FLCLRefCount);
end;
procedure TLCLComponent.DecLCLRefCount;
begin
dec(FLCLRefCount);
end;
{ TLCLReferenceComponent }
procedure TLCLReferenceComponent.CreateParams(var AParams: TCreateParams);
begin
end;
destructor TLCLReferenceComponent.Destroy;
begin
DestroyReference;
inherited Destroy;
end;
procedure TLCLReferenceComponent.DestroyReference;
begin
if ReferenceAllocated then
begin
ReferenceDestroying;
WSDestroyReference;
FReferencePtr^._Clear;
FReferencePtr := nil;
end;
end;
function TLCLReferenceComponent.GetHandle: THandle;
begin
ReferenceNeeded;
Result := GetReferenceHandle;
end;
function TLCLReferenceComponent.GetReferenceAllocated: Boolean;
begin
Result := (FReferencePtr <> nil) and FReferencePtr^.Allocated;
end;
procedure TLCLReferenceComponent.ReferenceCreated;
begin
end;
procedure TLCLReferenceComponent.ReferenceDestroying;
begin
end;
procedure TLCLReferenceComponent.ReferenceNeeded;
var
Params: TCreateParams;
begin
if ReferenceAllocated then Exit;
if FCreating
then begin
// raise some error ?
{$IFNDEF DisableChecks}
DebugLn('TLCLReferenceComponent: Circular reference creation');
{$ENDIF}
Exit;
end;
CreateParams(Params);
FCreating := True;
try
FReferencePtr := WSCreateReference(Params);
if not ReferenceAllocated
then begin
// raise some error ?
{$IFNDEF DisableChecks}
DebugLn('TLCLHandleComponent: Reference creation failed');
{$ENDIF}
Exit;
end;
finally
FCreating := False;
end;
ReferenceCreated;
end;
function TLCLReferenceComponent.WSCreateReference(AParams: TCreateParams): PWSReference;
begin
// this function should be overriden in derrived class
Result := nil;
end;
procedure TLCLReferenceComponent.WSDestroyReference;
begin
TWSLCLReferenceComponentClass(WidgetSetClass).DestroyReference(Self);
end;
end.
|