powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Вопрос к спецам по RTTI
25 сообщений из 41, страница 1 из 2
Вопрос к спецам по RTTI
    #32129892
Фотография maloi_alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как вызвать метод по имени, да еще и передать в него какие нибудь параметры, и можно ли вообще такое сделать ?
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129896
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Как вызвать метод по имени, да еще и передать в него какие нибудь параметры, и можно ли вообще такое сделать ?

Слушай, а по подробней нельзя. Вызов SomeObject.SomeMethod(SomeParam) разве не вызов по имени.
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129901
StarWind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
???
странный вопрос......

Form1.Update

чем не вызов метода? Ах да, нужно передать параметры...
Canvas.LineTo(X, Y) устраивает? да и причем тут RTTI?
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129902
Фотография maloi_alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я имею в виду в runtime
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129906
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Я имею в виду в runtime

Да напиши, что сделать то хочешь, а то RTTI сразу!
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129907
Фотография maloi_alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В смысле есть имя имя метода (строка) и есть параметры (всякие), т.е. хочу узнать как в runtime вызвать метод, зная его имя.
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129913
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>В смысле есть имя имя метода (строка) и есть параметры (всякие)

И откедова они у тебя нарисовались.:-)

Ты можешь по-русски задачу обрисовать. Типа, есть яблоко, как мне его поделить на 2 части.
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129915
StarWind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
у тебя имя метода в виде текстовой тврочки поступает из вне?
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129917
Фотография maloi_alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну например :

const

s: string = 'Show';

и есть форма Form1 у которой есть метод Show
короче, можно ли как нибудь получить точку входа метода 'Show' а затем вызвать вызвать, да еще и передать ему какие-нибудь параметры ?
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129920
StarWind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пиши парсер на свою строку....
в общем случае....
или в простейшем

if s = 'Show' then form1.show;
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129929
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну например :

const

s: string = 'Show';

и есть форма Form1 у которой есть метод Show
короче, можно ли как нибудь получить точку входа метода 'Show' а затем вызвать вызвать, да еще и передать ему какие-нибудь параметры ?


Ты меня никак не поймешь, ты можешь задачу описать, абстрагировавшись от методов и их имен. Какую задачу ты таким извращенным способом хочешь решить???
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129967
Фотография maloi_alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Постараюсь описать поподробней.
Суть в следующем: пишу класс, который позволяет исполнят код Visual Foxpro в программах на Delphi. Передаешь в него Self формы и дальше из FoxPro можно обращаться к свойствам и методам компонентов расположенным на форме. Для того чтобы все это работало нужно преобразовать класс TPersistent в IDispatch, и передать его в Фокс потому что с TPersistent Фокс работать явно не умеет, а вот IDispatch работает за милую душу. Дальше нужно в Invoke этого IDispatch по имени метода получить указатель точку входа в этод метод, как нибудь передать ему параметры, ну и вызвать его наконец.

Вообще, если довести это дело до конца, получиться отличная вещь.
Пока мой класс может работать только со свойствами компонентов
Например сейчас такой Фоксовский код работает без проблем:

Код: plaintext
1.
2.
3.
Self.Caption = "Сегодня: " +DTOC(DATE))
SCAN
   Edit1.Text = STR(RECNO())
ENDSCAN


и т.п.

А вот как работать с методами компонентов, я сейчас и пытаюсь узнать.

Кстати приглашаю всех желающих присоединиться к проекте.
В проекте я использовал код из статьи http://docs.gets.ru/read.html?id=1231

Выкладываю исходники, а то одному как-то скучно этим заниматься.
Исходники VFP COM сервера могу намилить желающим.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.
670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
684.
685.
686.
687.
688.
689.
690.
691.
692.
693.
694.
695.
696.
697.
698.
699.
700.
701.
702.
703.
704.
705.
706.
707.
708.
709.
710.
711.
712.
713.
714.
715.
716.
717.
718.
719.
720.
721.
722.
723.
724.
725.
726.
727.
728.
729.
730.
731.
732.
733.
734.
735.
736.
737.
738.
739.
740.
741.
742.
743.
744.
745.
746.
747.
748.
749.
750.
751.
752.
753.
754.
755.
756.
757.
758.
759.
760.
761.
762.
763.
764.
765.
766.
767.
768.
769.
770.
771.
772.
773.
774.
775.
776.
777.
778.
779.
780.
781.
782.
783.
784.
785.
786.
787.
788.
789.
790.
791.
792.
793.
794.
795.
796.
797.
798.
799.
800.
801.
802.
803.
804.
805.
806.
807.
808.
809.
810.
811.
812.
813.
814.
815.
816.
817.
818.
819.
820.
821.
822.
823.
824.
825.
826.
827.
828.
829.
830.
831.
832.
833.
834.
835.
836.
837.
838.
839.
840.
841.
842.
843.
844.
845.
846.
847.
848.
849.
850.
851.
852.
853.
854.
855.
856.
857.
858.
859.
860.
861.
862.
863.
864.
865.
866.
867.
868.
869.
870.
871.
872.
873.
874.
875.
876.
877.
878.
879.
880.
881.
882.
883.
884.
885.
886.
887.
888.
889.
890.
891.
892.
893.
894.
895.
896.
897.
898.
899.
900.
901.
902.
903.
904.
905.
906.
907.
908.
909.
910.
911.
912.
913.
914.
915.
916.
917.
918.
919.
920.
921.
922.
923.
924.
925.
926.
927.
928.
929.
930.
931.
932.
933.
934.
935.
936.
937.
938.
939.
940.
941.
942.
943.
944.
945.
946.
947.
948.
949.
950.
951.
952.
953.
954.
955.
956.
957.
958.
959.
960.
961.
962.
963.
964.
965.
966.
967.
968.
969.
970.
971.
972.
973.
974.
975.
976.
977.
978.
979.
980.
981.
982.
983.
984.
985.
986.
987.
988.
989.
990.
991.
992.
993.
994.
995.
996.
997.
998.
999.
1000.
1001.
1002.
1003.
1004.
1005.
1006.
1007.
1008.
1009.
1010.
1011.
1012.
1013.
1014.
1015.
1016.
1017.
1018.
1019.
1020.
1021.
1022.
1023.
1024.
1025.
1026.
1027.
1028.
1029.
1030.
1031.
1032.
1033.
1034.
1035.
1036.
1037.
1038.
1039.
1040.
1041.
1042.
1043.
1044.
1045.
1046.
1047.
1048.
1049.
1050.
1051.
1052.
1053.
1054.
1055.
1056.
1057.
1058.
1059.
1060.
1061.
1062.
1063.
1064.
1065.
1066.
1067.
1068.
1069.
1070.
1071.
1072.
1073.
1074.
1075.
1076.
1077.
1078.
1079.
1080.
1081.
1082.
1083.
1084.
1085.
1086.
1087.
1088.
1089.
1090.
1091.
1092.
1093.
1094.
1095.
1096.
1097.
1098.
1099.
1100.
1101.
1102.
1103.
1104.
1105.
1106.
1107.
1108.
1109.
1110.
1111.
1112.
1113.
1114.
1115.
1116.
1117.
1118.
1119.
1120.
1121.
1122.
1123.
1124.
1125.
1126.
1127.
1128.
1129.
unit VclProxyDisp;

