IdRegisterCore.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. {
  2. $Project$
  3. $Workfile$
  4. $Revision$
  5. $DateUTC$
  6. $Id$
  7. This file is part of the Indy (Internet Direct) project, and is offered
  8. under the dual-licensing agreement described on the Indy website.
  9. (http://www.indyproject.org/)
  10. Copyright:
  11. (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
  12. }
  13. {
  14. $Log$
  15. }
  16. {
  17. Rev 1.1 2/8/2004 1:35:40 PM JPMugaas
  18. IdSocks is now in DotNET.
  19. Rev 1.0 2/3/2004 12:28:06 PM JPMugaas
  20. Kudzu wanted this renamed.
  21. Rev 1.27 2004.01.01 2:40:02 PM czhower
  22. Removed test ifdef
  23. Rev 1.26 1/1/2004 3:32:30 PM BGooijen
  24. Added icons for .Net
  25. Rev 1.25 2003.12.31 11:02:50 PM czhower
  26. New components now registered for .net.
  27. Rev 1.24 2003.12.25 6:55:20 PM czhower
  28. TCPServer
  29. Rev 1.23 11/22/2003 11:49:52 PM BGooijen
  30. Icons for DotNet
  31. Rev 1.22 17/11/2003 16:00:22 ANeillans
  32. Fix Delphi compile errors.
  33. Rev 1.21 11/8/2003 8:09:24 PM BGooijen
  34. fix, i mixed up some stuff
  35. Rev 1.20 11/8/2003 7:27:10 PM BGooijen
  36. DotNet
  37. Rev 1.19 2003.10.19 1:35:32 PM czhower
  38. Moved Borland define to .inc
  39. Rev 1.18 2003.10.18 11:32:42 PM czhower
  40. Changed throttler to intercept
  41. Rev 1.17 2003.10.17 6:18:50 PM czhower
  42. TIdInterceptSimLog
  43. Rev 1.16 2003.10.14 1:26:42 PM czhower
  44. Uupdates + Intercept support
  45. Rev 1.15 9/21/2003 01:10:40 AM JPMugaas
  46. Added IdThreadCOmponent to the registration in Core.
  47. Rev 1.14 2003.08.19 11:06:34 PM czhower
  48. Fixed names of scheduler units.
  49. Rev 1.13 8/19/2003 01:25:08 AM JPMugaas
  50. Unnecessary junk removed.
  51. Rev 1.12 8/15/2003 12:02:48 AM JPMugaas
  52. Incremented version number.
  53. Moved some units to new IndySuperCore package in D7.
  54. Made sure package titles are uniform in the IDE and in the .RES files.
  55. Rev 1.11 7/24/2003 03:22:00 AM JPMugaas
  56. Removed some old files.
  57. Rev 1.10 7/18/2003 4:33:12 PM SPerry
  58. Added TIdCmdTCPClient
  59. Rev 1.7 4/17/2003 05:02:26 PM JPMugaas
  60. Rev 1.6 4/11/2003 01:09:50 PM JPMugaas
  61. Rev 1.5 3/25/2003 11:12:54 PM BGooijen
  62. TIdChainEngineStack added.
  63. Rev 1.4 3/25/2003 05:02:00 PM JPMugaas
  64. TCmdTCPServer added.
  65. Rev 1.3 3/22/2003 10:14:54 PM BGooijen
  66. Added TIdServerIOHandlerChain to the palette
  67. Rev 1.2 3/22/2003 02:20:48 PM JPMugaas
  68. Updated registration.
  69. Rev 1.1 1/17/2003 04:18:44 PM JPMugaas
  70. Now compiles with new packages.
  71. Rev 1.0 11/13/2002 08:41:42 AM JPMugaas
  72. }
  73. unit IdRegisterCore;
  74. interface
  75. // Procedures
  76. procedure Register;
  77. implementation
  78. {$I IdCompilerDefines.inc}
  79. uses
  80. Classes,
  81. {$IFDEF FMX}
  82. Controls,
  83. {$ENDIF}
  84. {$IFDEF FPC}
  85. LResources,
  86. {$ENDIF}
  87. IdSocks,
  88. {$IFDEF HAS_TSelectionEditor}
  89. {$IFDEF FPC}
  90. PropEdits,
  91. ComponentEditors,
  92. {$ELSE}
  93. DesignIntf,
  94. DesignEditors,
  95. {$ENDIF}
  96. TypInfo,
  97. {$IFDEF DCC_2010_OR_ABOVE}
  98. Rtti,
  99. {$ENDIF}
  100. SysUtils,
  101. IdGlobal,
  102. {$ENDIF}
  103. {$IFDEF HAS_TSelectionEditor}
  104. IdBaseComponent,
  105. {$ENDIF}
  106. IdComponent,
  107. IdDsnCoreResourceStrings,
  108. IdAntiFreeze,
  109. IdCmdTCPClient,
  110. IdCmdTCPServer,
  111. IdIOHandlerStream,
  112. IdIcmpClient,
  113. IdInterceptSimLog,
  114. IdInterceptThrottler,
  115. IdIPMCastClient,
  116. IdIPMCastServer,
  117. IdLogDebug,
  118. IdLogEvent,
  119. IdLogFile,
  120. IdLogStream,
  121. IdSchedulerOfThreadDefault,
  122. IdSchedulerOfThreadPool,
  123. IdServerIOHandlerStack,
  124. IdSimpleServer,
  125. IdThreadComponent,
  126. IdTraceRoute,
  127. IdUDPClient,
  128. IdUDPServer,
  129. IdIOHandlerStack,
  130. IdIntercept,
  131. IdTCPServer,
  132. IdTCPClient;
  133. {$IFNDEF FPC}
  134. {$IFDEF BORLAND}
  135. {$R IdCoreRegister.dcr}
  136. {$ELSE}
  137. {$R IdCoreRegisterCool.dcr}
  138. {$ENDIF}
  139. {$ENDIF}
  140. {$IFDEF HAS_TSelectionEditor}
  141. // TIdComponentSelectionEditor is called at design-time when saving/compiling a
  142. // project. It enumerates the data types of all parameters and return values of
  143. // every event handler assigned to any Indy component, extracting the unit names
  144. // of those data types and passing them to the IDE so it can insert them into
  145. // 'uses' clauses as needed.
  146. procedure SendUnitNameToProc(const AUnitName: String; Proc: TGetStrProc);
  147. begin
  148. // Do not return the 'System' unit, otherwise it will
  149. // cause an "Identifier redeclared" compiler error!
  150. if (AUnitName <> '') and (not TextIsSame(AUnitName, 'System')) then begin {do not localize}
  151. Proc(AUnitName);
  152. end;
  153. end;
  154. {$IFDEF DCC_XE2_OR_ABOVE}
  155. // in Delphi XE2 and later, TRttiInvokableType is used to enumerate parameters
  156. // and return values, and TRttiType reports fully qualified type names, so
  157. // finding a given type's unit name is very easy...
  158. function GetUnitNameForType(const AType: TRttiType): String;
  159. begin
  160. // TRttiParameter.ParamType may be nil if it's an untyped var or const parameter...
  161. // TRttiMethodType.ReturnType may be nil if it's a procedure...
  162. if AType <> nil then begin
  163. // TRttiType.UnitName returns the unit that declares TRttiType itself
  164. // (System.Rtti), so parse the TRttiType.QualifiedName value instead...
  165. Result := AType.QualifiedName;
  166. SetLength(Result, Length(Result) - Length(AType.Name) - 1);
  167. end else begin
  168. Result := '';
  169. end;
  170. end;
  171. {$ELSE}
  172. // in Delphi prior to XE2, as well as in FreePascal, TRttiInvokableType is not
  173. // available, so we have to use TypInfo RTTI to enumerating parameters and
  174. // return values, but only certain versions implement rich enough RTTI to allow
  175. // that. Let's try to pull out what we can...
  176. {$IF DEFINED(FPC) OR DEFINED(DCC_2010_OR_ABOVE)}
  177. {$DEFINE HAS_tkMethod_ParamTypeInfo}
  178. {$IFEND}
  179. procedure SkipShortString(var P: PByte);
  180. begin
  181. Inc(P, 1 + Integer(P^));
  182. end;
  183. function ReadShortString(var P: PByte): String;
  184. begin
  185. {$IFDEF DCC}
  186. Result := UTF8ToString(PShortString(P)^);
  187. {$ELSE}
  188. Result := PShortString(P)^;
  189. {$ENDIF}
  190. SkipShortString(P);
  191. end;
  192. {$IFDEF FPC}
  193. function NextShortString(PS: PShortString): PShortString;
  194. begin
  195. Result := PShortString(Pointer(PS)+PByte(PS)^+1);
  196. end;
  197. {$ENDIF}
  198. function GetUnitNameFromTypeName(const ATypeName: String): String;
  199. var
  200. K: Integer;
  201. begin
  202. // check if the type is qualified
  203. K := LastDelimiter('.', ATypeName);
  204. if K <> 0 then begin
  205. Result := Copy(ATypeName, 1, K-1);
  206. end else begin
  207. // TODO: enumerate package units and find the typename...
  208. Result := '';
  209. end;
  210. end;
  211. function GetUnitNameFromTypeInfo(const ATypeInfo: PPTypeInfo): String;
  212. var
  213. LTypeData: PTypeData;
  214. {$IFDEF FPC}
  215. PS, PSLast: PShortString;
  216. {$ELSE}
  217. LBaseTypeData: PTypeData;
  218. Value: Integer;
  219. P: PByte;
  220. {$ENDIF}
  221. begin
  222. Result := '';
  223. if ATypeInfo = nil then begin
  224. Exit;
  225. end;
  226. if ATypeInfo^ = nil then begin
  227. Exit;
  228. end;
  229. LTypeData := GetTypeData(ATypeInfo^);
  230. case ATypeInfo^.Kind of
  231. tkEnumeration: begin
  232. {$IFDEF FPC}
  233. // the unit name is the last string in the name list
  234. PS := @(LTypeData^.NameList);
  235. PSLast := nil;
  236. while PByte(PS)^ <> 0 do begin
  237. PSLast := PS;
  238. PS := NextShortString(PS);
  239. end;
  240. if PSLast <> nil then begin
  241. Result := PSLast^;
  242. end;
  243. {$ELSE}
  244. // the unit name follows after the name list
  245. LBaseTypeData := GetTypeData(LTypeData^.BaseType^);
  246. P := PByte(@(LBaseTypeData^.NameList));
  247. // LongBool/WordBool/ByteBool have MinValue < 0 and arbitrary
  248. // content in Value; Boolean has Value in [0, 1] }
  249. if (ATypeInfo^ = System.TypeInfo(Boolean)) or (LBaseTypeData^.MinValue < 0) then
  250. begin
  251. for Value := 0 to 1 do begin
  252. SkipShortString(P);
  253. end;
  254. end else
  255. begin
  256. for Value := LBaseTypeData^.MinValue to LBaseTypeData^.MaxValue do begin
  257. SkipShortString(P);
  258. end;
  259. end;
  260. Result := ReadShortString(P);
  261. {$ENDIF}
  262. end;
  263. tkSet: begin
  264. Result := GetUnitNameFromTypeInfo(LTypeData^.CompType);
  265. end;
  266. tkClass: begin
  267. {$IFDEF DCC}
  268. Result := UTF8ToString(LTypeData^.UnitName);
  269. {$ELSE}
  270. Result := LTypeData^.UnitName;
  271. {$ENDIF}
  272. end;
  273. {$IFDEF FPC}
  274. tkHelper: begin
  275. Result := LTypeData^.HelperUnit;
  276. end;
  277. {$ENDIF}
  278. tkInterface: begin
  279. {$IFDEF DCC}
  280. Result := UTF8ToString(LTypeData^.IntfUnit);
  281. {$ELSE}
  282. Result := LTypeData^.IntfUnit;
  283. {$ENDIF}
  284. end;
  285. {$IFDEF FPC}
  286. tkInterfaceRaw: begin
  287. Result := LTypeData^.RawIntfUnit;
  288. end;
  289. tkDynArray: begin
  290. {$IFDEF DCC}
  291. Result := UTF8ToString(LTypeData^.DynUnitName);
  292. {$ELSE}
  293. Result := LTypeData^.DynUnitName;
  294. {$ENDIF}
  295. if Result = '' then begin
  296. Result := GetUnitNameFromTypeInfo(LTypeData^.elType2);
  297. end;
  298. end;
  299. end;
  300. end;
  301. procedure GetUnitNamesForMethodType(const ATypeInfo: PTypeInfo; Proc: TGetStrProc);
  302. type
  303. PPPTypeInfo = ^PPTypeInfo;
  304. var
  305. LTypeData: PTypeData;
  306. LTypeDataPtr: PByte;
  307. K: Integer;
  308. UnitName: string;
  309. begin
  310. if ATypeInfo = nil then begin
  311. Exit;
  312. end;
  313. LTypeData := GetTypeData(ATypeInfo);
  314. LTypeDataPtr := PByte(@(LTypeData^.ParamList));
  315. if LTypeData^.ParamCount > 0 then
  316. begin
  317. for K := 0 to LTypeData^.ParamCount-1 do
  318. begin
  319. Inc(LTypeDataPtr, SizeOf(TParamFlags));
  320. SkipShortString(LTypeDataPtr);
  321. {$IFDEF HAS_tkMethod_ParamTypeInfo}
  322. // handled further below...
  323. SkipShortString(LTypeDataPtr);
  324. {$ELSE}
  325. UnitName := GetUnitNameFromTypeName(ReadShortString(LTypeDataPtr));
  326. SendUnitNameToProc(UnitName, Proc);
  327. {$ENDIF}
  328. end;
  329. end;
  330. if LTypeData^.MethodKind = mkFunction then
  331. begin
  332. {$IFDEF HAS_tkMethod_ParamTypeInfo}
  333. SkipShortString(LTypeDataPtr);
  334. UnitName := GetUnitNameFromTypeInfo(PPPTypeInfo(LTypeDataPtr)^);
  335. Inc(LTypeDataPtr, SizeOf(PPTypeInfo));
  336. {$ELSE}
  337. UnitName := GetUnitNameFromTypeName(ReadShortString(LTypeDataPtr));
  338. {$ENDIF}
  339. SendUnitNameToProc(UnitName, Proc);
  340. end;
  341. {$IFDEF HAS_tkMethod_ParamTypeInfo}
  342. if LTypeData^.ParamCount > 0 then
  343. begin
  344. Inc(LTypeDataPtr, SizeOf(TCallConv));
  345. for K := 0 to LTypeData^.ParamCount-1 do
  346. begin
  347. UnitName := GetUnitNameFromTypeInfo(PPPTypeInfo(LTypeDataPtr)^);
  348. SendUnitNameToProc(UnitName, Proc);
  349. Inc(LTypeDataPtr, SizeOf(PPTypeInfo));
  350. end;
  351. end;
  352. {$ENDIF}
  353. end;
  354. {$ENDIF}
  355. type
  356. TIdBaseComponentSelectionEditor = class(TSelectionEditor)
  357. public
  358. procedure RequiresUnits(Proc: TGetStrProc); override;
  359. end;
  360. procedure TIdBaseComponentSelectionEditor.RequiresUnits(Proc: TGetStrProc);
  361. var
  362. Comp: TIdBaseComponent;
  363. I: Integer;
  364. {$IFDEF DCC_2010_OR_ABOVE}
  365. Ctx: TRttiContext;
  366. RetreivedCtx: Boolean;
  367. PropInfo: TRttiProperty;
  368. PropValue: TValue;
  369. {$IFDEF DCC_XE2_OR_ABOVE}
  370. PropType: TRttiMethodType;
  371. Param: TRttiParameter;
  372. {$ENDIF}
  373. {$ELSE}
  374. PropList: PPropList;
  375. PropCount: Integer;
  376. PropInfo: PPropInfo;
  377. J: Integer;
  378. {$ENDIF}
  379. begin
  380. inherited RequiresUnits(Proc);
  381. if (Designer = nil) or (Designer.Root = nil) then Exit;
  382. {$IFDEF DCC_2010_OR_ABOVE}
  383. RetreivedCtx := False;
  384. {$ENDIF}
  385. for I := 0 to Designer.Root.ComponentCount - 1 do
  386. begin
  387. if Designer.Root.Components[i] is TIdBaseComponent then
  388. begin
  389. Comp := TIdBaseComponent(Designer.Root.Components[i]);
  390. {$IFDEF DCC_2010_OR_ABOVE}
  391. if not RetreivedCtx then
  392. begin
  393. Ctx := TRttiContext.Create;
  394. RetreivedCtx := True;
  395. end;
  396. for PropInfo in Ctx.GetType(Comp.ClassType).GetProperties do
  397. begin
  398. // only interested in *assigned* event handlers
  399. // NOTE: Delphi 2010 has a problem with checking the TValue.IsEmpty
  400. // property inlined like below. It causes a "F2084 Internal Error C13394"
  401. // compiler error. So splitting up the comparison to use a local TValue
  402. // variable to work around that...
  403. {
  404. if (PropInfo.PropertyType.TypeKind = tkMethod) and
  405. (not PropInfo.GetValue(Comp).IsEmpty) then
  406. }
  407. if PropInfo.PropertyType.TypeKind = tkMethod then
  408. begin
  409. PropValue := PropInfo.GetValue(Comp);
  410. if not PropValue.IsEmpty then
  411. begin
  412. // although the System.Rtti unit was introduced in Delphi 2010,
  413. // the TRttiInvokableType class was not added to it until XE2
  414. {$IFDEF DCC_XE2_OR_ABOVE}
  415. PropType := PropInfo.PropertyType as TRttiMethodType;
  416. for Param in PropType.GetParameters do begin
  417. SendUnitNameToProc(GetUnitNameForType(Param.ParamType), Proc);
  418. end;
  419. SendUnitNameToProc(GetUnitNameForType(PropType.ReturnType), Proc);
  420. {$ELSE}
  421. // use the System.TypInfo unit to access the parameters and return type
  422. GetUnitNamesForMethodType(PropInfo.PropertyType.Handle, Proc);
  423. {$ENDIF}
  424. end;
  425. end;
  426. end;
  427. {$ELSE}
  428. PropCount := GetPropList(Comp, PropList);
  429. if PropCount > 0 then
  430. begin
  431. try
  432. for J := 0 to PropCount-1 do
  433. begin
  434. PropInfo := PropList^[J];
  435. // only interested in *assigned* event handlers
  436. if (PropInfo^.PropType^.Kind = tkMethod) and
  437. (GetMethodProp(Comp, PropInfo).Code <> nil) then
  438. begin
  439. GetUnitNamesForMethodType(PropInfo^.PropType^, Proc);
  440. end;
  441. end;
  442. finally
  443. FreeMem(PropList);
  444. end;
  445. end;
  446. {$ENDIF}
  447. end;
  448. end;
  449. end;
  450. {$ENDIF}
  451. procedure Register;
  452. begin
  453. {$IFNDEF FPC}
  454. RegisterComponents(RSRegIndyClients, [
  455. TIdTCPClient
  456. ,TIdUDPClient
  457. ,TIdCmdTCPClient
  458. ,TIdIPMCastClient
  459. ,TIdIcmpClient
  460. ,TIdTraceRoute
  461. ]);
  462. RegisterComponents(RSRegIndyServers, [
  463. TIdUDPServer,
  464. TIdCmdTCPServer,
  465. TIdSimpleServer,
  466. TIdTCPServer,
  467. TIdIPMCastServer
  468. ]);
  469. RegisterComponents(RSRegIndyIOHandlers,[
  470. TIdIOHandlerStack
  471. ,TIdIOHandlerStream
  472. ,TIdServerIOHandlerStack
  473. ]);
  474. RegisterComponents(RSRegIndyIntercepts, [
  475. TIdConnectionIntercept
  476. ,TIdInterceptSimLog
  477. ,TIdInterceptThrottler
  478. ,TIdLogDebug
  479. ,TIdLogEvent
  480. ,TIdLogFile
  481. ,TIdLogStream
  482. ]);
  483. {$IFDEF FMX}
  484. // RLebeau 8/1/2011 - FireMonkey has problems resolving references to
  485. // TIdAntiFreeze correctly because it is implemented in a design-time
  486. // package and not a run-time package. Until we can fix that properly,
  487. // we'll group TIdAntiFreeze with TControl so the IDE can filter out
  488. // TIdAntiFreeze from appearing at design-time in FireMoney projects.
  489. // Users will have to instantiate TIdAntiFreeze in code. This does not
  490. // affect VCL projects.
  491. GroupDescendentsWith(TIdAntiFreeze, TControl);
  492. {$ENDIF}
  493. RegisterComponents(RSRegIndyMisc, [
  494. TIdSocksInfo,
  495. TIdAntiFreeze,
  496. TIdSchedulerOfThreadDefault,
  497. TIdSchedulerOfThreadPool,
  498. TIdThreadComponent
  499. ]);
  500. {$ELSE}
  501. //This is a tempoary workaround for components not fitting on the palette
  502. //in Lazarus. Unlike Delphi, Lazarus still does not have the ability to
  503. //scroll through a palette page.
  504. RegisterComponents(RSRegIndyClients+CoreSuffix, [
  505. TIdTCPClient
  506. ,TIdUDPClient
  507. ,TIdCmdTCPClient
  508. ,TIdIPMCastClient
  509. ,TIdIcmpClient
  510. ,TIdTraceRoute
  511. ]);
  512. RegisterComponents(RSRegIndyServers+CoreSuffix, [
  513. TIdUDPServer,
  514. TIdCmdTCPServer,
  515. TIdSimpleServer,
  516. TIdTCPServer,
  517. TIdIPMCastServer
  518. ]);
  519. RegisterComponents(RSRegIndyIOHandlers+CoreSuffix,[
  520. TIdIOHandlerStack
  521. ,TIdIOHandlerStream
  522. ,TIdServerIOHandlerStack
  523. ]);
  524. RegisterComponents(RSRegIndyIntercepts+CoreSuffix, [
  525. TIdConnectionIntercept
  526. ,TIdInterceptSimLog
  527. ,TIdInterceptThrottler
  528. ,TIdLogDebug
  529. ,TIdLogEvent
  530. ,TIdLogFile
  531. ,TIdLogStream
  532. ]);
  533. RegisterComponents(RSRegIndyMisc+CoreSuffix, [
  534. TIdSocksInfo,
  535. TIdAntiFreeze,
  536. TIdSchedulerOfThreadDefault,
  537. TIdSchedulerOfThreadPool,
  538. TIdThreadComponent
  539. ]);
  540. {$ENDIF}
  541. {$IFDEF HAS_TSelectionEditor}
  542. RegisterSelectionEditor(TIdBaseComponent, TIdBaseComponentSelectionEditor);
  543. {$ENDIF}
  544. end;
  545. {$IFDEF FPC}
  546. initialization
  547. {$i IdRegisterCore.lrs}
  548. {$ENDIF}
  549. end.