Bonjour,
alors j'ai un cas un peu compliqué à vous soumettre, c'est en relation avec l'utilisation de l'interface IEnumVariant qui permet de réaliser l'instruction foreach de VB avec Delphi. Voir la FAQ pour plus d'infos.
Donc j'arrive bien à faire un parcours de mon objet COM supportant l'interface pas de problème mais comme la syntaxe est assez lourde j'ai voulu faire une procédure qui serait capable de faire le foreach de l'objet COM et qui me transmettrais chaque item parcouru via une procédure de rappel passé en paramètre de ma procédure.
Voici mon code :
A noter que j'ai une version overload de cette procédure pour utiliser le type :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 TOleVariantProcedure = procedure (var poElement: OleVariant); procedure Enumerate( const poObject: IDispatch; const CallBack: TOleVariantProcedure ); overload; var voEnumDict, voElement: OleVariant; voEnumerator: IEnumVariant; DispParamNoArgs: TDispParams; viFetched: LongWord; begin try // si les paramètres sont invalides alors ne rien faire if not Assigned( CallBack ) or ( poObject = NIL ) then Exit; // initialiser les paramètres DispParamNoArgs.rgvarg := NIL; DispParamNoArgs.rgdispidNamedArgs := NIL; DispParamNoArgs.cArgs := 0; DispParamNoArgs.cNamedArgs := 0; // récupérer l'interface IEnumVariant OleCheck( poObject.Invoke( DISPID_NEWENUM, GUID_NULL, 0, DISPATCH_PROPERTYGET, DispParamNoArgs, @voEnumDict, NIL, NIL ) ); // L'interface est-elle assignée if VarIsEmpty( voEnumDict ) or VarIsNull( voEnumDict ) then raise Exception.Create( 'L''Enumerator récupéré n''est pas assigné.' ); // l'interface est-elle du bon type if VarType( voEnumDict ) <> varUnknown then raise Exception.Create( 'L''Enumerator récupéré n''est pas valide.' ); // caster l'Enumerator, très important !! voEnumerator := IUnknown( voEnumDict ) as IEnumVariant; // parcourir l'Enumerator while voEnumerator.Next( 1, voElement, viFetched ) = S_OK do CallBack( voElement ); except on E: Exception do begin Add_DBLogEvent( viLogApplicationCode, K_LogSevereError, 'incObj_Tools : Enumerate ', E.Message ); raise; end; end; end;
Ainsi je peux utiliser comme CallBack soit une procédure soit une méthode.
Code : Sélectionner tout - Visualiser dans une fenêtre à part TOleVariantProcedureObject = procedure (var poElement: OleVariant) of object;
Le problème est le suivant : j'obtiens une Opération de variant incorrecte...
Voici un exemple d'appel :
Le problème semble subvenir lorsque j'utilises l'objet COM (ou celui qui le contient) à l'intérieur de ma procédure ForEach. Je tient à préciser que le code contenu dans Enumerate pour parcourir l'interface lEnumVariant est valide car si je fais tout dans le même bloc ça passe sans problèmes.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 procedure TMaClasse.FaireQQchose(); var voFields: IDispatch; procedure ForEach( var poElement: OleVariant ); begin // fais des choses end; begin // voFields contient un objet COM supportant lEnumVariant Enumerate( voFields, @ForEach ); end;
Si vous avez des idées, je suis preneur.
Partager