compon.inc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  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. Procedure TComponent.Insert(AComponent: TComponent);
  89. begin
  90. If not assigned(FComponents) then
  91. FComponents:=TFpList.Create;
  92. FComponents.Add(AComponent);
  93. AComponent.FOwner:=Self;
  94. end;
  95. Procedure TComponent.ReadLeft(Reader: TReader);
  96. begin
  97. LongRec(FDesignInfo).Lo:=Reader.ReadInteger;
  98. end;
  99. Procedure TComponent.ReadTop(Reader: TReader);
  100. begin
  101. LongRec(FDesignInfo).Hi:=Reader.ReadInteger;
  102. end;
  103. Procedure TComponent.Remove(AComponent: TComponent);
  104. begin
  105. AComponent.FOwner:=Nil;
  106. If assigned(FCOmponents) then
  107. begin
  108. FComponents.Remove(AComponent);
  109. IF FComponents.Count=0 then
  110. begin
  111. FComponents.Free;
  112. FComponents:=Nil;
  113. end;
  114. end;
  115. end;
  116. Procedure TComponent.RemoveNotification(AComponent: TComponent);
  117. begin
  118. if FFreeNotifies<>nil then
  119. begin
  120. FFreeNotifies.Remove(AComponent);
  121. if FFreeNotifies.Count=0 then
  122. begin
  123. FFreeNotifies.Free;
  124. FFreeNotifies:=nil;
  125. Exclude(FComponentState,csFreeNotification);
  126. end;
  127. end;
  128. end;
  129. Procedure TComponent.SetComponentIndex(Value: Integer);
  130. Var Temp,Count : longint;
  131. begin
  132. If Not assigned(Fowner) then exit;
  133. Temp:=getcomponentindex;
  134. If temp<0 then exit;
  135. If value<0 then value:=0;
  136. Count:=Fowner.FComponents.Count;
  137. If Value>=Count then value:=count-1;
  138. If Value<>Temp then
  139. begin
  140. FOWner.FComponents.Delete(Temp);
  141. FOwner.FComponents.Insert(Value,Self);
  142. end;
  143. end;
  144. Procedure TComponent.SetReference(Enable: Boolean);
  145. var
  146. Field: ^TComponent;
  147. begin
  148. if Assigned(Owner) then
  149. begin
  150. Field := Owner.FieldAddress(Name);
  151. if Assigned(Field) then
  152. if Enable then
  153. Field^ := Self
  154. else
  155. Field^ := nil;
  156. end;
  157. end;
  158. Procedure TComponent.WriteLeft(Writer: TWriter);
  159. begin
  160. Writer.WriteInteger(LongRec(FDesignInfo).Lo);
  161. end;
  162. Procedure TComponent.WriteTop(Writer: TWriter);
  163. begin
  164. Writer.WriteInteger(LongRec(FDesignInfo).Hi);
  165. end;
  166. Procedure TComponent.ChangeName(const NewName: TComponentName);
  167. begin
  168. FName:=NewName;
  169. end;
  170. Procedure TComponent.DefineProperties(Filer: TFiler);
  171. Var Ancestor : TComponent;
  172. Temp : longint;
  173. begin
  174. Temp:=0;
  175. Ancestor:=TComponent(Filer.Ancestor);
  176. If Assigned(Ancestor) then Temp:=Ancestor.FDesignInfo;
  177. Filer.Defineproperty('Left',@readleft,@writeleft,
  178. (longrec(FDesignInfo).Lo<>Longrec(temp).Lo));
  179. Filer.Defineproperty('Top',@readtop,@writetop,
  180. (longrec(FDesignInfo).Hi<>Longrec(temp).Hi));
  181. end;
  182. Procedure TComponent.GetChildren(Proc: TGetChildProc; Root: TComponent);
  183. begin
  184. // Does nothing.
  185. end;
  186. Function TComponent.GetChildOwner: TComponent;
  187. begin
  188. Result:=Nil;
  189. end;
  190. Function TComponent.GetChildParent: TComponent;
  191. begin
  192. Result:=Self;
  193. end;
  194. Function TComponent.GetEnumerator: TComponentEnumerator;
  195. begin
  196. Result:=TComponentEnumerator.Create(Self);
  197. end;
  198. Function TComponent.GetNamePath: string;
  199. begin
  200. Result:=FName;
  201. end;
  202. Function TComponent.GetOwner: TPersistent;
  203. begin
  204. Result:=FOwner;
  205. end;
  206. Procedure TComponent.Loaded;
  207. begin
  208. Exclude(FComponentState,csLoading);
  209. end;
  210. Procedure TComponent.Loading;
  211. begin
  212. Include(FComponentState,csLoading);
  213. end;
  214. Procedure TComponent.Notification(AComponent: TComponent;
  215. Operation: TOperation);
  216. Var
  217. C : Longint;
  218. begin
  219. If (Operation=opRemove) then
  220. RemoveFreeNotification(AComponent);
  221. If Not assigned(FComponents) then
  222. exit;
  223. C:=FComponents.Count-1;
  224. While (C>=0) do
  225. begin
  226. TComponent(FComponents.Items[C]).Notification(AComponent,Operation);
  227. Dec(C);
  228. if C>=FComponents.Count then
  229. C:=FComponents.Count-1;
  230. end;
  231. end;
  232. procedure TComponent.PaletteCreated;
  233. begin
  234. end;
  235. Procedure TComponent.ReadState(Reader: TReader);
  236. begin
  237. Reader.ReadData(Self);
  238. end;
  239. Procedure TComponent.SetAncestor(Value: Boolean);
  240. Var Runner : Longint;
  241. begin
  242. If Value then
  243. Include(FComponentState,csAncestor)
  244. else
  245. Exclude(FCOmponentState,csAncestor);
  246. if Assigned(FComponents) then
  247. For Runner:=0 To FComponents.Count-1 do
  248. TComponent(FComponents.Items[Runner]).SetAncestor(Value);
  249. end;
  250. Procedure TComponent.SetDesigning(Value: Boolean; SetChildren : Boolean = True);
  251. Var Runner : Longint;
  252. begin
  253. If Value then
  254. Include(FComponentState,csDesigning)
  255. else
  256. Exclude(FComponentState,csDesigning);
  257. if Assigned(FComponents) and SetChildren then
  258. For Runner:=0 To FComponents.Count - 1 do
  259. TComponent(FComponents.items[Runner]).SetDesigning(Value);
  260. end;
  261. Procedure TComponent.SetDesignInstance(Value: Boolean);
  262. begin
  263. If Value then
  264. Include(FComponentState,csDesignInstance)
  265. else
  266. Exclude(FComponentState,csDesignInstance);
  267. end;
  268. Procedure TComponent.SetInline(Value: Boolean);
  269. begin
  270. If Value then
  271. Include(FComponentState,csInline)
  272. else
  273. Exclude(FComponentState,csInline);
  274. end;
  275. Procedure TComponent.SetName(const NewName: TComponentName);
  276. begin
  277. If FName=NewName then exit;
  278. If (NewName<>'') and not IsValidIdent(NewName) then
  279. Raise EComponentError.CreateFmt(SInvalidName,[NewName]);
  280. If Assigned(FOwner) Then
  281. FOwner.ValidateRename(Self,FName,NewName)
  282. else
  283. ValidateRename(Nil,FName,NewName);
  284. SetReference(False);
  285. ChangeName(NewName);
  286. Setreference(True);
  287. end;
  288. Procedure TComponent.SetChildOrder(Child: TComponent; Order: Integer);
  289. begin
  290. // does nothing
  291. end;
  292. Procedure TComponent.SetParentComponent(Value: TComponent);
  293. begin
  294. // Does nothing
  295. end;
  296. Procedure TComponent.Updating;
  297. begin
  298. Include (FComponentState,csUpdating);
  299. end;
  300. Procedure TComponent.Updated;
  301. begin
  302. Exclude(FComponentState,csUpdating);
  303. end;
  304. class Procedure TComponent.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);
  305. begin
  306. // For compatibility only.
  307. end;
  308. Procedure TComponent.ValidateRename(AComponent: TComponent;
  309. const CurName, NewName: string);
  310. begin
  311. //!! This contradicts the Delphi manual.
  312. If (AComponent<>Nil) and (CompareText(CurName,NewName)<>0) and (AComponent.Owner = Self) and
  313. (FindComponent(NewName)<>Nil) then
  314. raise EComponentError.Createfmt(SDuplicateName,[newname]);
  315. If (csDesigning in FComponentState) and (FOwner<>Nil) then
  316. FOwner.ValidateRename(AComponent,Curname,Newname);
  317. end;
  318. Procedure TComponent.ValidateContainer(AComponent: TComponent);
  319. begin
  320. AComponent.ValidateInsert(Self);
  321. end;
  322. Procedure TComponent.ValidateInsert(AComponent: TComponent);
  323. begin
  324. // Does nothing.
  325. end;
  326. Procedure TComponent.WriteState(Writer: TWriter);
  327. begin
  328. Writer.WriteComponentData(Self);
  329. end;
  330. Constructor TComponent.Create(AOwner: TComponent);
  331. begin
  332. FComponentStyle:=[csInheritable];
  333. If Assigned(AOwner) then AOwner.InsertComponent(Self);
  334. end;
  335. Destructor TComponent.Destroy;
  336. Var
  337. I : Integer;
  338. C : TComponent;
  339. begin
  340. Destroying;
  341. If Assigned(FFreeNotifies) then
  342. begin
  343. I:=FFreeNotifies.Count-1;
  344. While (I>=0) do
  345. begin
  346. C:=TComponent(FFreeNotifies.Items[I]);
  347. // Delete, so one component is not notified twice, if it is owned.
  348. FFreeNotifies.Delete(I);
  349. C.Notification (self,opRemove);
  350. If (FFreeNotifies=Nil) then
  351. I:=0
  352. else if (I>FFreeNotifies.Count) then
  353. I:=FFreeNotifies.Count;
  354. dec(i);
  355. end;
  356. FreeAndNil(FFreeNotifies);
  357. end;
  358. DestroyComponents;
  359. If FOwner<>Nil Then FOwner.RemoveComponent(Self);
  360. inherited destroy;
  361. end;
  362. Procedure TComponent.BeforeDestruction;
  363. begin
  364. if not(csDestroying in FComponentstate) then
  365. Destroying;
  366. end;
  367. Procedure TComponent.DestroyComponents;
  368. Var acomponent: TComponent;
  369. begin
  370. While assigned(FComponents) do
  371. begin
  372. aComponent:=TComponent(FComponents.Last);
  373. Remove(aComponent);
  374. Acomponent.Destroy;
  375. end;
  376. end;
  377. Procedure TComponent.Destroying;
  378. Var Runner : longint;
  379. begin
  380. If csDestroying in FComponentstate Then Exit;
  381. include (FComponentState,csDestroying);
  382. If Assigned(FComponents) then
  383. for Runner:=0 to FComponents.Count-1 do
  384. TComponent(FComponents.Items[Runner]).Destroying;
  385. end;
  386. function TComponent.ExecuteAction(Action: TBasicAction): Boolean;
  387. begin
  388. if Action.HandlesTarget(Self) then
  389. begin
  390. Action.ExecuteTarget(Self);
  391. Result := True;
  392. end
  393. else
  394. Result := False;
  395. end;
  396. Function TComponent.FindComponent(const AName: string): TComponent;
  397. Var I : longint;
  398. C : TComponent;
  399. begin
  400. Result:=Nil;
  401. If (AName='') or Not assigned(FComponents) then exit;
  402. For i:=0 to FComponents.Count-1 do
  403. Begin
  404. c:=TComponent(FComponents[I]);
  405. If (CompareText(C.Name,AName)=0) then
  406. Exit(C);
  407. End;
  408. end;
  409. Procedure TComponent.FreeNotification(AComponent: TComponent);
  410. begin
  411. If (Owner<>Nil) and (AComponent=Owner) then exit;
  412. If not (Assigned(FFreeNotifies)) then
  413. FFreeNotifies:=TFpList.Create;
  414. If FFreeNotifies.IndexOf(AComponent)=-1 then
  415. begin
  416. FFreeNotifies.Add(AComponent);
  417. AComponent.FreeNotification (self);
  418. end;
  419. end;
  420. procedure TComponent.RemoveFreeNotification(AComponent: TComponent);
  421. begin
  422. RemoveNotification(AComponent);
  423. AComponent.RemoveNotification (self);
  424. end;
  425. Procedure TComponent.FreeOnRelease;
  426. begin
  427. if Assigned(VCLComObject) then
  428. IVCLComObject(VCLComObject).FreeOnRelease;
  429. end;
  430. Function TComponent.GetParentComponent: TComponent;
  431. begin
  432. Result:=Nil;
  433. end;
  434. Function TComponent.HasParent: Boolean;
  435. begin
  436. Result:=False;
  437. end;
  438. Procedure TComponent.InsertComponent(AComponent: TComponent);
  439. begin
  440. AComponent.ValidateContainer(Self);
  441. ValidateRename(AComponent,'',AComponent.FName);
  442. If AComponent.FOwner<>Nil then
  443. AComponent.FOwner.Remove(AComponent);
  444. Insert(AComponent);
  445. AComponent.SetReference(True);
  446. If csDesigning in FComponentState then
  447. AComponent.SetDesigning(true);
  448. Notification(AComponent,opInsert);
  449. end;
  450. Procedure TComponent.RemoveComponent(AComponent: TComponent);
  451. begin
  452. Notification(AComponent,opRemove);
  453. AComponent.SetReference(False);
  454. Remove(AComponent);
  455. Acomponent.Setdesigning(False);
  456. ValidateRename(AComponent,AComponent.FName,'');
  457. end;
  458. Function TComponent.SafeCallException(ExceptObject: TObject;
  459. ExceptAddr: CodePointer): HResult;
  460. begin
  461. if Assigned(VCLComObject) then
  462. Result := IVCLComObject(VCLComObject).SafeCallException(ExceptObject, ExceptAddr)
  463. else
  464. Result := inherited SafeCallException(ExceptObject, ExceptAddr);
  465. end;
  466. procedure TComponent.SetSubComponent(ASubComponent: Boolean);
  467. begin
  468. if ASubComponent then
  469. Include(FComponentStyle, csSubComponent)
  470. else
  471. Exclude(FComponentStyle, csSubComponent);
  472. end;
  473. function TComponent.UpdateAction(Action: TBasicAction): Boolean;
  474. begin
  475. if Action.HandlesTarget(Self) then
  476. begin
  477. Action.UpdateTarget(Self);
  478. Result := True;
  479. end
  480. else
  481. Result := False;
  482. end;
  483. function TComponent.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; out Obj): HResult;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
  484. begin
  485. if Assigned(VCLComObject) then
  486. Result := IVCLComObject(VCLComObject).QueryInterface(IID, Obj)
  487. else
  488. if GetInterface(IID, Obj) then
  489. Result := S_OK
  490. else
  491. Result := E_NOINTERFACE;
  492. end;
  493. function TComponent._AddRef: Longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
  494. begin
  495. if Assigned(VCLComObject) then
  496. Result := IVCLComObject(VCLComObject)._AddRef
  497. else
  498. Result := -1;
  499. end;
  500. function TComponent._Release: Longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
  501. begin
  502. if Assigned(VCLComObject) then
  503. Result := IVCLComObject(VCLComObject)._Release
  504. else
  505. Result := -1;
  506. end;
  507. function TComponent.iicrGetComponent: TComponent;
  508. begin
  509. result:=self;
  510. end;
  511. function TComponent.GetTypeInfoCount(out Count: Integer): HResult; stdcall;
  512. begin
  513. if Assigned(VCLComObject) then
  514. Result := IVCLComObject(VCLComObject).GetTypeInfoCount(Count)
  515. else
  516. Result := E_NOTIMPL;
  517. end;
  518. function TComponent.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
  519. begin
  520. if Assigned(VCLComObject) then
  521. Result := IVCLComObject(VCLComObject).GetTypeInfo(Index, LocaleID, TypeInfo)
  522. else
  523. Result := E_NOTIMPL;
  524. end;
  525. function TComponent.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount,
  526. LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
  527. begin
  528. if Assigned(VCLComObject) then
  529. Result := IVCLComObject(VCLComObject).GetIDsOfNames(IID, Names, NameCount, LocaleID, DispIDs)
  530. else
  531. Result := E_NOTIMPL;
  532. end;
  533. function TComponent.Invoke(DispID: Integer; const IID: TGUID;
  534. LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo,
  535. ArgErr: Pointer): HResult; stdcall;
  536. begin
  537. if Assigned(VCLComObject) then
  538. Result := IVCLComObject(VCLComObject).Invoke(DispID, IID, LocaleID, Flags, Params,
  539. VarResult, ExcepInfo, ArgErr)
  540. else
  541. Result := E_NOTIMPL;
  542. end;