L'appel de idispatch directement
Comment intégrer les simples capacités de programmation en Delphi. Il pourrait être utile d'appeler une méthode, décrite comme une chaîne de caractères, sur une interface, défini par une chaîne de caractères contenant quelque chose comme ' MyLib.MyObject1'.
Cette unité, qui expose un peu de fonction que vous pouvez appeler à l'accès interface IDispatch plus facilement.
& & & & & & & & & & & & & & & -
{////////////////////////////////////////////////////////////////
Nom de l'unité: DispatchLib
le But de l'unité:
& ! & ! & ! & nbsp Expose une fonction pour manipuler les objets COM qui mettent en œuvre des
& ! & ! & ! & nbsp interface IDispatch.
& ! & ! & ! & nbsp Vous pouvez appeler les méthodes ou propriétés directement ou vous pouvez
& ! & ! & ! & nbsp liste de toutes les fonctions d'un objet TStringList.
& ! & ! & ! & nbsp Un exemple:
& ! & ! & ! & nbsp procédure fa(sl: TStringList)
& ! & ! & ! & nbsp var
& ! & ! & ! & ! & ! & ! & ! & nbsp un: variant
& ! & ! & ! & ! & ! & ! & ! & nbsp s: string
& ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & nbsp a := CreateOLEObject('microsoft.msxml')
& ! & ! & ! & ! & ! & ! & ! & nbsp DocumentIDispatch(a, sl)
& ! & ! & ! & ! & ! & ! & ! & nbsp ExecuteOnDispatchMultiParam(a, 'loadxml', ['b'])
& ! & ! & ! & ! & ! & ! & ! & nbsp s := ExecuteOnDispatchMultiParam(a, 'xml', [])
& ! & ! & ! & ! & ! & ! & ! & nbsp MessageDlg(s, mtInformation, [bakang], 0)
& ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp Code est basé sur une unité que j'ai trouvé sur internet, mais il contenait
& ! & ! & ! & nbsp certains bogues sérieux et il n'a pas plus d'un paramètre.
quelque Chose d'inhabituel:
encodé par: VJ
Date: 17.07.2001
Révision de l'histoire:
////////////////////////////////////////////////////////////////}
unité de DispatchLib
interface
& nbsp & nbsp ActiveX,
& nbsp & nbsp sysutils,
& nbsp & nbsp classes
type
& nbsp & nbsp exMethodNotSupported = classe(Exception)
& nbsp & nbsp exIDispatchCallError = classe(Exception)
fonction de ExecuteOnDispatchMultiParam(TargetObj: IDispatch MethodName: string ParamValues: tableau de const): OleVariant
procédure DocumentIDispatch(ID: IDispatch var SL: TStringList)
procédure DocumentIDispatch2(ID: IDispatch var SLNames: TStringList)
fonction de ElementDescriptionToString(a: TElemDesc): string
application
fonction de ElementDescriptionToString(a: TElemDesc): string
begin
& nbsp & nbsp cas une.tdesc.vt
& ! & ! & ! & nbsp VT_I4: Result := 'int'
& ! & ! & ! & nbsp VT_R8: Result := 'double'
& ! & ! & ! & nbsp VT_BSTR: Result := 'string'
& nbsp & nbsp else
& ! & ! & ! & nbsp Résultat := '
& nbsp & nbsp fin
fin
procédure DocumentIDispatch(ID: IDispatch var SL: TStringList)
var
& nbsp & nbsp res: HResult
& nbsp & nbsp Comte, boucle, loop2, loop3: integer
& nbsp & nbsp TI: ITypeinfo
& nbsp & nbsp zep: PTypeAttr
& nbsp & nbsp pFD: PFuncDesc
& nbsp & nbsp varDesc: pVarDesc
& nbsp & nbsp numFunctions: integer
& nbsp & nbsp numParams: integer
& nbsp & nbsp funcDispID: integer
& nbsp & nbsp noms: TBStrList
& nbsp & nbsp numReturned: integer
& nbsp & nbsp functionstr: widestring
& nbsp & nbsp cacher: boolean
begin
& nbsp & nbsp assert(SL <> nil, 'SL ne peut pas être nul')
& nbsp & nbsp SL.Clair
& nbsp & nbsp res := ID.GetTypeInfoCount(Nombre)
& nbsp & nbsp si réussi(res), puis commencer
& ! & ! & ! & nbsp pour la boucle := 0 à Count - 1 do begin
& ! & ! & ! & ! & ! & nbsp res := ID.GetTypeInfo(boucle, 0, TI)
& ! & ! & ! & ! & ! & nbsp si réussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.GetTypeAttr(pTA)
& ! & ! & ! & ! & ! & ! & ! & nbsp si réussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si pTA^.typekind = TKIND_DISPATCH puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp numFunctions := pTA^.cFuncs
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pour loop2 := 0 pour numFunctions - 1 do begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.GetFuncDesc(loop2, pFD)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si réussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp funcDispID := vfi^.memid
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp numParams := vfi^.cParams
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.Getnames a(funcDispID, @noms, numParams 1, numReturned)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si réussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := '
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si numReturned > 0, alors
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionstr noms[0]
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si numReturned > 1 then begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionStr '('
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pour loop3 := 1 à numReturned - 1 do begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si loop3 > 1
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp & ! & ! & ! & ! & ! & nbsp functionstr := functionstr ', '
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr :=
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp & nbsp & nbsp & nbsp noms[loop3] ':'
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & n sp & nbsp ElementDescriptionToString(vfi^.lprgelemdescParam^[loop3 - 1])
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp //functionstr := functionstr noms[numReturned - 1] ')'
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionstr ')'
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp cacher := False
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp // Cache le non-envoi des fonctions
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si (vfi^.wFuncFlags et FUNCFLAG_FRESTRICTED) = FUNCFLAG_FRESTRICTED puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp cacher := True
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp // Masque les fonctions qui ne sont pas prévu pour le script: essentiellement des fonctions redondantes
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si (vfi^.wFuncFlags et FUNCFLAG_FHIDDEN) = FUNCFLAG_FHIDDEN puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp cacher := True
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si pas cacher puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp SL.ajouter(functionstr)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp TI.ReleaseFuncDesc(pFD)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & nbsp & ! & ! & ! & ! & nbsp TI.ReleaseTypeAttr(pTA)
& ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp fin
& nbsp & nbsp fin
& nbsp & nbsp else
& ! & ! & ! & nbsp raise Exception.Create('GetTypeInfoCount Échoué')
fin
procédure DocumentIDispatch2(ID: IDispatch var SLNames: TStringList)
var
& nbsp & nbsp res: HResult
& nbsp & nbsp Comte, boucle, loop2, loop3: integer
& nbsp & nbsp TI: ITypeinfo
& nbsp & nbsp zep: PTypeAttr
& nbsp & nbsp pFD: PFuncDesc
& nbsp & nbsp varDesc: pVarDesc
& nbsp & nbsp numFunctions: integer
& nbsp & nbsp numParams: integer
& nbsp & nbsp funcDispID: integer
& nbsp & nbsp noms: TBStrList
& nbsp & nbsp numReturned: integer
& nbsp & nbsp functionstr: widestring
& nbsp & nbsp cacher: boolean
begin
& nbsp & nbsp SLNames.Clair
& nbsp & nbsp res := ID.GetTypeInfoCount(Nombre)
& nbsp & nbsp si réussi(res), puis commencer
& ! & ! & ! & nbsp pour la boucle := 0 à Count - 1 do begin
& ! & ! & ! & ! & ! & nbsp res := ID.GetTypeInfo(boucle, 0, TI)
& ! & ! & ! & ! & ! & nbsp si réussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.GetTypeAttr(pTA)
& ! & ! & ! & ! & ! & ! & ! & nbsp si réussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si pTA^.typekind = TKIND_DISPATCH puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp numFunctions := pTA^.cFuncs
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pour loop2 := 0 pour numFunctions - 1 do begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.GetFuncDesc(loop2, pFD)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si pas réussi(res) puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Continuer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp funcDispID := vfi^.memid
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp numParams := vfi^.cParams
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.Getnames a(funcDispID, @noms, numParams 1, numReturned)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si pas réussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp TI.ReleaseFuncDesc(pFD)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Continuer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp & nbsp // Cache le non-envoi des fonctions
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si (vfi^.wFuncFlags et FUNCFLAG_FRESTRICTED) = FUNCFLAG_FRESTRICTED puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Continuer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp // Masque les fonctions qui ne sont pas prévu pour le script: essentiellement des fonctions redondantes
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si (vfi^.wFuncFlags et FUNCFLAG_FHIDDEN) = FUNCFLAG_FHIDDEN puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Continuer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp & nbsp & nbsp functionstr := '
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si numReturned > 0 then begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionstr noms[0]
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionstr '('
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si numReturned > 1 then begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pour loop3 := 1 à numReturned - 1 do begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si loop3 > 1
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionstr ','
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr :=
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ElementDescriptionToString(vfi^.lprgelemdescParam^[loop3 - 1])
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp & nbsp SLNames.Ajouter(functionstr ')')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp TI.ReleaseFuncDesc(pFD)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp TI.ReleaseTypeAttr(pTA)
& ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp fin
& nbsp & nbsp fin
& nbsp & nbsp else
& ! & ! & ! & nbsp raise Exception.Create('GetTypeInfoCount Échoué')
fin
{////////////////////////////////////////////////////////////////
Nom: ExecuteOnDispatchMultiParam
Objet:
& ! & ! & ! & nbsp executer méthode sur un objet COM.
Auteur: VJ
Date: 07.07.2001
Histoire:
////////////////////////////////////////////////////////////////}
fonction de ExecuteOnDispatchMultiParam(
& nbsp & nbsp TargetObj: IDispatch
& nbsp & nbsp MethodName: string
& nbsp & nbsp ParamValues: tableau de const): OleVariant
var
& nbsp & nbsp large: widestring
& nbsp & nbsp disps: TDispIDList
& nbsp & nbsp panswer: ^olevariant
& nbsp & nbsp réponse: olevariant
& nbsp & nbsp dispParams: TDispParams
& nbsp & nbsp aexception: TExcepInfo
& nbsp & nbsp pVarArg: PVariantArgList
& nbsp & nbsp res: HResult
& nbsp & nbsp ParamCount, i: integer
begin
& nbsp & nbsp Result := false
& nbsp & nbsp // préparer l'appel de la fonction
& nbsp & nbsp ParamCount := Haut(ParamValues) 1
& nbsp & nbsp large := MethodName
& nbsp & nbsp pVarArg := nil
& nbsp & nbsp si ParamCount > 0, alors
& ! & ! & ! & nbsp GetMem(pVarArg, ParamCount * sizeof(TVariantArg))
& nbsp & nbsp essayer
& ! & ! & ! & nbsp // obtenir dispid de la méthode
& ! & ! & ! & nbsp si pas réussi(TargetObj.GetIDsOfNames(GUID_NULL, @large, 1, 0, @disps))
& ! & ! & ! & ! & ! & nbsp élever exMethodNotSupported.Créer ('Cet objet ne prend pas en charge cette méthode')
& ! & ! & ! & nbsp pAnswer : = réponse @
& ! & ! & ! & nbsp // préparation de paramètres
& ! & ! & ! & nbsp for i := 0 to ParamCount - 1 do begin
& ! & ! & ! & ! & ! & nbsp cas ParamValues[ParamCount - 1 - i].VType de
& ! & ! & ! & ! & ! & ! & ! & nbsp vtInteger: commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].vt := VT_I4
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].lVal := ParamValues[ParamCount - 1 - i].VInteger
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & nbsp vtExtended: commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].vt := VT_R8
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].dblVal := ParamValues[ParamCount - 1 - i].VExtended^
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & nbsp vtString, vtAnsiString, vtChar: commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].vt := VT_BSTR
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].bstrVal := PWideChar(WideString(PChar(ParamValues[ParamCount - 1 - i].VString)))
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp else
& ! & ! & ! & ! & ! & ! & ! & nbsp raise Exception.CreateFmt('Unsuported type de paramètre avec l'indice %d', [i])
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp // préparation de l'expédition paramètres
& ! & ! & ! & nbsp dispparams.rgvarg := pVarArg
& ! & ! & ! & nbsp dispparams.rgdispidNamedArgs := nil
& ! & ! & ! & nbsp dispparams.cArgs := ParamCount
& ! & ! & ! & nbsp dispparams.cNamedArgs := 0
& ! & ! & ! & nbsp // faire appel de IDispatch
& ! & ! & ! & nbsp res := TargetObj.Invoke(disps[0],
& ! & ! & ! & ! & ! & nbsp GUID_NULL, 0, DISPATCH_METHOD ou DISPATCH_PROPERTYGET,
& ! & ! & ! & ! & ! & nbsp dispParams, pAnswer, @aexception, nil)
& ! & ! & ! & nbsp // vérifier le résultat
& ! & ! & ! & nbsp si res <> 0 then
& ! & ! & ! & ! & ! & nbsp élever exIDispatchCallError.CreateFmt(
& ! & ! & ! & ! & ! & ! & ! & ! 'appel de la Méthode unsuccessfull. %s (%s).',
& ! & ! & ! & ! & ! & ! & ! & nbsp [string(aexception.bstrDescription), chaîne(aexception.bstrSource)])
& ! & ! & ! & nbsp // retourne le résultat
& ! & ! & ! & nbsp Résultat := réponse
& nbsp & nbsp enfin
& ! & ! & ! & nbsp si ParamCount > 0, alors
& ! & ! & ! & ! & ! & nbsp FreeMem(pVarArg, ParamCount * sizeof(TVariantArg))
& nbsp & nbsp fin
fin
à la fin.
L'appel de idispatch directement
L'appel de idispatch directement : Plusieurs milliers de conseils pour vous faciliter la vie.
Comment integrer les simples capacites de programmation en Delphi. Il pourrait etre utile d'appeler une methode, decrite comme une chaîne de caracteres, sur une interface, defini par une chaîne de caracteres contenant quelque chose comme ' MyLib.MyObject1'.
Cette unite, qui expose un peu de fonction que vous pouvez appeler a l'acces interface IDispatch plus facilement.
& & & & & & & & & & & & & & & -
{////////////////////////////////////////////////////////////////
Nom de l'unite: DispatchLib
le But de l'unite:
& ! & ! & ! & nbsp Expose une fonction pour manipuler les objets COM qui mettent en œuvre des
& ! & ! & ! & nbsp interface IDispatch.
& ! & ! & ! & nbsp Vous pouvez appeler les methodes ou proprietes directement ou vous pouvez
& ! & ! & ! & nbsp liste de toutes les fonctions d'un objet TStringList.
& ! & ! & ! & nbsp Un exemple:
& ! & ! & ! & nbsp procedure fa(sl: TStringList)
& ! & ! & ! & nbsp var
& ! & ! & ! & ! & ! & ! & ! & nbsp un: variant
& ! & ! & ! & ! & ! & ! & ! & nbsp s: string
& ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & nbsp a := CreateOLEObject('microsoft.msxml')
& ! & ! & ! & ! & ! & ! & ! & nbsp DocumentIDispatch(a, sl)
& ! & ! & ! & ! & ! & ! & ! & nbsp ExecuteOnDispatchMultiParam(a, 'loadxml', ['b'])
& ! & ! & ! & ! & ! & ! & ! & nbsp s := ExecuteOnDispatchMultiParam(a, 'xml', [])
& ! & ! & ! & ! & ! & ! & ! & nbsp MessageDlg(s, mtInformation, [bakang], 0)
& ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp Code est base sur une unite que j'ai trouve sur internet, mais il contenait
& ! & ! & ! & nbsp certains bogues serieux et il n'a pas plus d'un parametre.
quelque Chose d'inhabituel:
encode par: VJ
Date: 17.07.2001
Revision de l'histoire:
////////////////////////////////////////////////////////////////}
unite de DispatchLib
interface
& nbsp & nbsp ActiveX,
& nbsp & nbsp sysutils,
& nbsp & nbsp classes
type
& nbsp & nbsp exMethodNotSupported = classe(Exception)
& nbsp & nbsp exIDispatchCallError = classe(Exception)
fonction de ExecuteOnDispatchMultiParam(TargetObj: IDispatch MethodName: string ParamValues: tableau de const): OleVariant
procedure DocumentIDispatch(ID: IDispatch var SL: TStringList)
procedure DocumentIDispatch2(ID: IDispatch var SLNames: TStringList)
fonction de ElementDescriptionToString(a: TElemDesc): string
application
fonction de ElementDescriptionToString(a: TElemDesc): string
begin
& nbsp & nbsp cas une.tdesc.vt
& ! & ! & ! & nbsp VT_I4: Result := 'int'
& ! & ! & ! & nbsp VT_R8: Result := 'double'
& ! & ! & ! & nbsp VT_BSTR: Result := 'string'
& nbsp & nbsp else
& ! & ! & ! & nbsp Resultat := '
& nbsp & nbsp fin
fin
procedure DocumentIDispatch(ID: IDispatch var SL: TStringList)
var
& nbsp & nbsp res: HResult
& nbsp & nbsp Comte, boucle, loop2, loop3: integer
& nbsp & nbsp TI: ITypeinfo
& nbsp & nbsp zep: PTypeAttr
& nbsp & nbsp pFD: PFuncDesc
& nbsp & nbsp varDesc: pVarDesc
& nbsp & nbsp numFunctions: integer
& nbsp & nbsp numParams: integer
& nbsp & nbsp funcDispID: integer
& nbsp & nbsp noms: TBStrList
& nbsp & nbsp numReturned: integer
& nbsp & nbsp functionstr: widestring
& nbsp & nbsp cacher: boolean
begin
& nbsp & nbsp assert(SL <> nil, 'SL ne peut pas etre nul')
& nbsp & nbsp SL.Clair
& nbsp & nbsp res := ID.GetTypeInfoCount(Nombre)
& nbsp & nbsp si reussi(res), puis commencer
& ! & ! & ! & nbsp pour la boucle := 0 a Count - 1 do begin
& ! & ! & ! & ! & ! & nbsp res := ID.GetTypeInfo(boucle, 0, TI)
& ! & ! & ! & ! & ! & nbsp si reussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.GetTypeAttr(pTA)
& ! & ! & ! & ! & ! & ! & ! & nbsp si reussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si pTA^.typekind = TKIND_DISPATCH puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp numFunctions := pTA^.cFuncs
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pour loop2 := 0 pour numFunctions - 1 do begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.GetFuncDesc(loop2, pFD)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si reussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp funcDispID := vfi^.memid
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp numParams := vfi^.cParams
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.Getnames a(funcDispID, @noms, numParams 1, numReturned)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si reussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := '
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si numReturned > 0, alors
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionstr noms[0]
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si numReturned > 1 then begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionStr '('
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pour loop3 := 1 a numReturned - 1 do begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si loop3 > 1
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp & ! & ! & ! & ! & ! & nbsp functionstr := functionstr ', '
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr :=
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp & nbsp & nbsp & nbsp noms[loop3] ':'
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & n sp & nbsp ElementDescriptionToString(vfi^.lprgelemdescParam^[loop3 - 1])
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp //functionstr := functionstr noms[numReturned - 1] ')'
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionstr ')'
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp cacher := False
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp // Cache le non-envoi des fonctions
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si (vfi^.wFuncFlags et FUNCFLAG_FRESTRICTED) = FUNCFLAG_FRESTRICTED puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp cacher := True
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp // Masque les fonctions qui ne sont pas prevu pour le script: essentiellement des fonctions redondantes
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si (vfi^.wFuncFlags et FUNCFLAG_FHIDDEN) = FUNCFLAG_FHIDDEN puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp cacher := True
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si pas cacher puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp SL.ajouter(functionstr)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp TI.ReleaseFuncDesc(pFD)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & nbsp & ! & ! & ! & ! & nbsp TI.ReleaseTypeAttr(pTA)
& ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp fin
& nbsp & nbsp fin
& nbsp & nbsp else
& ! & ! & ! & nbsp raise Exception.Create('GetTypeInfoCount Echoue')
fin
procedure DocumentIDispatch2(ID: IDispatch var SLNames: TStringList)
var
& nbsp & nbsp res: HResult
& nbsp & nbsp Comte, boucle, loop2, loop3: integer
& nbsp & nbsp TI: ITypeinfo
& nbsp & nbsp zep: PTypeAttr
& nbsp & nbsp pFD: PFuncDesc
& nbsp & nbsp varDesc: pVarDesc
& nbsp & nbsp numFunctions: integer
& nbsp & nbsp numParams: integer
& nbsp & nbsp funcDispID: integer
& nbsp & nbsp noms: TBStrList
& nbsp & nbsp numReturned: integer
& nbsp & nbsp functionstr: widestring
& nbsp & nbsp cacher: boolean
begin
& nbsp & nbsp SLNames.Clair
& nbsp & nbsp res := ID.GetTypeInfoCount(Nombre)
& nbsp & nbsp si reussi(res), puis commencer
& ! & ! & ! & nbsp pour la boucle := 0 a Count - 1 do begin
& ! & ! & ! & ! & ! & nbsp res := ID.GetTypeInfo(boucle, 0, TI)
& ! & ! & ! & ! & ! & nbsp si reussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.GetTypeAttr(pTA)
& ! & ! & ! & ! & ! & ! & ! & nbsp si reussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si pTA^.typekind = TKIND_DISPATCH puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp numFunctions := pTA^.cFuncs
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pour loop2 := 0 pour numFunctions - 1 do begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.GetFuncDesc(loop2, pFD)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si pas reussi(res) puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Continuer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp funcDispID := vfi^.memid
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp numParams := vfi^.cParams
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp res := TI.Getnames a(funcDispID, @noms, numParams 1, numReturned)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si pas reussi(res), puis commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp TI.ReleaseFuncDesc(pFD)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Continuer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp & nbsp // Cache le non-envoi des fonctions
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si (vfi^.wFuncFlags et FUNCFLAG_FRESTRICTED) = FUNCFLAG_FRESTRICTED puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Continuer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp // Masque les fonctions qui ne sont pas prevu pour le script: essentiellement des fonctions redondantes
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si (vfi^.wFuncFlags et FUNCFLAG_FHIDDEN) = FUNCFLAG_FHIDDEN puis
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Continuer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp & nbsp & nbsp functionstr := '
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si numReturned > 0 then begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionstr noms[0]
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionstr '('
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si numReturned > 1 then begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pour loop3 := 1 a numReturned - 1 do begin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si loop3 > 1
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr := functionstr ','
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr :=
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp functionstr
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ElementDescriptionToString(vfi^.lprgelemdescParam^[loop3 - 1])
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp & nbsp SLNames.Ajouter(functionstr ')')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp TI.ReleaseFuncDesc(pFD)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp TI.ReleaseTypeAttr(pTA)
& ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp fin
& nbsp & nbsp fin
& nbsp & nbsp else
& ! & ! & ! & nbsp raise Exception.Create('GetTypeInfoCount Echoue')
fin
{////////////////////////////////////////////////////////////////
Nom: ExecuteOnDispatchMultiParam
Objet:
& ! & ! & ! & nbsp executer methode sur un objet COM.
Auteur: VJ
Date: 07.07.2001
Histoire:
////////////////////////////////////////////////////////////////}
fonction de ExecuteOnDispatchMultiParam(
& nbsp & nbsp TargetObj: IDispatch
& nbsp & nbsp MethodName: string
& nbsp & nbsp ParamValues: tableau de const): OleVariant
var
& nbsp & nbsp large: widestring
& nbsp & nbsp disps: TDispIDList
& nbsp & nbsp panswer: ^olevariant
& nbsp & nbsp reponse: olevariant
& nbsp & nbsp dispParams: TDispParams
& nbsp & nbsp aexception: TExcepInfo
& nbsp & nbsp pVarArg: PVariantArgList
& nbsp & nbsp res: HResult
& nbsp & nbsp ParamCount, i: integer
begin
& nbsp & nbsp Result := false
& nbsp & nbsp // preparer l'appel de la fonction
& nbsp & nbsp ParamCount := Haut(ParamValues) 1
& nbsp & nbsp large := MethodName
& nbsp & nbsp pVarArg := nil
& nbsp & nbsp si ParamCount > 0, alors
& ! & ! & ! & nbsp GetMem(pVarArg, ParamCount * sizeof(TVariantArg))
& nbsp & nbsp essayer
& ! & ! & ! & nbsp // obtenir dispid de la methode
& ! & ! & ! & nbsp si pas reussi(TargetObj.GetIDsOfNames(GUID_NULL, @large, 1, 0, @disps))
& ! & ! & ! & ! & ! & nbsp elever exMethodNotSupported.Creer ('Cet objet ne prend pas en charge cette methode')
& ! & ! & ! & nbsp pAnswer : = reponse @
& ! & ! & ! & nbsp // preparation de parametres
& ! & ! & ! & nbsp for i := 0 to ParamCount - 1 do begin
& ! & ! & ! & ! & ! & nbsp cas ParamValues[ParamCount - 1 - i].VType de
& ! & ! & ! & ! & ! & ! & ! & nbsp vtInteger: commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].vt := VT_I4
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].lVal := ParamValues[ParamCount - 1 - i].VInteger
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & nbsp vtExtended: commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].vt := VT_R8
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].dblVal := ParamValues[ParamCount - 1 - i].VExtended^
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & nbsp vtString, vtAnsiString, vtChar: commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].vt := VT_BSTR
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp pVarArg^[i].bstrVal := PWideChar(WideString(PChar(ParamValues[ParamCount - 1 - i].VString)))
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp else
& ! & ! & ! & ! & ! & ! & ! & nbsp raise Exception.CreateFmt('Unsuported type de parametre avec l'indice %d', [i])
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp // preparation de l'expedition parametres
& ! & ! & ! & nbsp dispparams.rgvarg := pVarArg
& ! & ! & ! & nbsp dispparams.rgdispidNamedArgs := nil
& ! & ! & ! & nbsp dispparams.cArgs := ParamCount
& ! & ! & ! & nbsp dispparams.cNamedArgs := 0
& ! & ! & ! & nbsp // faire appel de IDispatch
& ! & ! & ! & nbsp res := TargetObj.Invoke(disps[0],
& ! & ! & ! & ! & ! & nbsp GUID_NULL, 0, DISPATCH_METHOD ou DISPATCH_PROPERTYGET,
& ! & ! & ! & ! & ! & nbsp dispParams, pAnswer, @aexception, nil)
& ! & ! & ! & nbsp // verifier le resultat
& ! & ! & ! & nbsp si res <> 0 then
& ! & ! & ! & ! & ! & nbsp elever exIDispatchCallError.CreateFmt(
& ! & ! & ! & ! & ! & ! & ! & ! 'appel de la Methode unsuccessfull. %s (%s).',
& ! & ! & ! & ! & ! & ! & ! & nbsp [string(aexception.bstrDescription), chaîne(aexception.bstrSource)])
& ! & ! & ! & nbsp // retourne le resultat
& ! & ! & ! & nbsp Resultat := reponse
& nbsp & nbsp enfin
& ! & ! & ! & nbsp si ParamCount > 0, alors
& ! & ! & ! & ! & ! & nbsp FreeMem(pVarArg, ParamCount * sizeof(TVariantArg))
& nbsp & nbsp fin
fin
a la fin.
L'appel de idispatch directement
By commentfaire
L'appel de idispatch directement : Plusieurs milliers de conseils pour vous faciliter la vie.