compon.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. {
  2. $Id$
  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. {* TComponent *}
  13. {****************************************************************************}
  14. Type
  15. Longrec = Packed Record
  16. Hi,lo : word;
  17. end;
  18. Function TComponent.GetComponent(AIndex: Integer): TComponent;
  19. begin
  20. If not assigned(FComponents) then
  21. Result:=Nil
  22. else
  23. Result:=TComponent(FComponents.Items[Aindex]);
  24. end;
  25. Function TComponent.GetComponentCount: Integer;
  26. begin
  27. If not assigned(FComponents) then
  28. result:=0
  29. else
  30. Result:=FComponents.Count;
  31. end;
  32. Function TComponent.GetComponentIndex: Integer;
  33. begin
  34. If Assigned(FOwner) and Assigned(FOwner.FComponents) then
  35. Result:=FOWner.FComponents.IndexOf(Self)
  36. else
  37. Result:=-1;
  38. end;
  39. Procedure TComponent.Insert(AComponent: TComponent);
  40. begin
  41. If not assigned(FComponents) then
  42. FComponents:=TList.Create;
  43. FComponents.Add(AComponent);
  44. AComponent.FOwner:=Self;
  45. end;
  46. Procedure TComponent.ReadLeft(Reader: TReader);
  47. begin
  48. LongRec(FDesignInfo).Lo:=Reader.ReadInteger;
  49. end;
  50. Procedure TComponent.ReadTop(Reader: TReader);
  51. begin
  52. LongRec(FDesignInfo).Hi:=Reader.ReadInteger;
  53. end;
  54. Procedure TComponent.Remove(AComponent: TComponent);
  55. begin
  56. AComponent.FOwner:=Nil;
  57. If assigned(FCOmponents) then
  58. begin
  59. FComponents.Remove(AComponent);
  60. IF FComponents.Count=0 then
  61. begin
  62. FComponents.Free;
  63. FComponents:=Nil;
  64. end;
  65. end;
  66. end;
  67. Procedure TComponent.RemoveNotification(AComponent: TComponent);
  68. begin
  69. if FFreeNotifies<>nil then
  70. begin
  71. FFreeNotifies.Remove(AComponent);
  72. if FFreeNotifies.Count=0 then
  73. begin
  74. FFreeNotifies.Free;
  75. FFreeNotifies:=nil;
  76. Exclude(FComponentState,csFreeNotification);
  77. end;
  78. end;
  79. end;
  80. Procedure TComponent.SetComponentIndex(Value: Integer);
  81. Var Temp,Count : longint;
  82. begin
  83. If Not assigned(Fowner) then exit;
  84. Temp:=getcomponentindex;
  85. If temp<0 then exit;
  86. If value<0 then value:=0;
  87. Count:=Fowner.FComponents.Count;
  88. If Value>=Count then value:=count-1;
  89. If Value<>Temp then
  90. begin
  91. FOWner.FComponents.Delete(Temp);
  92. FOwner.FComponents.Insert(Value,Self);
  93. end;
  94. end;
  95. Procedure TComponent.SetReference(Enable: Boolean);
  96. var
  97. Field: ^TComponent;
  98. begin
  99. if Assigned(Owner) then
  100. begin
  101. Field := Owner.FieldAddress(Name);
  102. if Assigned(Field) then
  103. if Enable then
  104. Field^ := Self
  105. else
  106. Field^ := nil;
  107. end;
  108. end;
  109. Procedure TComponent.WriteLeft(Writer: TWriter);
  110. begin
  111. Writer.WriteInteger(LongRec(FDesignInfo).Lo);
  112. end;
  113. Procedure TComponent.WriteTop(Writer: TWriter);
  114. begin
  115. Writer.WriteInteger(LongRec(FDesignInfo).Hi);
  116. end;
  117. Procedure TComponent.ChangeName(const NewName: TComponentName);
  118. begin
  119. FName:=NewName;
  120. end;
  121. Procedure TComponent.DefineProperties(Filer: TFiler);
  122. Var Ancestor : TComponent;
  123. Temp : longint;
  124. begin
  125. Temp:=0;
  126. Ancestor:=TComponent(Filer.Ancestor);
  127. If Assigned(Ancestor) then Temp:=Ancestor.FDesignInfo;
  128. Filer.Defineproperty('left',@readleft,@writeleft,
  129. (longrec(FDesignInfo).Lo<>Longrec(temp).Lo));
  130. Filer.Defineproperty('top',@readtop,@writetop,
  131. (longrec(FDesignInfo).Hi<>Longrec(temp).Hi));
  132. end;
  133. Procedure TComponent.GetChildren(Proc: TGetChildProc; Root: TComponent);
  134. begin
  135. // Does nothing.
  136. end;
  137. Function TComponent.GetChildOwner: TComponent;
  138. begin
  139. Result:=Nil;
  140. end;
  141. Function TComponent.GetChildParent: TComponent;
  142. begin
  143. Result:=Self;
  144. end;
  145. Function TComponent.GetNamePath: string;
  146. begin
  147. Result:=FName;
  148. end;
  149. Function TComponent.GetOwner: TPersistent;
  150. begin
  151. Result:=FOwner;
  152. end;
  153. Procedure TComponent.Loaded;
  154. begin
  155. Exclude(FComponentState,csLoading);
  156. end;
  157. Procedure TComponent.Notification(AComponent: TComponent;
  158. Operation: TOperation);
  159. Var Runner : Longint;
  160. begin
  161. If (Operation=opRemove) and Assigned(FFreeNotifies) then
  162. begin
  163. FFreeNotifies.Remove(AComponent);
  164. If FFreeNotifies.Count=0 then
  165. begin
  166. FFreeNotifies.Free;
  167. FFreenotifies:=Nil;
  168. end;
  169. end;
  170. If assigned(FComponents) then
  171. For Runner:=0 To FComponents.Count-1 do
  172. TComponent(FComponents.Items[Runner]).Notification(AComponent,Operation);
  173. end;
  174. Procedure TComponent.ReadState(Reader: TReader);
  175. begin
  176. Reader.ReadData(Self);
  177. end;
  178. Procedure TComponent.SetAncestor(Value: Boolean);
  179. Var Runner : Longint;
  180. begin
  181. If Value then
  182. Include(FComponentState,csAncestor)
  183. else
  184. Include(FCOmponentState,csAncestor);
  185. if Assigned(FComponents) then
  186. For Runner:=0 To FComponents.Count-1 do
  187. TComponent(FComponents.Items[Runner]).SetAncestor(Value);
  188. end;
  189. Procedure TComponent.SetDesigning(Value: Boolean);
  190. Var Runner : Longint;
  191. begin
  192. If Value then
  193. Include(FComponentSTate,csDesigning)
  194. else
  195. Exclude(FComponentSTate,csDesigning);
  196. if Assigned(FComponents) then
  197. For Runner:=0 To FComponents.Count - 1 do
  198. TComponent(FComponents.items[Runner]).SetDesigning(Value);
  199. end;
  200. Procedure TComponent.SetName(const NewName: TComponentName);
  201. begin
  202. If FName=NewName then exit;
  203. If not IsValidIdent(NewName) then
  204. Raise EComponentError.CreateFmt(SInvalidName,[NewName]);
  205. If Assigned(FOwner) Then
  206. FOwner.ValidateRename(Self,FName,NewName)
  207. else
  208. ValidateRename(Nil,FName,NewName);
  209. SetReference(False);
  210. ChangeName(NewName);
  211. Setreference(True);
  212. end;
  213. Procedure TComponent.SetChildOrder(Child: TComponent; Order: Integer);
  214. begin
  215. // does nothing
  216. end;
  217. Procedure TComponent.SetParentComponent(Value: TComponent);
  218. begin
  219. // Does nothing
  220. end;
  221. Procedure TComponent.Updating;
  222. begin
  223. Include (FComponentState,csUpdating);
  224. end;
  225. Procedure TComponent.Updated;
  226. begin
  227. Exclude(FComponentState,csUpdating);
  228. end;
  229. class Procedure TComponent.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);
  230. begin
  231. // For compatibility only.
  232. end;
  233. Procedure TComponent.ValidateRename(AComponent: TComponent;
  234. const CurName, NewName: string);
  235. begin
  236. //!! This contradicts the Delphi manual.
  237. If (AComponent<>Nil) and (CurName<>NewName) and (AComponent.Owner = Self) and
  238. (FindComponent(NewName)<>Nil) then
  239. raise EComponentError.Createfmt(SDuplicateName,[newname]);
  240. If (csDesigning in FComponentState) and (FOwner<>Nil) then
  241. FOwner.ValidateRename(AComponent,Curname,Newname);
  242. end;
  243. Procedure TComponent.ValidateContainer(AComponent: TComponent);
  244. begin
  245. end;
  246. Procedure TComponent.ValidateInsert(AComponent: TComponent);
  247. begin
  248. // Does nothing.
  249. end;
  250. Procedure TComponent.WriteState(Writer: TWriter);
  251. begin
  252. Writer.WriteComponentData(Self);
  253. end;
  254. Constructor TComponent.Create(AOwner: TComponent);
  255. begin
  256. FComponentStyle:=[csInheritable];
  257. If Assigned(AOwner) then AOwner.InsertComponent(Self);
  258. end;
  259. Destructor TComponent.Destroy;
  260. Var
  261. I : Integer;
  262. C : TComponent;
  263. begin
  264. Destroying;
  265. If Assigned(FFreeNotifies) then
  266. begin
  267. I:=FFreeNotifies.Count-1;
  268. While (I>=0) do
  269. begin
  270. C:=TComponent(FFreeNotifies.Items[I]);
  271. // Delete, so one component is not notified twice, if it is owned.
  272. FFreeNotifies.Delete(I);
  273. C.Notification (self,opRemove);
  274. If (FFreeNotifies=Nil) then
  275. I:=0
  276. else if (I>FFreeNotifies.Count) then
  277. I:=FFreeNotifies.Count;
  278. dec(i);
  279. end;
  280. FreeAndNil(FFreeNotifies);
  281. end;
  282. DestroyComponents;
  283. If FOwner<>Nil Then FOwner.RemoveComponent(Self);
  284. inherited destroy;
  285. end;
  286. Procedure TComponent.BeforeDestruction;
  287. begin
  288. if not(csDestroying in FComponentstate) then
  289. Destroying;
  290. end;
  291. Procedure TComponent.DestroyComponents;
  292. Var acomponent: TComponent;
  293. begin
  294. While assigned(FComponents) do
  295. begin
  296. aComponent:=TComponent(FComponents.Last);
  297. Remove(aComponent);
  298. Acomponent.Destroy;
  299. end;
  300. end;
  301. Procedure TComponent.Destroying;
  302. Var Runner : longint;
  303. begin
  304. If csDestroying in FComponentstate Then Exit;
  305. include (FComponentState,csDestroying);
  306. If Assigned(FComponents) then
  307. for Runner:=0 to FComponents.Count-1 do
  308. TComponent(FComponents.Items[Runner]).Destroying;
  309. end;
  310. function TComponent.ExecuteAction(Action: TBasicAction): Boolean;
  311. begin
  312. if Action.HandlesTarget(Self) then
  313. begin
  314. Action.ExecuteTarget(Self);
  315. Result := True;
  316. end
  317. else
  318. Result := False;
  319. end;
  320. Function TComponent.FindComponent(const AName: string): TComponent;
  321. Var I : longint;
  322. begin
  323. Result:=Nil;
  324. If (AName='') or Not assigned(FComponents) then exit;
  325. For i:=0 to FComponents.Count-1 do
  326. if TComponent(FComponents[I]).Name=AName then
  327. begin
  328. Result:=TComponent(FComponents.Items[I]);
  329. exit;
  330. end;
  331. end;
  332. Procedure TComponent.FreeNotification(AComponent: TComponent);
  333. begin
  334. If (Owner<>Nil) and (AComponent=Owner) then exit;
  335. if csDestroying in ComponentState then
  336. AComponent.Notification(Self,opRemove)
  337. else
  338. begin
  339. If not (Assigned(FFreeNotifies)) then
  340. FFreeNotifies:=TList.Create;
  341. If FFreeNotifies.IndexOf(AComponent)=-1 then
  342. begin
  343. FFreeNotifies.Add(AComponent);
  344. AComponent.FreeNotification (self);
  345. end;
  346. end;
  347. end;
  348. procedure TComponent.RemoveFreeNotification(AComponent: TComponent);
  349. begin
  350. RemoveNotification(AComponent);
  351. AComponent.RemoveNotification (self);
  352. end;
  353. Procedure TComponent.FreeOnRelease;
  354. begin
  355. // Delphi compatibility only at the moment.
  356. end;
  357. Function TComponent.GetParentComponent: TComponent;
  358. begin
  359. Result:=Nil;
  360. end;
  361. Function TComponent.HasParent: Boolean;
  362. begin
  363. Result:=False;
  364. end;
  365. Procedure TComponent.InsertComponent(AComponent: TComponent);
  366. begin
  367. AComponent.ValidateContainer(Self);
  368. ValidateRename(AComponent,'',AComponent.FName);
  369. Insert(AComponent);
  370. AComponent.SetReference(True);
  371. If csDesigning in FComponentState then
  372. AComponent.SetDesigning(true);
  373. Notification(AComponent,opInsert);
  374. end;
  375. Procedure TComponent.RemoveComponent(AComponent: TComponent);
  376. begin
  377. Notification(AComponent,opRemove);
  378. AComponent.SetReference(False);
  379. Remove(AComponent);
  380. Acomponent.Setdesigning(False);
  381. ValidateRename(AComponent,AComponent.FName,'');
  382. end;
  383. Function TComponent.SafeCallException(ExceptObject: TObject;
  384. ExceptAddr: Pointer): Integer;
  385. begin
  386. SafeCallException:=0;
  387. end;
  388. function TComponent.UpdateAction(Action: TBasicAction): Boolean;
  389. begin
  390. if Action.HandlesTarget(Self) then
  391. begin
  392. Action.UpdateTarget(Self);
  393. Result := True;
  394. end
  395. else
  396. Result := False;
  397. end;
  398. {
  399. $Log$
  400. Revision 1.5 2004-09-22 19:57:45 michael
  401. + More optimal FreeNotification when destroying
  402. Revision 1.4 2004/09/22 18:48:31 michael
  403. + Fix in TComponent destroy FreeNotifications.
  404. Revision 1.3 2004/08/07 16:44:35 florian
  405. * tcomponent.destroying is now called in tcomponent.beforedestruction
  406. Revision 1.2 2004/01/12 17:44:22 peter
  407. * LongRec is a packed record
  408. Revision 1.1 2003/10/06 21:01:06 peter
  409. * moved classes unit to rtl
  410. Revision 1.9 2003/04/27 21:16:11 sg
  411. * Fixed TComponent.ValidateRename
  412. Revision 1.8 2002/10/15 20:06:19 michael
  413. + Fixed SetAncestor. Index was getting too big
  414. Revision 1.7 2002/09/07 15:15:24 peter
  415. * old logs removed and tabs fixed
  416. Revision 1.6 2002/01/09 10:40:24 michael
  417. + re-enabled Top/Left property writing
  418. Revision 1.5 2002/01/06 21:54:50 peter
  419. * action classes added
  420. }