compon.inc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. {%MainUnit classes.pp}
  2. {
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {****************************************************************************}
  12. {* TComponentEnumerator *}
  13. {****************************************************************************}
  14. constructor TComponentEnumerator.Create(AComponent: TComponent);
  15. begin
  16. inherited Create;
  17. FComponent := AComponent;
  18. FPosition := -1;
  19. end;
  20. function TComponentEnumerator.GetCurrent: TComponent;
  21. begin
  22. Result := FComponent.Components[FPosition];
  23. end;
  24. function TComponentEnumerator.MoveNext: Boolean;
  25. begin
  26. Inc(FPosition);
  27. Result := FPosition < FComponent.ComponentCount;
  28. end;
  29. {****************************************************************************}
  30. {* TComponent *}
  31. {****************************************************************************}
  32. function TComponent.GetComObject: IUnknown;
  33. begin
  34. { Check if VCLComObject is not assigned - we need to create it by }
  35. { the call to CreateVCLComObject routine. If in the end we are still }
  36. { have no valid VCLComObject pointer we need to raise an exception }
  37. if not Assigned(VCLComObject) then
  38. begin
  39. if Assigned(CreateVCLComObjectProc) then
  40. CreateVCLComObjectProc(Self);
  41. if not Assigned(VCLComObject) then
  42. raise EComponentError.CreateFmt(SNoComSupport,[Name]);
  43. end;
  44. { VCLComObject is IVCComObject but we need to return IUnknown }
  45. IVCLComObject(VCLComObject).QueryInterface(IUnknown, Result);
  46. end;
  47. Function TComponent.GetComponent(AIndex: Integer): TComponent;
  48. begin
  49. If not assigned(FComponents) then
  50. Result:=Nil
  51. else
  52. Result:=TComponent(FComponents.Items[Aindex]);
  53. end;
  54. function TComponent.IsImplementorOf (const Intf:IInterface):boolean;
  55. var ref : IInterfaceComponentReference;
  56. begin
  57. result:=assigned(intf) and supports(intf,IInterfaceComponentReference,ref);
  58. if result then
  59. result:=ref.getcomponent=self;
  60. end;
  61. procedure TComponent.ReferenceInterface(const intf:IInterface;op:TOperation);
  62. var ref : IInterfaceComponentReference;
  63. comp : TComponent;
  64. begin
  65. if assigned(intf) and supports(intf,IInterfaceComponentReference,ref) then
  66. begin
  67. comp:=ref.getcomponent;
  68. if op = opInsert then
  69. comp.FreeNotification(Self)
  70. else
  71. comp.RemoveFreeNotification(Self);
  72. end;
  73. end;
  74. Function TComponent.GetComponentCount: Integer;
  75. begin
  76. If not assigned(FComponents) then
  77. result:=0
  78. else
  79. Result:=FComponents.Count;
  80. end;
  81. Function TComponent.GetComponentIndex: Integer;
  82. begin
  83. If Assigned(FOwner) and Assigned(FOwner.FComponents) then
  84. Result:=FOWner.FComponents.IndexOf(Self)
  85. else
  86. Result:=-1;
  87. end;
  88. function TComponent.GetObservers: TObservers;
  89. begin
  90. if FDObservers=Nil then
  91. FDObservers:=TObservers.Create;
  92. Result:=FDObservers;
  93. end;
  94. Procedure TComponent.Insert(AComponent: TComponent);
  95. begin
  96. If not assigned(FComponents) then
  97. FComponents:=TFpList.Create;
  98. FComponents.Add(AComponent);
  99. AComponent.FOwner:=Self;
  100. end;
  101. Procedure TComponent.ReadLeft(Reader: TReader);
  102. begin
  103. LongRec(FDesignInfo).Lo:=Reader.ReadInteger;
  104. end;
  105. Procedure TComponent.ReadTop(Reader: TReader);
  106. begin
  107. LongRec(FDesignInfo).Hi:=Reader.ReadInteger;
  108. end;
  109. Procedure TComponent.Remove(AComponent: TComponent);
  110. begin
  111. AComponent.FOwner:=Nil;
  112. If assigned(FCOmponents) then
  113. begin
  114. FComponents.Remove(AComponent);
  115. IF FComponents.Count=0 then
  116. begin
  117. FComponents.Free;
  118. FComponents:=Nil;
  119. end;
  120. end;
  121. end;
  122. Procedure TComponent.RemoveNotification(AComponent: TComponent);
  123. begin
  124. if FFreeNotifies<>nil then
  125. begin
  126. FFreeNotifies.Remove(AComponent);
  127. if FFreeNotifies.Count=0 then
  128. begin
  129. FFreeNotifies.Free;
  130. FFreeNotifies:=nil;
  131. Exclude(FComponentState,csFreeNotification);
  132. end;
  133. end;
  134. end;
  135. Procedure TComponent.SetComponentIndex(Value: Integer);
  136. Var Temp,Count : longint;
  137. begin
  138. If Not assigned(Fowner) then exit;
  139. Temp:=getcomponentindex;
  140. If temp<0 then exit;
  141. If value<0 then value:=0;
  142. Count:=Fowner.FComponents.Count;
  143. If Value>=Count then value:=count-1;
  144. If Value<>Temp then
  145. begin
  146. FOWner.FComponents.Delete(Temp);
  147. FOwner.FComponents.Insert(Value,Self);
  148. end;
  149. end;
  150. Procedure TComponent.SetReference(Enable: Boolean);
  151. var
  152. Field: ^TComponent;
  153. begin
  154. if Assigned(Owner) then
  155. begin
  156. Field := Owner.FieldAddress(Name);
  157. if Assigned(Field) then
  158. if Enable then
  159. Field^ := Self
  160. else
  161. Field^ := nil;
  162. end;
  163. end;
  164. Procedure TComponent.WriteLeft(Writer: TWriter);
  165. begin
  166. Writer.WriteInteger(LongRec(FDesignInfo).Lo);
  167. end;
  168. Procedure TComponent.WriteTop(Writer: TWriter);
  169. begin
  170. Writer.WriteInteger(LongRec(FDesignInfo).Hi);
  171. end;
  172. Procedure TComponent.ChangeName(const NewName: TComponentName);
  173. begin
  174. FName:=NewName;
  175. end;
  176. Procedure TComponent.DefineProperties(Filer: TFiler);
  177. Var Ancestor : TComponent;
  178. Temp : longint;
  179. begin
  180. Temp:=0;
  181. Ancestor:=TComponent(Filer.Ancestor);
  182. If Assigned(Ancestor) then Temp:=Ancestor.FDesignInfo;
  183. Filer.Defineproperty('Left',@readleft,@writeleft,
  184. (longrec(FDesignInfo).Lo<>Longrec(temp).Lo));
  185. Filer.Defineproperty('Top',@readtop,@writetop,
  186. (longrec(FDesignInfo).Hi<>Longrec(temp).Hi));
  187. end;
  188. Procedure TComponent.GetChildren(Proc: TGetChildProc; Root: TComponent);
  189. begin
  190. // Does nothing.
  191. end;
  192. Function TComponent.GetChildOwner: TComponent;
  193. begin
  194. Result:=Nil;
  195. end;
  196. Function TComponent.GetChildParent: TComponent;
  197. begin
  198. Result:=Self;
  199. end;
  200. Function TComponent.GetEnumerator: TComponentEnumerator;
  201. begin
  202. Result:=TComponentEnumerator.Create(Self);
  203. end;
  204. Function TComponent.GetNamePath: string;
  205. begin
  206. Result:=FName;
  207. end;
  208. Function TComponent.GetOwner: TPersistent;
  209. begin
  210. Result:=FOwner;
  211. end;
  212. Procedure TComponent.Loaded;
  213. begin
  214. Exclude(FComponentState,csLoading);
  215. end;
  216. Procedure TComponent.Loading;
  217. begin
  218. Include(FComponentState,csLoading);
  219. end;
  220. Procedure TComponent.Notification(AComponent: TComponent;
  221. Operation: TOperation);
  222. Var
  223. C : Longint;
  224. begin
  225. If (Operation=opRemove) then
  226. RemoveFreeNotification(AComponent);
  227. If Not assigned(FComponents) then
  228. exit;
  229. C:=FComponents.Count-1;
  230. While (C>=0) do
  231. begin
  232. TComponent(FComponents.Items[C]).Notification(AComponent,Operation);
  233. Dec(C);
  234. if C>=FComponents.Count then
  235. C:=FComponents.Count-1;
  236. end;
  237. end;
  238. procedure TComponent.PaletteCreated;
  239. begin
  240. end;
  241. Procedure TComponent.ReadState(Reader: TReader);
  242. begin
  243. Reader.ReadData(Self);
  244. end;
  245. Procedure TComponent.SetAncestor(Value: Boolean);
  246. Var Runner : Longint;
  247. begin
  248. If Value then
  249. Include(FComponentState,csAncestor)
  250. else
  251. Exclude(FCOmponentState,csAncestor);
  252. if Assigned(FComponents) then
  253. For Runner:=0 To FComponents.Count-1 do
  254. TComponent(FComponents.Items[Runner]).SetAncestor(Value);
  255. end;
  256. Procedure TComponent.SetDesigning(Value: Boolean; SetChildren : Boolean = True);
  257. Var Runner : Longint;
  258. begin
  259. If Value then
  260. Include(FComponentState,csDesigning)
  261. else
  262. Exclude(FComponentState,csDesigning);
  263. if Assigned(FComponents) and SetChildren then
  264. For Runner:=0 To FComponents.Count - 1 do
  265. TComponent(FComponents.items[Runner]).SetDesigning(Value);
  266. end;
  267. Procedure TComponent.SetDesignInstance(Value: Boolean);
  268. begin
  269. If Value then
  270. Include(FComponentState,csDesignInstance)
  271. else
  272. Exclude(FComponentState,csDesignInstance);
  273. end;
  274. Procedure TComponent.SetInline(Value: Boolean);
  275. begin
  276. If Value then
  277. Include(FComponentState,csInline)
  278. else
  279. Exclude(FComponentState,csInline);
  280. end;
  281. Procedure TComponent.SetName(const NewName: TComponentName);
  282. begin
  283. If FName=NewName then exit;
  284. If (NewName<>'') and not IsValidIdent(NewName) then
  285. Raise EComponentError.CreateFmt(SInvalidName,[NewName]);
  286. If Assigned(FOwner) Then
  287. FOwner.ValidateRename(Self,FName,NewName)
  288. else
  289. ValidateRename(Nil,FName,NewName);
  290. SetReference(False);
  291. ChangeName(NewName);
  292. Setreference(True);
  293. end;
  294. Procedure TComponent.SetChildOrder(Child: TComponent; Order: Integer);
  295. begin
  296. // does nothing
  297. end;
  298. Procedure TComponent.SetParentComponent(Value: TComponent);
  299. begin
  300. // Does nothing
  301. end;
  302. Procedure TComponent.Updating;
  303. begin
  304. Include (FComponentState,csUpdating);
  305. end;
  306. Procedure TComponent.Updated;
  307. begin
  308. Exclude(FComponentState,csUpdating);
  309. end;
  310. class Procedure TComponent.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);
  311. begin
  312. // For compatibility only.
  313. end;
  314. Procedure TComponent.ValidateRename(AComponent: TComponent;
  315. const CurName, NewName: string);
  316. begin
  317. //!! This contradicts the Delphi manual.
  318. If (AComponent<>Nil) and (CompareText(CurName,NewName)<>0) and (AComponent.Owner = Self) and
  319. (FindComponent(NewName)<>Nil) then
  320. raise EComponentError.Createfmt(SDuplicateName,[newname]);
  321. If (csDesigning in FComponentState) and (FOwner<>Nil) then
  322. FOwner.ValidateRename(AComponent,Curname,Newname);
  323. end;
  324. Procedure TComponent.ValidateContainer(AComponent: TComponent);
  325. begin
  326. AComponent.ValidateInsert(Self);
  327. end;
  328. Procedure TComponent.ValidateInsert(AComponent: TComponent);
  329. begin
  330. // Does nothing.
  331. end;
  332. Procedure TComponent.WriteState(Writer: TWriter);
  333. begin
  334. Writer.WriteComponentData(Self);
  335. end;
  336. Constructor TComponent.Create(AOwner: TComponent);
  337. begin
  338. FComponentStyle:=[csInheritable];
  339. If Assigned(AOwner) then AOwner.InsertComponent(Self);
  340. end;
  341. Destructor TComponent.Destroy;
  342. Var
  343. I : Integer;
  344. C : TComponent;
  345. begin
  346. Destroying;
  347. FreeAndNil(FObservers);
  348. If Assigned(FFreeNotifies) then
  349. begin
  350. I:=FFreeNotifies.Count-1;
  351. While (I>=0) do
  352. begin
  353. C:=TComponent(FFreeNotifies.Items[I]);
  354. // Delete, so one component is not notified twice, if it is owned.
  355. FFreeNotifies.Delete(I);
  356. C.Notification (self,opRemove);
  357. If (FFreeNotifies=Nil) then
  358. I:=0
  359. else if (I>FFreeNotifies.Count) then
  360. I:=FFreeNotifies.Count;
  361. dec(i);
  362. end;
  363. FreeAndNil(FFreeNotifies);
  364. end;
  365. DestroyComponents;
  366. If FOwner<>Nil Then FOwner.RemoveComponent(Self);
  367. inherited destroy;
  368. end;
  369. Procedure TComponent.BeforeDestruction;
  370. begin
  371. if not(csDestroying in FComponentstate) then
  372. Destroying;
  373. end;
  374. Procedure TComponent.DestroyComponents;
  375. Var acomponent: TComponent;
  376. begin
  377. While assigned(FComponents) do
  378. begin
  379. aComponent:=TComponent(FComponents.Last);
  380. Remove(aComponent);
  381. Acomponent.Destroy;
  382. end;
  383. end;
  384. Procedure TComponent.Destroying;
  385. Var Runner : longint;
  386. begin
  387. If csDestroying in FComponentstate Then Exit;
  388. include (FComponentState,csDestroying);
  389. If Assigned(FComponents) then
  390. for Runner:=0 to FComponents.Count-1 do
  391. TComponent(FComponents.Items[Runner]).Destroying;
  392. end;
  393. function TComponent.ExecuteAction(Action: TBasicAction): Boolean;
  394. begin
  395. if Action.HandlesTarget(Self) then
  396. begin
  397. Action.ExecuteTarget(Self);
  398. Result := True;
  399. end
  400. else
  401. Result := False;
  402. end;
  403. Function TComponent.FindComponent(const AName: string): TComponent;
  404. Var I : longint;
  405. C : TComponent;
  406. begin
  407. Result:=Nil;
  408. If (AName='') or Not assigned(FComponents) then exit;
  409. For i:=0 to FComponents.Count-1 do
  410. Begin
  411. c:=TComponent(FComponents[I]);
  412. If (CompareText(C.Name,AName)=0) then
  413. Exit(C);
  414. End;
  415. end;
  416. Procedure TComponent.FreeNotification(AComponent: TComponent);
  417. begin
  418. If (Owner<>Nil) and (AComponent=Owner) then exit;
  419. If not (Assigned(FFreeNotifies)) then
  420. FFreeNotifies:=TFpList.Create;
  421. If FFreeNotifies.IndexOf(AComponent)=-1 then
  422. begin
  423. FFreeNotifies.Add(AComponent);
  424. AComponent.FreeNotification (self);
  425. end;
  426. end;
  427. procedure TComponent.RemoveFreeNotification(AComponent: TComponent);
  428. begin
  429. RemoveNotification(AComponent);
  430. AComponent.RemoveNotification (self);
  431. end;
  432. Procedure TComponent.FreeOnRelease;
  433. begin
  434. if Assigned(VCLComObject) then
  435. IVCLComObject(VCLComObject).FreeOnRelease;
  436. end;
  437. Function TComponent.GetParentComponent: TComponent;
  438. begin
  439. Result:=Nil;
  440. end;
  441. Function TComponent.HasParent: Boolean;
  442. begin
  443. Result:=False;
  444. end;
  445. Procedure TComponent.InsertComponent(AComponent: TComponent);
  446. begin
  447. AComponent.ValidateContainer(Self);
  448. ValidateRename(AComponent,'',AComponent.FName);
  449. If AComponent.FOwner<>Nil then
  450. AComponent.FOwner.Remove(AComponent);
  451. Insert(AComponent);
  452. AComponent.SetReference(True);
  453. If csDesigning in FComponentState then
  454. AComponent.SetDesigning(true);
  455. Notification(AComponent,opInsert);
  456. end;
  457. Procedure TComponent.RemoveComponent(AComponent: TComponent);
  458. begin
  459. Notification(AComponent,opRemove);
  460. AComponent.SetReference(False);
  461. Remove(AComponent);
  462. Acomponent.Setdesigning(False);
  463. ValidateRename(AComponent,AComponent.FName,'');
  464. end;
  465. Function TComponent.SafeCallException(ExceptObject: TObject;
  466. ExceptAddr: CodePointer): HResult;
  467. begin
  468. if Assigned(VCLComObject) then
  469. Result := IVCLComObject(VCLComObject).SafeCallException(ExceptObject, ExceptAddr)
  470. else
  471. Result := inherited SafeCallException(ExceptObject, ExceptAddr);
  472. end;
  473. procedure TComponent.SetSubComponent(ASubComponent: Boolean);
  474. begin
  475. if ASubComponent then
  476. Include(FComponentStyle, csSubComponent)
  477. else
  478. Exclude(FComponentStyle, csSubComponent);
  479. end;
  480. function TComponent.UpdateAction(Action: TBasicAction): Boolean;
  481. begin
  482. if Action.HandlesTarget(Self) then
  483. begin
  484. Action.UpdateTarget(Self);
  485. Result := True;
  486. end
  487. else
  488. Result := False;
  489. end;
  490. function TComponent.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; out Obj): HResult;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
  491. begin
  492. if Assigned(VCLComObject) then
  493. Result := IVCLComObject(VCLComObject).QueryInterface(IID, Obj)
  494. else
  495. if GetInterface(IID, Obj) then
  496. Result := S_OK
  497. else
  498. Result := E_NOINTERFACE;
  499. end;
  500. function TComponent._AddRef: Longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
  501. begin
  502. if Assigned(VCLComObject) then
  503. Result := IVCLComObject(VCLComObject)._AddRef
  504. else
  505. Result := -1;
  506. end;
  507. function TComponent._Release: Longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
  508. begin
  509. if Assigned(VCLComObject) then
  510. Result := IVCLComObject(VCLComObject)._Release
  511. else
  512. Result := -1;
  513. end;
  514. function TComponent.iicrGetComponent: TComponent;
  515. begin
  516. result:=self;
  517. end;
  518. function TComponent.GetTypeInfoCount(out Count: Integer): HResult; stdcall;
  519. begin
  520. if Assigned(VCLComObject) then
  521. Result := IVCLComObject(VCLComObject).GetTypeInfoCount(Count)
  522. else
  523. Result := E_NOTIMPL;
  524. end;
  525. function TComponent.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
  526. begin
  527. if Assigned(VCLComObject) then
  528. Result := IVCLComObject(VCLComObject).GetTypeInfo(Index, LocaleID, TypeInfo)
  529. else
  530. Result := E_NOTIMPL;
  531. end;
  532. function TComponent.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount,
  533. LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
  534. begin
  535. if Assigned(VCLComObject) then
  536. Result := IVCLComObject(VCLComObject).GetIDsOfNames(IID, Names, NameCount, LocaleID, DispIDs)
  537. else
  538. Result := E_NOTIMPL;
  539. end;
  540. function TComponent.Invoke(DispID: Integer; const IID: TGUID;
  541. LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo,
  542. ArgErr: Pointer): HResult; stdcall;
  543. begin
  544. if Assigned(VCLComObject) then
  545. Result := IVCLComObject(VCLComObject).Invoke(DispID, IID, LocaleID, Flags, Params,
  546. VarResult, ExcepInfo, ArgErr)
  547. else
  548. Result := E_NOTIMPL;
  549. end;
  550. { Delta stream support }
  551. procedure TComponent.GetDeltaStreams(aProc: TGetStreamProc);
  552. begin
  553. // To be implemented by descendants
  554. end;
  555. procedure TComponent.ReadDeltaStream(const S: TStream);
  556. begin
  557. S.ReadComponent(Self);
  558. end;
  559. procedure TComponent.ReadDeltaState;
  560. var
  561. Done : boolean;
  562. begin
  563. if (csDesigning in ComponentState) then
  564. exit;
  565. Done:=False;
  566. if Assigned(FOnGetDeltaStreams) then
  567. FOnGetDeltaStreams(Self,@ReadDeltaStream,Done);
  568. if not Done then
  569. GetDeltaStreams(@ReadDeltaStream);
  570. end;