interface

uses Classes, TypInfo, ComObj, Variants, ActiveX, SysUtils, Controls, Windows,
     Contnrs, Forms, Graphics, dialogs, vfp7serv_TLB;

type
     TVCLProxy = class;
     TVFPConnector = class;

     IEnumVariant = interface(IUnknown)
     ['{00020404-0000-0000-C000-000000000046}']
     function Next(celt: LongWord; var rgvar: OleVariant;
       pceltFetched: PLongWord): HResult; stdcall;
     function Skip(celt: LongWord): HResult; stdcall;
     function Reset: HResult; stdcall;
     function Clone(out Enum: IEnumVariant): HResult; stdcall;
   end;  


   IQueryPersistent = interface
  ['{26F5B6E1-9DA5-11D3-BCAD-00902759A497}']
      function GetPersistent: TPersistent;
   end;

  TDispIDsArray = array[ 0 .. 0 ] of TDISPID;
  PDispIDsArray = ^TDispIDsArray;
  TVariantList = array [ 0 .. 0 ] of OleVariant;

  TTypeCompStub = class(TinterfacedObject, iTypeComp)
     private
     FOwner: TVCLProxy;
     public
     constructor Create(AOwner: TVCLProxy);
     function Bind(szName: POleStr; lHashVal: Longint; wflags: Word;
        out tinfo: ITypeInfo; out desckind: TDescKind;
        out bindptr: TBindPtr): HResult; stdcall;
     function BindType(szName: POleStr; lHashVal: Longint;
        out tinfo: ITypeInfo; out tcomp: ITypeComp): HResult;stdcall;
  end;

  TNamedItemList = class(TObjectList)
    private
    FConnector: TVFPConnector;
  public
    constructor Create(Connector: TVFPConnector);
    procedure AddItem(const Name: string; Item: IDispatch);
    function GetItemIDispatch(const Name: string): IDispatch;
    function FindItem(Item: string): IDispatch;
    procedure Clear; override;
  end;

  TNamedItem = class
  protected
    FTypeInfo: ITypeInfo;
    FDispatch: IDispatch;
    FName: string;
  end;

  TTypeinfoPlug = class(TinterfacedObject, iTypeinfo)
    private
      FClassNameStr: WideString;
      FOwner: TVCLProxy;
    public
    function GetTypeAttr(out ptypeattr: PTypeAttr): HResult; stdcall;
    function GetTypeComp(out tcomp: ITypeComp): HResult; stdcall;
    function GetFuncDesc(index: Integer; out pfuncdesc: PFuncDesc): HResult;
      stdcall;
    function GetVarDesc(index: Integer; out pvardesc: PVarDesc): HResult;
      stdcall;
    function GetNames(memid: TMemberID; rgbstrNames: PBStrList;
      cMaxNames: Integer; out cNames: Integer): HResult; stdcall;
    function GetRefTypeOfImplType(index: Integer; out reftype: HRefType): HResult;
      stdcall;
    function GetImplTypeFlags(index: Integer; out impltypeflags: Integer): HResult;
      stdcall;
    function GetIDsOfNames(rgpszNames: POleStrList; cNames: Integer;
      rgmemid: PMemberIDList): HResult; stdcall;
    function Invoke(pvInstance: Pointer; memid: TMemberID; flags: Word;
      var dispParams: TDispParams; varResult: PVariant;
      excepInfo: PExcepInfo; argErr: PInteger): HResult; stdcall;
    function GetDocumentation(memid: TMemberID; pbstrName: PWideString;
      pbstrDocString: PWideString; pdwHelpContext: PLongint;
      pbstrHelpFile: PWideString): HResult; stdcall;
    function GetDllEntry(memid: TMemberID; invkind: TInvokeKind;
      bstrDllName, bstrName: PWideString; wOrdinal: PWord): HResult;
      stdcall;
    function GetRefTypeInfo(reftype: HRefType; out tinfo: ITypeInfo): HResult;
      stdcall;
    function AddressOfMember(memid: TMemberID; invkind: TInvokeKind;
      out ppv: Pointer): HResult; stdcall;
    function CreateInstance(const unkOuter: IUnknown; const iid: TIID;
      out vObj): HResult; stdcall;
    function GetMops(memid: TMemberID; out bstrMops: WideString): HResult;
      stdcall;
    function GetContainingTypeLib(out tlib: ITypeLib; out pindex: Integer): HResult;
      stdcall;
    procedure ReleaseTypeAttr(ptypeattr: PTypeAttr); stdcall;
    procedure ReleaseFuncDesc(pfuncdesc: PFuncDesc); stdcall;
    procedure ReleaseVarDesc(pvardesc: PVarDesc); stdcall;
    constructor Create(AOwner: TVCLProxy; ClassNameStr: WideString);
  end;

  TVFPConnector = class(TComponent)
     private
       FForm: TCustomForm;
       FNamedItems: TNamedItemList;
       FCode: TStringList;
      procedure RegisterClass(AName: string; PC: TPersistent);
    procedure SetCode(const Value: TStringList);
     public
       FVFP: Ivfpoleserver;
      constructor Create(AOwner: TComponent); override;
      destructor Destroy; override;
      function GetProxy(P: TPersistent): OleVariant;
      function Execute: OleVariant;
      procedure SetForm(frm: TCustomForm);
      procedure FreeItems;
      property NamedItems: TNamedItemList read FNamedItems;
     published
      property Code: TStringList read FCode write SetCode;
     end;

   TVCLEnum = class(TInterfacedObject, IEnumVariant)
   private
     FEnumPosition: Integer;
     FOwner: TPersistent;
     FScriptControl: TVFPConnector;
     { IEnumVariant }
     function Next(celt: LongWord; var rgvar: OleVariant;
       pceltFetched: PLongWord): HResult; stdcall;
     function Skip(celt: LongWord): HResult; stdcall;
     function Reset: HResult; stdcall;
     function Clone(out Enum: IEnumVariant): HResult; stdcall;
   public
     constructor Create(AOwner: TPersistent;
       AScriptControl: TVFPConnector);
   end;


   TVCLProxy = class(TInterfacedObject, IDispatch, IQueryPersistent)
   private
     FOwner: TPersistent;
     FScriptControl: TVFPConnector;
     procedure DoCreateControl(AName, AClassName: WideString;
       WithEvents: Boolean);
     function SetVCLProperty(PropInfo: PPropInfo;
       Argument: TVariantArg): HRESULT;
     function GetVCLProperty(PropInfo: PPropInfo; dps: TDispParams;
       PDispIds: PDispIdList; var Value: OleVariant): HRESULT;
     { IDispatch }
     function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
     function GetTypeInfo(Index, LocaleID: Integer;
       out TypeInfo): HResult; stdcall;
     function GetIDsOfNames(const IID: TGUID; Names: Pointer;
       NameCount, LocaleID: Integer;
       DispIDs: Pointer): HResult; stdcall;
     function Invoke(DispID: Integer; const IID: TGUID;
       LocaleID: Integer; Flags: Word; var  Params;
       VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
     { IQueryPersistent }
     function GetPersistent: TPersistent;
   protected
     function DoInvoke (DispID: Integer; const IID: TGUID;
       LocaleID: Integer; Flags: Word; var dps : TDispParams;
       pDispIds : PDispIdList; VarResult, ExcepInfo,
       ArgErr: Pointer): HResult; virtual;
   public
     constructor Create(AOwner: TPersistent;
       ScriptControl: TVFPConnector);
     destructor Destroy; override;
   end;

  PNamesArray = ^TNamesArray;
  TNamesArray = array[ 0 .. 0 ] of PWideChar;

const
  DISPID_CONTROLS =  1 ;
  DISPID_COUNT =  2 ;
  DISPID_ADD =  3 ;
  DISPID_HASPROPERTY =  4 ;


procedure Register;

implementation


//uses ActiveX;

procedure Register;
begin
//  RegisterComponents('Stat', [TFVPConnector]);
end;

function TVCLProxy.GetIDsOfNames(const  IID: TGUID; Names: Pointer;
   NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;
 var
   S: String;
   Info: PPropInfo;
 begin
   Result := S_OK;
   S := PNamesArray(Names)[ 0 ];
   Info := GetPropInfo(FOwner.ClassInfo, S);
   if Assigned(Info) then begin
     PDispIdsArray(DispIds)[ 0 ] := Integer(Info);
   end
 else
   if CompareText(S, 'CONTROLS') =  0  then begin
     if (FOwner is TWinControl) then
       PDispIdsArray(DispIds)[ 0 ] := DISPID_CONTROLS
     else
       Result := DISP_E_UNKNOWNNAME;
   end
   else 
  if CompareText(S, 'COUNT') =  0  then begin
     if (FOwner is TCollection) or (FOwner is TStrings)
        or (FOwner is TWinControl) then
       PDispIdsArray(DispIds)[ 0 ] := DISPID_COUNT
     else
       Result := DISP_E_UNKNOWNNAME;
   end  
 else
   if CompareText(S, 'ADD') =  0  then begin
     Result := S_OK;
     if (FOwner is TCollection) or (FOwner is TStrings) or
        (FOwner is TWinControl) then
       PDispIdsArray(DispIds)[ 0 ] := DISPID_ADD
     else
       Result := DISP_E_UNKNOWNNAME;
   end
 else

  if CompareText(S, 'HASPROPERTY') =  0  then
     PDispIdsArray(DispIds)[ 0 ] := DISPID_HASPROPERTY
   else
     Result := DISP_E_UNKNOWNNAME;
 end;  

function TVCLProxy.DoInvoke(DispID: Integer; const IID: TGUID;
   LocaleID: Integer; Flags: Word; var dps: TDispParams;
   pDispIds: PDispIdList; VarResult, ExcepInfo, ArgErr: Pointer
   ): HResult;
 var
   S: String;
   Put: Boolean;
   I: Integer;
   P: TPersistent;
   B: Boolean;
   OutValue: OleVariant;  
   v: tagVariant;
procedure CheckArgCount(args: LongInt; ar: array of integer; b_excp: boolean);
  var Err: Boolean;
  i, nc, np: integer;
  label l_err;
begin
  if args <=  0  then goto l_err;
     nc:=Length(ar);
  for i:= 1  to nc do begin
    if args < ar[i- 1 ] then goto l_err;
  end;
  Exit;
l_err:
  if b_excp then raise Exception.Create('Íåâåðíîå êîëè÷åñòâî ïàðàìåòðîâ !');
end;

function _ValidType(n_arg: integer; chk_type: integer; cond: boolean): boolean;
var ov: OleVariant;
    ie: Integer;
begin
  Result:=dps.rgvarg^[n_arg].vt = chk_type;
  if not Result and cond then raise Exception.Create('Íåñîîòâåòñâèå òèïà !');
end;

function _IntValue(cn: Integer): integer;
begin
  Result:=dps.rgvarg^[cn].intVal;
end;

begin
   Result := S_OK;
   case DispId of
   DISPID_CONTROLS:
         begin
         with FOwner as TWinControl do
         begin
           CheckArgCount(dps.cArgs, [ 1 ], TRUE);
           P := NIL;
           if _ValidType( 0 , VT_BSTR, FALSE) then begin
             S := dps.rgvarg^[pDispIds^[ 0 ]].bstrVal;
             for I :=  0  to Pred(ControlCount) do
               if CompareText(S, Controls[I].Name) =  0  then begin
                 P := Controls[I];
                 Break;
               end;
           end else begin
             I := _IntValue( 0 );
             P := Controls[I];
           end;
           if not Assigned(P) then
             raise Exception.Create('Íåâîçìîæíî íàéòè êîìïîíåíò '+S+'!');
           OleVariant(VarResult^) := FScriptControl.GetProxy(P);
         end;
       end;
   DISPID_COUNT:
        begin
         CheckArgCount(dps.cArgs, [ 0 ], TRUE);
         if FOwner is TWinControl then
           OleVariant(VarResult^) := TWinControl(FOwner).ControlCount
         else
         if FOwner is TCollection then
           OleVariant(VarResult^) := TCollection(FOwner).Count
         else
         if FOwner is TStrings then
           OleVariant(VarResult^) := TStrings(FOwner).Count;
       end;  
   DISPID_ADD:
         begin
         if FOwner is TWinControl then begin
           CheckArgCount(dps.cArgs, [ 2 , 3 ], TRUE);
           _ValidType( 0 , VT_BSTR, TRUE);
           _ValidType( 1 , VT_BSTR, TRUE);
           if (dps.cArgs =  3 ) and _ValidType( 2 , VT_BOOL, TRUE) then
             B := dps.rgvarg^[pDispIds^[ 0 ]].vbool
           else
             B := FALSE;
           DoCreateControl(dps.rgvarg^[pDispIds^[ 0 ]].bstrVal,
             dps.rgvarg^[pDispIds^[ 1 ]].bstrVal, B);
         end
         else
         if FOwner is TCollection then begin
           P := TCollection(FOwner).Add;
           OleVariant(varResult^) := FScriptControl.GetProxy(P);
         end
         else
         if FOwner is TStrings then begin
           CheckArgCount(dps.cArgs, [ 1 , 2 ], TRUE);
           _ValidType( 0 , VT_BSTR, TRUE);
           if dps.cArgs =  2  then
             I := _IntValue( 1 )
           else
             I := TStrings(FOwner).Count;
           TStrings(FOwner).Insert(I,
             dps.rgvarg^[pDispIds^[ 0 ]].bstrVal);
         end;
       end;

   DISPID_HASPROPERTY:
       begin
         CheckArgCount(dps.cArgs, [ 1 ], TRUE);
         _ValidType( 0 , VT_BSTR, TRUE);
         S := dps.rgvarg^[pDispIds^[ 0 ]].bstrVal;
         OleVariant(varResult^) :=
           Assigned(GetPropInfo(FOwner.ClassInfo, S));
       end;  

    DISPID_NEWENUM: begin
         OleVariant(VarResult^) := TVCLEnum.Create(FOwner,
           FScriptControl) as IEnumVariant;
       end;


else
     Put := (Flags and DISPATCH_PROPERTYPUT) <>  0 ;
     if Put then begin
       CheckArgCount(dps.cArgs, [ 1 ], TRUE);
       v:=dps.rgvarg^[{pDispIds^[ 0 ]} 0 ];
       Result := SetVCLProperty(PPropInfo(DispId),
         dps.rgvarg^[ 0 {pDispIds^[ 0 ]}]) // dps.rgvarg^[pDispIds^[ 0 ]] -  192 ; 240 ; 227 ; 243 ; 229 ; 236 ; 237 ; 242 ;  226 ; 224 ; 240 ; 232 ; 224 ; 237 ; 242 ; 237 ; 238 ; 227 ; 238 ;  242 ; 232 ; 239 ; 224 ;
     end
     else
     begin
       if DispId =  0  then begin
         OleVariant(VarResult^) := Self as IDispatch;
         Exit;
       end;
       Result := GetVCLProperty(PPropInfo(DispId),
         dps, pDispIds, OutValue);
       if Result = S_OK then
         OleVariant(VarResult^) := OutValue;
     end;
   end;
 end;

procedure TVCLProxy.DoCreateControl(AName, AClassName: WideString;
   WithEvents: Boolean);

   procedure SetHandler(Control: TPersistent; Owner: TObject;
     Name: String);
   var
     Method: TMethod;
     PropInfo: PPropInfo;
   begin
     PropInfo := GetPropInfo(Control.ClassInfo, Name);
     if Assigned(PropInfo) then begin
       Method.Code := FScriptControl.MethodAddress(Name + 'Handler');
       if Assigned(Method.Code) then begin
         Method.Data := FScriptControl;
         SetMethodProp(Control, PropInfo, Method);
       end;
     end;
    end;


var
   ThisClass: TControlClass;
   C: TComponent;
   NewOwner: TCustomForm;
 begin
   if not (FOwner is TCustomForm) then
     NewOwner := GetParentForm(FOwner as TControl)
   else
     NewOwner := FOwner as TCustomForm;
   ThisClass := TControlClass(GetClass(AClassName));
   C := ThisClass.Create(NewOwner);
   C.Name := AName;
   if C is TControl then
     TControl(C).Parent := FOwner as TWinControl;
   if WithEvents then begin
     SetHandler(C, NewOwner, 'OnClick');
     SetHandler(C, NewOwner, 'OnChange');
     SetHandler(C, NewOwner, 'OnEnter');
     SetHandler(C, NewOwner, 'OnExit');
     SetHandler(C, NewOwner, 'OnTimer');
   end;
   FScriptControl.RegisterClass(AName, C);
 end;


////*********************************************
function TVCLProxy.GetVCLProperty(PropInfo: PPropInfo; dps: TDispParams;
       PDispIds: PDispIdList; var Value: OleVariant): HRESULT;

 var
   I, J, K: Integer;
   S: String;
   P, P1: TPersistent;
   Data: PTypeData;
   DT: TDateTime;
   TypeInfo: PTypeInfo;

function ValidType(n_arg: tagVARIANT; chk_type: integer; cond: boolean): boolean;
var ov: OleVariant;
    ie: Integer;
begin
  Result:=DispGetParam(dps, n_arg.intVal, chk_type, ov, ie) = S_OK;
end;

function IntValue(cn: tagVARIANT): integer;
begin
  Result:=dps.rgvarg^[cn.intVal].intVal;
end;

 begin
   Result := S_OK;
   case PropInfo^.PropType^.Kind  of
     tkString, tkLString, tkWChar, tkWString:
       Value := GetStrProp(FOwner, PropInfo);
    tkChar, tkInteger:
       Value := GetOrdProp(FOwner, PropInfo);
    tkEnumeration:
       begin
         if CompareText(PropInfo^.PropType^.Name, 'BOOLEAN') =  0  then
           Value := Boolean(GetOrdProp(FOwner, PropInfo))
         else begin
           I := GetOrdProp(FOwner, PropInfo);
           Value := GetEnumName(PropInfo^.PropType^, I);
         end;
       end;
    tkClass:
       begin  // 0 
         P := TPersistent(GetOrdProp(FOwner, PropInfo));
         if Assigned(P) and (P is TCollection)
            and (dps.cArgs =  1 ) then begin // 1 
           if ValidType(dps.rgvarg^[pDispIds^[ 0 ]], VT_BSTR,
               FALSE) then begin // 2 
             S := dps.rgvarg^[pDispIds^[ 0 ]].bstrVal;
             P1 := NIL;
             for I :=  0  to Pred(TCollection(P).Count) do
               if CompareText(S,
                 TCollection(P).Items[I].DisplayName)  =  0  then begin // 3 
                    P1 := TCollection(P).Items[I];
                    Break;
                // end; // 3 
              end; // 3 
             if Assigned(P1) then
               Value := FScriptControl.GetProxy(P1)
             else
               Result := DISP_E_MEMBERNOTFOUND;
           end else begin // 3 
             I :=IntValue(dps.rgvarg^[pDispIds^[ 0 ]]);
             if (I >=  0 ) and (I < TCollection(P).Count) then begin // 4 
               P := TCollection(P).Items[I];
               Value := FScriptControl.GetProxy(P);
             end else
               Result := DISP_E_MEMBERNOTFOUND;
           end;//  4 
end // 3 
else
         if Assigned(P) and (P is TStrings) and (dps.cArgs =  1 ) then
         begin // 1 
           if ValidType(dps.rgvarg^[pDispIds^[ 0 ]], VT_BSTR,
             FALSE) then begin // 2 
             S := dps.rgvarg^[pDispIds^[ 0 ]].bstrVal;
             Value := TStrings(P).Values[S];
            end else begin  // 3 
             I := IntValue(dps.rgvarg^[pDispIds^[ 0 ]]);
              if (I >=  0 ) and (I < TStrings(P).Count) then
                Value := TStrings(P)[I]
              else
               Result := DISP_E_MEMBERNOTFOUND;
              end; // 3 
           end; // 2 
           if Assigned(P) then
             Value := FScriptControl.GetProxy(P)
           else
             Value := Unassigned;
    end;
    tkFloat:
       begin
         if (PropInfo^.PropType^ = System.TypeInfo(TDateTime))or
            (PropInfo^.PropType^ = System.TypeInfo(TDate)) then
         begin
           Value := DT;
         end else
           Value := GetFloatProp(FOwner, PropInfo);
       end;
    tkSet:
       begin
         I := GetOrdProp(FOwner, PropInfo);
         Data := GetTypeData(PropInfo^.PropType^);
         TypeInfo := Data^.CompType^;
         S := '';
         if I <>  0  then begin
           for K :=  0  to  31  do begin
             J :=  1  shl K;
             if (J and I) = J then
               S := S + GetEnumName(TypeInfo, K) + ',';
           end;
           System.Delete(S, Length(S),  1 );
         end;
         Value := S;
       end;
    tkVariant:
       Value := GetVariantProp(FOwner, PropInfo);
   else
     Result := DISP_E_MEMBERNOTFOUND;
  end;
end;



constructor TVCLProxy.Create(AOwner: TPersistent;
  ScriptControl: TVFPConnector);
begin
  FOwner:=AOwner;
  FScriptControl:=ScriptControl;
end;

destructor TVCLProxy.Destroy;
begin

  inherited;
end;

function TVCLProxy.GetPersistent: TPersistent;
begin
  Result:=FOwner;
end;

function TVCLProxy.GetTypeInfo(Index, LocaleID: Integer;
  out TypeInfo): HResult;
begin
  if index= 0  then begin
      ITypeInfo(TypeInfo):=TTypeinfoPlug.Create(Self, FOwner.ClassName) as ITypeInfo;
      Result := S_OK;
  end
  else
    Result:=DISP_E_BADINDEX;
end;

function TVCLProxy.GetTypeInfoCount(out Count: Integer): HResult;
begin
  Count:= 1 ;
  Result:=S_OK;
end;

function TVCLProxy.Invoke(DispID: Integer; const IID: TGUID;
  LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo,
  ArgErr: Pointer): HResult;
begin
 Result:=DoInvoke(DispId,
                  IID,
                  LocaleID,
                  Flags,
                  tagDispParams(Params),
                  pDispiDList(tagDispParams(Params).rgdispidNamedArgs),
                  VarResult,
                  ExcepInfo,
                  ArgErr);
end;

function TVCLEnum.Reset: HResult;
begin
  FEnumPosition :=  0 ;
  Result:=S_OK;
end;

{ TVFPConnector }

constructor TVFPConnector.Create(AOwner: TComponent);
var i: integer;

begin
  inherited Create(AOwner);
  FCode:=TStringList.Create;
  FNamedItems:=TNameditemList.Create(Self);
  FVFP:=CoVFPOLEServer.Create;
  if Owner is TCustomForm then
      SetForm(TCustomForm(Owner))
  else
      SetForm(GetParentForm(TControl(Owner)));
end;

destructor TVFPConnector.Destroy;
begin
  FCode.Free;
  FVFP:=nil;
  inherited;
end;

function TVFPConnector.Execute: OleVariant;
begin
  Result:=Unassigned;
  if Assigned(FVFP) then Result:=FVFP.NAFunct(WideString(FCode.Text));
end;

procedure TVFPConnector.FreeItems;
begin
  FNamedItems.Clear;
end;

function TVFPConnector.GetProxy(P: TPersistent): OleVariant;
var
    Dispatch: IDispatch;
begin
  Dispatch:=NamedItems.FindItem(TComponent(P).Name);
  if Dispatch = nil then
      Dispatch:=TVCLProxy.Create(P, Self) as IDispatch;
  NamedItems.AddItem(TComponent(P).Name, Dispatch);
  Result:=Dispatch;
end;

procedure TVFPConnector.RegisterClass(AName: string; PC: TPersistent);
var
    Dispatch: IDispatch;
begin
  Dispatch:=NamedItems.FindItem(TComponent(PC).Name);
  if Dispatch = nil then begin
     Dispatch:=TVCLProxy.Create(PC, Self) as IDispatch;
     NamedItems.AddItem(TComponent(PC).Name, Dispatch);
  end;
end;


function TVCLProxy.SetVCLProperty(PropInfo: PPropInfo;
   Argument: TVariantArg): HResult;
 var
   I, J, K, CommaPos: Integer;
   GoodToken: Boolean;
   S, S1: string;
   DT: TDateTime;
   ST: TSystemTime;
   IP: IQueryPersistent;
   Data, TypeData: PTypeData;
   TypeInfo: PTypeInfo;

function ValidType(n_arg: TVariantArg; chk_type: integer; cond: boolean): boolean;
begin
  Result:= n_arg.vt = chk_type;
  if not Result and cond then
    raise Exception.Create('Íåñîîòâåòâèå òèïà !');
end;

function IntValue(cn: TVariantArg): integer;
begin
  Result:=cn.intVal;
end;


 begin
   Result := S_OK;
   case PropInfo^.PropType^.Kind  of
    tkChar, tkString, tkLString, tkWChar, tkWString:
       begin
         ValidType(Argument, VT_BSTR, TRUE);
         SetStrProp(FOwner, PropInfo, Argument.bstrVal);
       end;
    tkInteger:
       begin
          if (CompareText(PropInfo^.PropType^.Name, 'TCURSOR') =  0 ) and
            (Argument.vt = VT_BSTR) then begin  // 1 
           if not IdentToCursor(Argument.bstrVal, I) then begin  // 2 
             Result := DISP_E_BADVARTYPE;
             Exit;
           end;  // 2 
         end {// 1 } else
         if (CompareText(PropInfo^.PropType^.Name, 'TCOLOR') =  0 ) and
           (Argument.vt = VT_BSTR) then begin // 1 
            if not IdentToColor(Argument.bstrVal, I) then begin
             Result := DISP_E_BADVARTYPE;
             Exit;
            end;
         end else
           I := IntValue(Argument);
         SetOrdProp(FOwner, PropInfo, I);
       end;
    tkEnumeration:
       begin
         if CompareText(PropInfo^.PropType^.Name, 'BOOLEAN') =  0  then
         begin
           ValidType(Argument, VT_BOOL, TRUE);
           SetOrdProp(FOwner, PropInfo, Integer(Argument.vBool));
         end else begin
           ValidType(Argument, VT_BSTR, TRUE);
           S := Trim(Argument.bstrVal);
           I := GetEnumValue(PropInfo^.PropType^, S);
           if I >=  0  then
             SetOrdProp(FOwner, PropInfo, I)
           else
             raise Exception.Create('');
         end;
        end;
    tkClass:
         begin
           ValidType(Argument, VT_DISPATCH,    TRUE);
           if Assigned(Argument.dispVal) then begin
             IP := IDispatch(Argument.dispVal) as IQueryPersistent;
             I := Integer(IP.GetPersistent);
           end else
             I :=  0 ;
           SetOrdProp(FOwner, PropInfo, I);
         end;
   tkFloat:
       begin
         if (PropInfo^.PropType^ = System.TypeInfo(TDateTime)) or
            (PropInfo^.PropType^ = System.TypeInfo(TDate)) then
 begin
           if Argument.vt = VT_BSTR then begin
             DT := StrToDate(Argument.bstrVal);
           end else begin
             ValidType(Argument, VT_DATE, TRUE);
             if VariantTimeToSystemTime(Argument.date, ST) <>  0  then
               DT := SystemTimeToDateTime(ST)
             else begin
               Result := DISP_E_BADVARTYPE;
               Exit;
             end;
           end;
           SetFloatProp(FOwner, PropInfo, DT);
         end else begin
           ValidType(Argument, VT_R8, TRUE);
           SetFloatProp(FOwner, PropInfo, Argument.dblVal);
         end;
       end;
   tkSet:
       begin

         ValidType(Argument, VT_BSTR, TRUE);
         S := Trim(Argument.bstrVal);

         Data := GetTypeData(PropInfo^.PropType^);
         TypeInfo := Data^.CompType^;
         TypeData := GetTypeData(TypeInfo);
         I :=  0 ;
         while Length(S) >  0  do begin
           CommaPos := Pos(',', S);
           if CommaPos =  0  then
             CommaPos := Length(S) +  1 ;
           S1 := Trim(System.Copy(S,  1 , CommaPos -  1 ));
           System.Delete(S,  1 , CommaPos);
           if Length(S1) >  0  then begin
             K :=  1 ;
             GoodToken := FALSE;
             for J := TypeData^.MinValue to TypeData^.MaxValue do
             begin
               if CompareText(S1, GetEnumName(TypeInfo , J)) =  0  then
                begin
                 I := I or K;
                 GoodToken := TRUE;
               end;
               K := K shl  1 ;
             end;
             if not GoodToken then begin
               Result := DISP_E_BADVARTYPE;
               Exit;
             end;
           end;
         end;
         SetOrdProp(FOwner, PropInfo, I);
       end;
    tkVariant:
       begin
         ValidType(Argument, VT_VARIANT, TRUE);
         SetVariantProp(FOwner, PropInfo, Argument.pvarVal^);
       end;
    else
      Result := DISP_E_MEMBERNOTFOUND;
   end;
 end;


 constructor TVCLEnum.Create(AOwner: TPersistent;
   AScriptControl: TVFPConnector);
 begin
   inherited Create;
   FOwner := AOwner;
   FScriptControl := AScriptControl;
   FEnumPosition :=  0 ;
 end;

 function TVCLEnum.Next(celt: LongWord; var rgvar: OleVariant;
   pceltFetched: PLongWord): HResult;
 var
   I: Cardinal;
 begin
   Result := S_OK;
   I :=  0 ;
  if FOwner is TWinControl then begin
     with TWinControl(FOwner) do begin
       while (FEnumPosition < ControlCount) and (I < celt) do begin
         TVariantList(rgvar)[I] :=
           FScriptControl.GetProxy(Controls[FEnumPosition]);
         Inc(I);
         Inc(FEnumPosition);
       end;
     end;
 end
 else
   if FOwner is TCollection then begin
     with TCollection(FOwner) do begin
       while (FEnumPosition < Count) and (I < celt) do begin
         TVariantList(rgvar)[I] :=
           FScriptControl.GetProxy(Items[FEnumPosition]);
         Inc(I);
         Inc(FEnumPosition);
       end;
     end;
 end
else
   if FOwner is TStrings then begin
     with TStrings(FOwner) do begin
       while (FEnumPosition < Count) and (I < celt) do begin
         TVariantList(rgvar)[I] := TStrings(FOwner)[FEnumPosition];
         Inc(I);
         Inc(FEnumPosition);
       end;
     end;
   end else
     Result := S_FALSE;
   if I <> celt then
     Result := S_FALSE;
   if Assigned(pceltFetched) then
     pceltFetched^ := I;
 end;

 function  TVCLEnum.Skip(celt: LongWord): HResult;
 var
   Total: Integer;
 begin
   Result := S_FALSE;
   if FOwner is TWinControl then
     Total := TWinControl(FOwner).ControlCount
   else
   if FOwner is TCollection then
     Total := TCollection(FOwner).Count
   else
   if FOwner is TStrings then
     Total := TStrings(FOwner).Count
   else
     Exit;
   if FEnumPosition + celt <= Total then begin
     Result := S_OK;
     Inc(FEnumPosition, celt)
   end;
 end;

function TVCLEnum.Clone(out Enum: IEnumVariant): HResult;
 var
   NewEnum: TVCLEnum;
 begin
   NewEnum := TVCLEnum.Create(FOwner, FScriptControl);
   NewEnum.FEnumPosition := FEnumPosition;
   Enum := NewEnum as IEnumVariant;
   Result := S_OK;
 end;


procedure TVFPConnector.SetCode(const Value: TStringList);
begin
  FCode.Assign(Value);
end;

procedure TVFPConnector.SetForm(frm: TCustomForm);
var i: integer;
begin
  if Assigned(frm) then begin
    NamedItems.Clear;
    NamedItems.AddItem('Self', TVCLProxy.Create(frm, Self));
    for i:= 0  to frm.ComponentCount -  1  do begin
       NamedItems.AddItem(frm.Components[i].Name, GetProxy(frm.Components[i]));
    end;
  end;

end;

{ TNamedItemList }

procedure TNamedItemList.AddItem(const Name: string; Item: IDispatch);
var i1: TNameditem;
begin
  i1:=TNameditem.Create;
  i1.FDispatch:=item;
  i1.FName:=AnsiUpperCase(Name);
  Add(i1);
  if Assigned(FConnector.FVFP) and (Name<>'') then
      FConnector.FVFP.AddDispatch(item, WideString(Name));
end;

procedure TNamedItemList.Clear;
var i: integer;
begin
  if not (csDestroying in FConnector.Owner.ComponentState) then begin
  FConnector.FVFP.FreeDispatch('Self');
  for i:= 0  to Self.Count -  1  do
    FConnector.FVFP.FreeDispatch(TNamedItem(Items[i]).FName);
  end;
  inherited;
end;



constructor TNamedItemList.Create(Connector: TVFPConnector);
begin
  inherited Create;
  FConnector:=Connector;
end;

function TNamedItemList.FindItem(Item: string): IDispatch;
var i: integer;
begin
  Result:=nil;
  for i:= 0  to count -  1  do begin
    if SameText(TNamedItem(Items[i]).FName, Item) then begin
      Result:=TNamedItem(Items[i]).FDispatch;
      break;
    end;
  end;
end;

function TNamedItemList.GetItemIDispatch(const Name: string): IDispatch;
begin
  Result:=FindItem(Name);
end;

{ TTypeinfoPlug }

function TTypeinfoPlug.AddressOfMember(memid: TMemberID;
  invkind: TInvokeKind; out ppv: Pointer): HResult;
begin
  Result:=E_FAiL;
end;

constructor TTypeinfoPlug.Create(AOwner: TVCLProxy; ClassNameStr: WideString);
begin
  FClassNameStr:=ClassNameStr;
  FOwner:=AOwner;
end;

function TTypeinfoPlug.CreateInstance(const unkOuter: IInterface;
  const iid: TIID; out vObj): HResult;
begin
  Result:=E_NOTiMPL;
end;

function TTypeinfoPlug.GetContainingTypeLib(out tlib: ITypeLib;
  out pindex: Integer): HResult;
begin
  Result:=E_NOTiMPL;
end;

function TTypeinfoPlug.GetDllEntry(memid: TMemberID; invkind: TInvokeKind;
  bstrDllName, bstrName: PWideString; wOrdinal: PWord): HResult;
begin
  Result:=E_FAiL;
end;

function TTypeinfoPlug.GetDocumentation(memid: TMemberID; pbstrName,
  pbstrDocString: PWideString; pdwHelpContext: PLongint;
  pbstrHelpFile: PWideString): HResult;
begin
  if Memid = MEMBERiD_Nil then begin
    if pbstrName <> nil then pbstrName^:=FClassNameStr;
    if pbstrDocString <> nil then pbstrDocString^ := '';
    result:=S_OK;
  end else
    Result:=E_FAiL;
end;

function TTypeinfoPlug.GetFuncDesc(index: Integer;
  out pfuncdesc: PFuncDesc): HResult;
begin
  Result:=E_NOTiMPL;
end;

function TTypeinfoPlug.GetIDsOfNames(rgpszNames: POleStrList;
  cNames: Integer; rgmemid: PMemberIDList): HResult;
begin
   Result:=FOwner.GetIDsOfNames(GUID_NULL, rgpszNames, Length(rgpszNames^),  0 , rgmemid);
end;

function TTypeinfoPlug.GetImplTypeFlags(index: Integer;
  out impltypeflags: Integer): HResult;
begin
  impltypeflags:=iMPLTYPEFLAG_FDEFAULT;
  result:=S_OK;
end;

function TTypeinfoPlug.GetMops(memid: TMemberID;
  out bstrMops: WideString): HResult;
begin
  Result:=E_NOTiMPL;
end;

function TTypeinfoPlug.GetNames(memid: TMemberID; rgbstrNames: PBStrList;
  cMaxNames: Integer; out cNames: Integer): HResult;
begin
   Result:=E_NOTiMPL;
end;

function TTypeinfoPlug.GetRefTypeInfo(reftype: HRefType;
  out tinfo: ITypeInfo): HResult;
begin
   Result:=Queryinterface(iTypeinfo, tinfo);
end;


function TTypeinfoPlug.GetRefTypeOfImplType(index: Integer;
  out reftype: HRefType): HResult;
begin
  reftype:= 0 ;
  Result:=S_OK;
end;
var TypeAttr: TTypeAttr;

function TTypeinfoPlug.GetTypeAttr(out ptypeattr: PTypeAttr): HResult;
begin
  FillChar(TypeAttr, SizeOf(TypeAttr), 0 );
  with TypeAttr do begin
    cimplTypes:= 1 ;
    guid:=iDispatch;
  end;
  pTypeAttr:=@TypeAttr;
  Result:=S_OK;
end;

function TTypeinfoPlug.GetTypeComp(out tcomp: ITypeComp): HResult;
begin
   iTypeComp(tcomp):=TTypeCompStub.Create(FOwner) as iTypeComp;
   Result:=S_OK;
end;

function TTypeinfoPlug.GetVarDesc(index: Integer;
  out pvardesc: PVarDesc): HResult;
begin
  Result:=E_NOTiMPL;
end;

function TTypeinfoPlug.Invoke(pvInstance: Pointer; memid: TMemberID;
  flags: Word; var dispParams: TDispParams; varResult: PVariant;
  excepInfo: PExcepInfo; argErr: PInteger): HResult;
begin
   Result:=FOwner.Invoke(memid,
                          GUiD_NULL,
                           0 ,
                          flags,
                          dispParams,
                          varResult,
                          excepInfo,
                          argErr);
end;

procedure TTypeinfoPlug.ReleaseFuncDesc(pfuncdesc: PFuncDesc);
begin
end;

procedure TTypeinfoPlug.ReleaseTypeAttr(ptypeattr: PTypeAttr);
begin
end;

procedure TTypeinfoPlug.ReleaseVarDesc(pvardesc: PVarDesc);
begin
end;

{ TTypeCompStub }

function TTypeCompStub.Bind(szName: POleStr; lHashVal: Integer;
  wflags: Word; out tinfo: ITypeInfo; out desckind: TDescKind;
  out bindptr: TBindPtr): HResult;
begin
   Result:=E_NOTiMPL;
end;

function TTypeCompStub.BindType(szName: POleStr; lHashVal: Integer;
  out tinfo: ITypeInfo; out tcomp: ITypeComp): HResult;
begin
   Result:=E_NOTiMPL;
end;

constructor TTypeCompStub.Create(AOwner: TVCLProxy);
begin
  FOwner:=AOwner;
end;

initialization
  Coinitialize(nil);
finalization
  CoUninitialize;
end.


Сорри, что без коментариев, для желающих могу все подробно описать.
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129974
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Суть в следующем: пишу класс, который позволяет исполнят код Visual Foxpro в программах на Delphi

Тока без обид. А по кой х... это надо!?


>Вообще, если довести это дело до конца, получиться отличная вещь.

Это было подтверждено маркетинговыми исследованиями?
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129979
Фотография maloi_alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А на х вообще надо встраивать языки сценариев в приложения ?.........
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129980
StarWind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот уж точно изврат.....
зачем??? что это даст?
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129984
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во-первых, чтоб запостить такой длиннющий листинг, надо было поинтересоваться, а стоит ли.

>А на х вообще надо встраивать языки сценариев в приложения ?.........

Вот именно, на х... они нужны в приложении.
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32129993
StarWind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pkarklin

не сами по себе языки сценариев может и нужны в каких-то особых случаях... (например в FastReport) но уж явно не интерпретатор другого языка....
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32130001
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>не сами по себе языки сценариев может и нужны в каких-то особых

Языки сценариев в контексте приложения на Delphi - убожество, IMHO. Если разработчик стороннего компонента не может предоставить нормальный объектно ориентированный интерфейс, а дает язык сценариев, то я не буду использовать такой компонент. Еще раз повторюсь, IMHO.
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32130004
Фотография maloi_alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pkarklin

Допустим, есть программный комплекс который позволяет пользователям создавать свои отчеты, причем алгоритм формирования отчета должен разрабатываться самим пользователем (ну или разработчиком). Кроме того, пользователь может иметь возможность самостоятельно осуществлять выборку данных и доступной базы, по условиям разработанным самим пользователям, а не создателем программного комплекса. Фокс в этом случае, в качестве встроенного языка сценария хорош тем, что поддерживает не только реляционные команды, но и навигационные. Так что не вижу ничего плохого, если в моих програх на Delphi, будут присутствовать возоможнсти Фокса.
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32130026
Фотография maloi_alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если разработчик стороннего компонента не может предоставить нормальный объектно ориентированный интерфейс, а дает язык сценариев, то я не буду использовать такой компонент

Что ты имееш ввиду под нормальным объектно ориентированным интерфейсом ?
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32130055
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Что ты имееш ввиду под нормальным объектно ориентированным интерфейсом ?

Это когда разрабочик компонента дает набор свойств, методов и событий, которые бы позволили разработчику приложения реализовать нужную функуциональность без применения сценариев.
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32130178
Фотография maloi_alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за мысль. Обязательно учту.
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32130412
Фотография maloi_alex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вопрос мы так и не закрыли...........
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32130493
aag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИМХО, pkarklin несколько погорячился - есть целы ряд задач, где языки сценариев, сиречь втроенные интерпретаторы, могут оказаться полезны (хотя сам ни с одной такой не сталкивался). Напр. генераторы отчетов, всякие реадкторы формул и пр.
Только на Delphi уже существует целая куча таких интерпретаторов - больше всего на самом Object Pascal. Напр. RALIb.
А зачем нужен интерпр. FoxPro на Delphi - этого я понять не могу
...
Рейтинг: 0 / 0
Вопрос к спецам по RTTI
    #32130505
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 aag

>могут оказаться полезны (хотя сам ни с одной такой не сталкивался).

Вот и я про тоже. Все должно определяться необходимостью. Если я пишу на серъезном объектно-ориентированном средстве разработки, то на кой мне эти дефективные языки сценариев. Но, повторяюсь еще раз. Это мое личное IMHO. И я не требую, чтоб все этому следовали. :-)
...
Рейтинг: 0 / 0
25 сообщений из 41, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Вопрос к спецам по RTTI
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]