compon.inc 16 KB

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