compon.inc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  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. if op = opInsert then
  68. comp.FreeNotification(Self)
  69. else
  70. comp.RemoveFreeNotification(Self);
  71. end;
  72. end;
  73. Function TComponent.GetComponentCount: Integer;
  74. begin
  75. If not assigned(FComponents) then
  76. result:=0
  77. else
  78. Result:=FComponents.Count;
  79. end;
  80. Function TComponent.GetComponentIndex: Integer;
  81. begin
  82. If Assigned(FOwner) and Assigned(FOwner.FComponents) then
  83. Result:=FOWner.FComponents.IndexOf(Self)
  84. else
  85. Result:=-1;
  86. end;
  87. Procedure TComponent.Insert(AComponent: TComponent);
  88. begin
  89. If not assigned(FComponents) then
  90. FComponents:=TFpList.Create;
  91. FComponents.Add(AComponent);
  92. AComponent.FOwner:=Self;
  93. end;
  94. Procedure TComponent.ReadLeft(Reader: TReader);
  95. begin
  96. LongRec(FDesignInfo).Lo:=Reader.ReadInteger;
  97. end;
  98. Procedure TComponent.ReadTop(Reader: TReader);
  99. begin
  100. LongRec(FDesignInfo).Hi:=Reader.ReadInteger;
  101. end;
  102. Procedure TComponent.Remove(AComponent: TComponent);
  103. begin
  104. AComponent.FOwner:=Nil;
  105. If assigned(FCOmponents) then
  106. begin
  107. FComponents.Remove(AComponent);
  108. IF FComponents.Count=0 then
  109. begin
  110. FComponents.Free;
  111. FComponents:=Nil;
  112. end;
  113. end;
  114. end;
  115. Procedure TComponent.RemoveNotification(AComponent: TComponent);
  116. begin
  117. if FFreeNotifies<>nil then
  118. begin
  119. FFreeNotifies.Remove(AComponent);
  120. if FFreeNotifies.Count=0 then
  121. begin
  122. FFreeNotifies.Free;
  123. FFreeNotifies:=nil;
  124. Exclude(FComponentState,csFreeNotification);
  125. end;
  126. end;
  127. end;
  128. Procedure TComponent.SetComponentIndex(Value: Integer);
  129. Var Temp,Count : longint;
  130. begin
  131. If Not assigned(Fowner) then exit;
  132. Temp:=getcomponentindex;
  133. If temp<0 then exit;
  134. If value<0 then value:=0;
  135. Count:=Fowner.FComponents.Count;
  136. If Value>=Count then value:=count-1;
  137. If Value<>Temp then
  138. begin
  139. FOWner.FComponents.Delete(Temp);
  140. FOwner.FComponents.Insert(Value,Self);
  141. end;
  142. end;
  143. Procedure TComponent.SetReference(Enable: Boolean);
  144. var
  145. Field: ^TComponent;
  146. begin
  147. if Assigned(Owner) then
  148. begin
  149. Field := Owner.FieldAddress(Name);
  150. if Assigned(Field) then
  151. if Enable then
  152. Field^ := Self
  153. else
  154. Field^ := nil;
  155. end;
  156. end;
  157. Procedure TComponent.WriteLeft(Writer: TWriter);
  158. begin
  159. Writer.WriteInteger(LongRec(FDesignInfo).Lo);
  160. end;
  161. Procedure TComponent.WriteTop(Writer: TWriter);
  162. begin
  163. Writer.WriteInteger(LongRec(FDesignInfo).Hi);
  164. end;
  165. Procedure TComponent.ChangeName(const NewName: TComponentName);
  166. begin
  167. FName:=NewName;
  168. end;
  169. Procedure TComponent.DefineProperties(Filer: TFiler);
  170. Var Ancestor : TComponent;
  171. Temp : longint;
  172. begin
  173. Temp:=0;
  174. Ancestor:=TComponent(Filer.Ancestor);
  175. If Assigned(Ancestor) then Temp:=Ancestor.FDesignInfo;
  176. Filer.Defineproperty('left',@readleft,@writeleft,
  177. (longrec(FDesignInfo).Lo<>Longrec(temp).Lo));
  178. Filer.Defineproperty('top',@readtop,@writetop,
  179. (longrec(FDesignInfo).Hi<>Longrec(temp).Hi));
  180. end;
  181. Procedure TComponent.GetChildren(Proc: TGetChildProc; Root: TComponent);
  182. begin
  183. // Does nothing.
  184. end;
  185. Function TComponent.GetChildOwner: TComponent;
  186. begin
  187. Result:=Nil;
  188. end;
  189. Function TComponent.GetChildParent: TComponent;
  190. begin
  191. Result:=Self;
  192. end;
  193. Function TComponent.GetEnumerator: TComponentEnumerator;
  194. begin
  195. Result:=TComponentEnumerator.Create(Self);
  196. end;
  197. Function TComponent.GetNamePath: string;
  198. begin
  199. Result:=FName;
  200. end;
  201. Function TComponent.GetOwner: TPersistent;
  202. begin
  203. Result:=FOwner;
  204. end;
  205. Procedure TComponent.Loaded;
  206. begin
  207. Exclude(FComponentState,csLoading);
  208. end;
  209. Procedure TComponent.Loading;
  210. begin
  211. Include(FComponentState,csLoading);
  212. end;
  213. Procedure TComponent.Notification(AComponent: TComponent;
  214. Operation: TOperation);
  215. Var Runner : Longint;
  216. begin
  217. If (Operation=opRemove) and Assigned(FFreeNotifies) then
  218. begin
  219. FFreeNotifies.Remove(AComponent);
  220. If FFreeNotifies.Count=0 then
  221. begin
  222. FFreeNotifies.Free;
  223. FFreenotifies:=Nil;
  224. end;
  225. end;
  226. If assigned(FComponents) then
  227. For Runner:=0 To FComponents.Count-1 do
  228. TComponent(FComponents.Items[Runner]).Notification(AComponent,Operation);
  229. end;
  230. procedure TComponent.PaletteCreated;
  231. begin
  232. end;
  233. Procedure TComponent.ReadState(Reader: TReader);
  234. begin
  235. Reader.ReadData(Self);
  236. end;
  237. Procedure TComponent.SetAncestor(Value: Boolean);
  238. Var Runner : Longint;
  239. begin
  240. If Value then
  241. Include(FComponentState,csAncestor)
  242. else
  243. Exclude(FCOmponentState,csAncestor);
  244. if Assigned(FComponents) then
  245. For Runner:=0 To FComponents.Count-1 do
  246. TComponent(FComponents.Items[Runner]).SetAncestor(Value);
  247. end;
  248. Procedure TComponent.SetDesigning(Value: Boolean; SetChildren : Boolean = True);
  249. Var Runner : Longint;
  250. begin
  251. If Value then
  252. Include(FComponentState,csDesigning)
  253. else
  254. Exclude(FComponentState,csDesigning);
  255. if Assigned(FComponents) and SetChildren then
  256. For Runner:=0 To FComponents.Count - 1 do
  257. TComponent(FComponents.items[Runner]).SetDesigning(Value);
  258. end;
  259. Procedure TComponent.SetDesignInstance(Value: Boolean);
  260. begin
  261. If Value then
  262. Include(FComponentState,csDesignInstance)
  263. else
  264. Exclude(FComponentState,csDesignInstance);
  265. end;
  266. Procedure TComponent.SetInline(Value: Boolean);
  267. begin
  268. If Value then
  269. Include(FComponentState,csInline)
  270. else
  271. Exclude(FComponentState,csInline);
  272. end;
  273. Procedure TComponent.SetName(const NewName: TComponentName);
  274. begin
  275. If FName=NewName then exit;
  276. If (NewName<>'') and not IsValidIdent(NewName) then
  277. Raise EComponentError.CreateFmt(SInvalidName,[NewName]);
  278. If Assigned(FOwner) Then
  279. FOwner.ValidateRename(Self,FName,NewName)
  280. else
  281. ValidateRename(Nil,FName,NewName);
  282. SetReference(False);
  283. ChangeName(NewName);
  284. Setreference(True);
  285. end;
  286. Procedure TComponent.SetChildOrder(Child: TComponent; Order: Integer);
  287. begin
  288. // does nothing
  289. end;
  290. Procedure TComponent.SetParentComponent(Value: TComponent);
  291. begin
  292. // Does nothing
  293. end;
  294. Procedure TComponent.Updating;
  295. begin
  296. Include (FComponentState,csUpdating);
  297. end;
  298. Procedure TComponent.Updated;
  299. begin
  300. Exclude(FComponentState,csUpdating);
  301. end;
  302. class Procedure TComponent.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);
  303. begin
  304. // For compatibility only.
  305. end;
  306. Procedure TComponent.ValidateRename(AComponent: TComponent;
  307. const CurName, NewName: string);
  308. begin
  309. //!! This contradicts the Delphi manual.
  310. If (AComponent<>Nil) and (CompareText(CurName,NewName)<>0) and (AComponent.Owner = Self) and
  311. (FindComponent(NewName)<>Nil) then
  312. raise EComponentError.Createfmt(SDuplicateName,[newname]);
  313. If (csDesigning in FComponentState) and (FOwner<>Nil) then
  314. FOwner.ValidateRename(AComponent,Curname,Newname);
  315. end;
  316. Procedure TComponent.ValidateContainer(AComponent: TComponent);
  317. begin
  318. AComponent.ValidateInsert(Self);
  319. end;
  320. Procedure TComponent.ValidateInsert(AComponent: TComponent);
  321. begin
  322. // Does nothing.
  323. end;
  324. Procedure TComponent.WriteState(Writer: TWriter);
  325. begin
  326. Writer.WriteComponentData(Self);
  327. end;
  328. Constructor TComponent.Create(AOwner: TComponent);
  329. begin
  330. FComponentStyle:=[csInheritable];
  331. If Assigned(AOwner) then AOwner.InsertComponent(Self);
  332. end;
  333. Destructor TComponent.Destroy;
  334. Var
  335. I : Integer;
  336. C : TComponent;
  337. begin
  338. Destroying;
  339. If Assigned(FFreeNotifies) then
  340. begin
  341. I:=FFreeNotifies.Count-1;
  342. While (I>=0) do
  343. begin
  344. C:=TComponent(FFreeNotifies.Items[I]);
  345. // Delete, so one component is not notified twice, if it is owned.
  346. FFreeNotifies.Delete(I);
  347. C.Notification (self,opRemove);
  348. If (FFreeNotifies=Nil) then
  349. I:=0
  350. else if (I>FFreeNotifies.Count) then
  351. I:=FFreeNotifies.Count;
  352. dec(i);
  353. end;
  354. FreeAndNil(FFreeNotifies);
  355. end;
  356. DestroyComponents;
  357. If FOwner<>Nil Then FOwner.RemoveComponent(Self);
  358. inherited destroy;
  359. end;
  360. Procedure TComponent.BeforeDestruction;
  361. begin
  362. if not(csDestroying in FComponentstate) then
  363. Destroying;
  364. end;
  365. Procedure TComponent.DestroyComponents;
  366. Var acomponent: TComponent;
  367. begin
  368. While assigned(FComponents) do
  369. begin
  370. aComponent:=TComponent(FComponents.Last);
  371. Remove(aComponent);
  372. Acomponent.Destroy;
  373. end;
  374. end;
  375. Procedure TComponent.Destroying;
  376. Var Runner : longint;
  377. begin
  378. If csDestroying in FComponentstate Then Exit;
  379. include (FComponentState,csDestroying);
  380. If Assigned(FComponents) then
  381. for Runner:=0 to FComponents.Count-1 do
  382. TComponent(FComponents.Items[Runner]).Destroying;
  383. end;
  384. function TComponent.ExecuteAction(Action: TBasicAction): Boolean;
  385. begin
  386. if Action.HandlesTarget(Self) then
  387. begin
  388. Action.ExecuteTarget(Self);
  389. Result := True;
  390. end
  391. else
  392. Result := False;
  393. end;
  394. Function TComponent.FindComponent(const AName: string): TComponent;
  395. Var I : longint;
  396. begin
  397. Result:=Nil;
  398. If (AName='') or Not assigned(FComponents) then exit;
  399. For i:=0 to FComponents.Count-1 do
  400. if (CompareText(TComponent(FComponents[I]).Name,AName)=0) then
  401. begin
  402. Result:=TComponent(FComponents.Items[I]);
  403. exit;
  404. end;
  405. end;
  406. Procedure TComponent.FreeNotification(AComponent: TComponent);
  407. begin
  408. If (Owner<>Nil) and (AComponent=Owner) then exit;
  409. if csDestroying in ComponentState then
  410. AComponent.Notification(Self,opRemove)
  411. else
  412. begin
  413. If not (Assigned(FFreeNotifies)) then
  414. FFreeNotifies:=TFpList.Create;
  415. If FFreeNotifies.IndexOf(AComponent)=-1 then
  416. begin
  417. FFreeNotifies.Add(AComponent);
  418. AComponent.FreeNotification (self);
  419. end;
  420. end;
  421. end;
  422. procedure TComponent.RemoveFreeNotification(AComponent: TComponent);
  423. begin
  424. RemoveNotification(AComponent);
  425. AComponent.RemoveNotification (self);
  426. end;
  427. Procedure TComponent.FreeOnRelease;
  428. begin
  429. if Assigned(VCLComObject) then
  430. IVCLComObject(VCLComObject).FreeOnRelease;
  431. end;
  432. Function TComponent.GetParentComponent: TComponent;
  433. begin
  434. Result:=Nil;
  435. end;
  436. Function TComponent.HasParent: Boolean;
  437. begin
  438. Result:=False;
  439. end;
  440. Procedure TComponent.InsertComponent(AComponent: TComponent);
  441. begin
  442. AComponent.ValidateContainer(Self);
  443. ValidateRename(AComponent,'',AComponent.FName);
  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: Pointer): 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: Integer;{$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: Integer;{$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;