compon.inc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  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 not (Assigned(FFreeNotifies)) then
  410. FFreeNotifies:=TFpList.Create;
  411. If FFreeNotifies.IndexOf(AComponent)=-1 then
  412. begin
  413. FFreeNotifies.Add(AComponent);
  414. AComponent.FreeNotification (self);
  415. end;
  416. end;
  417. procedure TComponent.RemoveFreeNotification(AComponent: TComponent);
  418. begin
  419. RemoveNotification(AComponent);
  420. AComponent.RemoveNotification (self);
  421. end;
  422. Procedure TComponent.FreeOnRelease;
  423. begin
  424. if Assigned(VCLComObject) then
  425. IVCLComObject(VCLComObject).FreeOnRelease;
  426. end;
  427. Function TComponent.GetParentComponent: TComponent;
  428. begin
  429. Result:=Nil;
  430. end;
  431. Function TComponent.HasParent: Boolean;
  432. begin
  433. Result:=False;
  434. end;
  435. Procedure TComponent.InsertComponent(AComponent: TComponent);
  436. begin
  437. AComponent.ValidateContainer(Self);
  438. ValidateRename(AComponent,'',AComponent.FName);
  439. Insert(AComponent);
  440. AComponent.SetReference(True);
  441. If csDesigning in FComponentState then
  442. AComponent.SetDesigning(true);
  443. Notification(AComponent,opInsert);
  444. end;
  445. Procedure TComponent.RemoveComponent(AComponent: TComponent);
  446. begin
  447. Notification(AComponent,opRemove);
  448. AComponent.SetReference(False);
  449. Remove(AComponent);
  450. Acomponent.Setdesigning(False);
  451. ValidateRename(AComponent,AComponent.FName,'');
  452. end;
  453. Function TComponent.SafeCallException(ExceptObject: TObject;
  454. ExceptAddr: CodePointer): HResult;
  455. begin
  456. if Assigned(VCLComObject) then
  457. Result := IVCLComObject(VCLComObject).SafeCallException(ExceptObject, ExceptAddr)
  458. else
  459. Result := inherited SafeCallException(ExceptObject, ExceptAddr);
  460. end;
  461. procedure TComponent.SetSubComponent(ASubComponent: Boolean);
  462. begin
  463. if ASubComponent then
  464. Include(FComponentStyle, csSubComponent)
  465. else
  466. Exclude(FComponentStyle, csSubComponent);
  467. end;
  468. function TComponent.UpdateAction(Action: TBasicAction): Boolean;
  469. begin
  470. if Action.HandlesTarget(Self) then
  471. begin
  472. Action.UpdateTarget(Self);
  473. Result := True;
  474. end
  475. else
  476. Result := False;
  477. end;
  478. function TComponent.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; out Obj): HResult;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
  479. begin
  480. if Assigned(VCLComObject) then
  481. Result := IVCLComObject(VCLComObject).QueryInterface(IID, Obj)
  482. else
  483. if GetInterface(IID, Obj) then
  484. Result := S_OK
  485. else
  486. Result := E_NOINTERFACE;
  487. end;
  488. function TComponent._AddRef: Longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
  489. begin
  490. if Assigned(VCLComObject) then
  491. Result := IVCLComObject(VCLComObject)._AddRef
  492. else
  493. Result := -1;
  494. end;
  495. function TComponent._Release: Longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
  496. begin
  497. if Assigned(VCLComObject) then
  498. Result := IVCLComObject(VCLComObject)._Release
  499. else
  500. Result := -1;
  501. end;
  502. function TComponent.iicrGetComponent: TComponent;
  503. begin
  504. result:=self;
  505. end;
  506. function TComponent.GetTypeInfoCount(out Count: Integer): HResult; stdcall;
  507. begin
  508. if Assigned(VCLComObject) then
  509. Result := IVCLComObject(VCLComObject).GetTypeInfoCount(Count)
  510. else
  511. Result := E_NOTIMPL;
  512. end;
  513. function TComponent.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
  514. begin
  515. if Assigned(VCLComObject) then
  516. Result := IVCLComObject(VCLComObject).GetTypeInfo(Index, LocaleID, TypeInfo)
  517. else
  518. Result := E_NOTIMPL;
  519. end;
  520. function TComponent.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount,
  521. LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
  522. begin
  523. if Assigned(VCLComObject) then
  524. Result := IVCLComObject(VCLComObject).GetIDsOfNames(IID, Names, NameCount, LocaleID, DispIDs)
  525. else
  526. Result := E_NOTIMPL;
  527. end;
  528. function TComponent.Invoke(DispID: Integer; const IID: TGUID;
  529. LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo,
  530. ArgErr: Pointer): HResult; stdcall;
  531. begin
  532. if Assigned(VCLComObject) then
  533. Result := IVCLComObject(VCLComObject).Invoke(DispID, IID, LocaleID, Flags, Params,
  534. VarResult, ExcepInfo, ArgErr)
  535. else
  536. Result := E_NOTIMPL;
  537. end;