2
0

compon.inc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  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
  216. C : Longint;
  217. begin
  218. If (Operation=opRemove) then
  219. RemoveFreeNotification(AComponent);
  220. If Not assigned(FComponents) then
  221. exit;
  222. C:=FComponents.Count-1;
  223. While (C>=0) do
  224. begin
  225. TComponent(FComponents.Items[C]).Notification(AComponent,Operation);
  226. Dec(C);
  227. if C>=FComponents.Count then
  228. C:=FComponents.Count-1;
  229. end;
  230. end;
  231. procedure TComponent.PaletteCreated;
  232. begin
  233. end;
  234. Procedure TComponent.ReadState(Reader: TReader);
  235. begin
  236. Reader.ReadData(Self);
  237. end;
  238. Procedure TComponent.SetAncestor(Value: Boolean);
  239. Var Runner : Longint;
  240. begin
  241. If Value then
  242. Include(FComponentState,csAncestor)
  243. else
  244. Exclude(FCOmponentState,csAncestor);
  245. if Assigned(FComponents) then
  246. For Runner:=0 To FComponents.Count-1 do
  247. TComponent(FComponents.Items[Runner]).SetAncestor(Value);
  248. end;
  249. Procedure TComponent.SetDesigning(Value: Boolean; SetChildren : Boolean = True);
  250. Var Runner : Longint;
  251. begin
  252. If Value then
  253. Include(FComponentState,csDesigning)
  254. else
  255. Exclude(FComponentState,csDesigning);
  256. if Assigned(FComponents) and SetChildren then
  257. For Runner:=0 To FComponents.Count - 1 do
  258. TComponent(FComponents.items[Runner]).SetDesigning(Value);
  259. end;
  260. Procedure TComponent.SetDesignInstance(Value: Boolean);
  261. begin
  262. If Value then
  263. Include(FComponentState,csDesignInstance)
  264. else
  265. Exclude(FComponentState,csDesignInstance);
  266. end;
  267. Procedure TComponent.SetInline(Value: Boolean);
  268. begin
  269. If Value then
  270. Include(FComponentState,csInline)
  271. else
  272. Exclude(FComponentState,csInline);
  273. end;
  274. Procedure TComponent.SetName(const NewName: TComponentName);
  275. begin
  276. If FName=NewName then exit;
  277. If (NewName<>'') and not IsValidIdent(NewName) then
  278. Raise EComponentError.CreateFmt(SInvalidName,[NewName]);
  279. If Assigned(FOwner) Then
  280. FOwner.ValidateRename(Self,FName,NewName)
  281. else
  282. ValidateRename(Nil,FName,NewName);
  283. SetReference(False);
  284. ChangeName(NewName);
  285. Setreference(True);
  286. end;
  287. Procedure TComponent.SetChildOrder(Child: TComponent; Order: Integer);
  288. begin
  289. // does nothing
  290. end;
  291. Procedure TComponent.SetParentComponent(Value: TComponent);
  292. begin
  293. // Does nothing
  294. end;
  295. Procedure TComponent.Updating;
  296. begin
  297. Include (FComponentState,csUpdating);
  298. end;
  299. Procedure TComponent.Updated;
  300. begin
  301. Exclude(FComponentState,csUpdating);
  302. end;
  303. class Procedure TComponent.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);
  304. begin
  305. // For compatibility only.
  306. end;
  307. Procedure TComponent.ValidateRename(AComponent: TComponent;
  308. const CurName, NewName: string);
  309. begin
  310. //!! This contradicts the Delphi manual.
  311. If (AComponent<>Nil) and (CompareText(CurName,NewName)<>0) and (AComponent.Owner = Self) and
  312. (FindComponent(NewName)<>Nil) then
  313. raise EComponentError.Createfmt(SDuplicateName,[newname]);
  314. If (csDesigning in FComponentState) and (FOwner<>Nil) then
  315. FOwner.ValidateRename(AComponent,Curname,Newname);
  316. end;
  317. Procedure TComponent.ValidateContainer(AComponent: TComponent);
  318. begin
  319. AComponent.ValidateInsert(Self);
  320. end;
  321. Procedure TComponent.ValidateInsert(AComponent: TComponent);
  322. begin
  323. // Does nothing.
  324. end;
  325. Procedure TComponent.WriteState(Writer: TWriter);
  326. begin
  327. Writer.WriteComponentData(Self);
  328. end;
  329. Constructor TComponent.Create(AOwner: TComponent);
  330. begin
  331. FComponentStyle:=[csInheritable];
  332. If Assigned(AOwner) then AOwner.InsertComponent(Self);
  333. end;
  334. Destructor TComponent.Destroy;
  335. Var
  336. I : Integer;
  337. C : TComponent;
  338. begin
  339. Destroying;
  340. If Assigned(FFreeNotifies) then
  341. begin
  342. I:=FFreeNotifies.Count-1;
  343. While (I>=0) do
  344. begin
  345. C:=TComponent(FFreeNotifies.Items[I]);
  346. // Delete, so one component is not notified twice, if it is owned.
  347. FFreeNotifies.Delete(I);
  348. C.Notification (self,opRemove);
  349. If (FFreeNotifies=Nil) then
  350. I:=0
  351. else if (I>FFreeNotifies.Count) then
  352. I:=FFreeNotifies.Count;
  353. dec(i);
  354. end;
  355. FreeAndNil(FFreeNotifies);
  356. end;
  357. DestroyComponents;
  358. If FOwner<>Nil Then FOwner.RemoveComponent(Self);
  359. inherited destroy;
  360. end;
  361. Procedure TComponent.BeforeDestruction;
  362. begin
  363. if not(csDestroying in FComponentstate) then
  364. Destroying;
  365. end;
  366. Procedure TComponent.DestroyComponents;
  367. Var acomponent: TComponent;
  368. begin
  369. While assigned(FComponents) do
  370. begin
  371. aComponent:=TComponent(FComponents.Last);
  372. Remove(aComponent);
  373. Acomponent.Destroy;
  374. end;
  375. end;
  376. Procedure TComponent.Destroying;
  377. Var Runner : longint;
  378. begin
  379. If csDestroying in FComponentstate Then Exit;
  380. include (FComponentState,csDestroying);
  381. If Assigned(FComponents) then
  382. for Runner:=0 to FComponents.Count-1 do
  383. TComponent(FComponents.Items[Runner]).Destroying;
  384. end;
  385. function TComponent.ExecuteAction(Action: TBasicAction): Boolean;
  386. begin
  387. if Action.HandlesTarget(Self) then
  388. begin
  389. Action.ExecuteTarget(Self);
  390. Result := True;
  391. end
  392. else
  393. Result := False;
  394. end;
  395. Function TComponent.FindComponent(const AName: string): TComponent;
  396. Var I : longint;
  397. C : TComponent;
  398. begin
  399. Result:=Nil;
  400. If (AName='') or Not assigned(FComponents) then exit;
  401. For i:=0 to FComponents.Count-1 do
  402. Begin
  403. c:=TComponent(FComponents[I]);
  404. If (CompareText(C.Name,AName)=0) then
  405. Exit(C);
  406. End;
  407. end;
  408. Procedure TComponent.FreeNotification(AComponent: TComponent);
  409. begin
  410. If (Owner<>Nil) and (AComponent=Owner) then exit;
  411. If not (Assigned(FFreeNotifies)) then
  412. FFreeNotifies:=TFpList.Create;
  413. If FFreeNotifies.IndexOf(AComponent)=-1 then
  414. begin
  415. FFreeNotifies.Add(AComponent);
  416. AComponent.FreeNotification (self);
  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: CodePointer): 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: Longint;{$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: Longint;{$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;