![]() |
Supports verständnis problem
Ich erstelle ein Com Objekt auf diese weise.
Delphi-Quellcode:
Wenn ich auf das IWmpEffects2 caste funktioniert es auf verschiedener weise
function TWMPHelper.InitVis(VisGUID: TGuid; PresetIndex: Integer): Bool;
var ObjInstance : IUnknown; begin Result := False; if CoCreateInstance(VisGUID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IUnknown, ObjInstance) = S_OK then begin // Versuch auf IWmpEffects zu casten. Bei einem Fehlschlag, // wird Nil zurück gegeben und die ObjInstance // unterstützt das Interface IWmpEffects nicht. _IWmpEffects := ObjInstance as IWMPEffects; if Assigned(_IWmpEffects) then // Versuch auf IWmpEffects2 zu casten. Bei einem Fehlschlag, // wird Nil zurück gegeben und die ObjInstance // unterstützt das Interface IWmpEffects2 nicht. if Supports(_IWmpEffects, IID_IWMPEffects2, _IWmpEffects2) then _IWmpEffects2 := ObjInstance as IWmpEffects2; // wird das Interface IWmpEffects2 unterstützt, brauchen // wir das Interface IWmpEffects nicht mehr. if Assigned(_IWmpEffects2) then _IWmpEffects := nil; // Erstes Preset setzen. Das muss sein da es ansonsten bei // einigen Visualisierungen zu einer AccessViolation Exception führt. SetCurrentPreset(PresetIndex); Result := True; end; end; warum das so ist da komme ich nicht hinter.
Delphi-Quellcode:
funktioniert!
Supports(_IWmpEffects, IID_IWMPEffects2, _IWmpEffects2)
aber auch das!
Delphi-Quellcode:
Supports(_IWmpEffects, IID_IWMPEffects2, ObjInstance)
ObjInstance wäre in den fall dann IWmpEffects. und das geht ebenfalls
Delphi-Quellcode:
Was mache ich falsch?
Supports(_IWmpEffects, IID_IWMPEffects, ObjInstance)
Oder warum führen alle Aufrufe zum gleichen Ergebnis? Sorry gehört zum gleichen Thema.. Kann man CoCreateInstance irgendwo freigeben ? Denn die eine Visualisierung funktioniert nicht wenn ich nicht vorher CoUninitialize aufrufe. EDIT: Hab es nochmal korrigiert. gruss |
AW: Supports verständnis problem
Supports kann den Typ der Variablen nicht gegen den angegebene Interface-Typ prüfen.
Ansonsten verstehe ich nicht, wo das Problem liegt. ![]() |
AW: Supports verständnis problem
Zitat:
Also wenn du schon verlinkst dann ist das die Antwort auf deine frage. Zitat:
Wie du sehen kannst gebe ich unterschiedliche Interface an und trotzdem ist das Ergebnis immer gleich. Warum ? gruss |
AW: Supports verständnis problem
Du kannst das auch so schreiben (wird dann evtl. verständlicher)
Delphi-Quellcode:
oder auch so
function TWMPHelper.InitVis(VisGUID: TGuid; PresetIndex: Integer): Bool;
var ObjInstance : IUnknown; begin Result := False; if CoCreateInstance(VisGUID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IUnknown, ObjInstance) = S_OK then begin // Versuch auf IWmpEffects zu casten. Bei einem Fehlschlag, // wird Nil zurück gegeben und die ObjInstance // unterstützt das Interface IWmpEffects nicht. if Supports( ObjInstance, IID_IWMPEffects, _IWmpEffects ) then // Versuch auf IWmpEffects2 zu casten. Bei einem Fehlschlag, // wird Nil zurück gegeben und die ObjInstance // unterstützt das Interface IWmpEffects2 nicht. if Supports( ObjInstance, IID_IWMPEffects2, _IWmpEffects2) then // wird das Interface IWmpEffects2 unterstützt, brauchen // wir das Interface IWmpEffects nicht mehr. _IWmpEffects := nil; // Erstes Preset setzen. Das muss sein da es ansonsten bei // einigen Visualisierungen zu einer AccessViolation Exception führt. SetCurrentPreset(PresetIndex); Result := True; end; end;
Delphi-Quellcode:
function TWMPHelper.InitVis(VisGUID: TGuid; PresetIndex: Integer): Bool;
var ObjInstance : IUnknown; begin Result := False; if CoCreateInstance(VisGUID, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IUnknown, ObjInstance) = S_OK then begin // Versuch auf IWmpEffects2 zu casten. Bei einem Fehlschlag, // wird Nil zurück gegeben und die ObjInstance // unterstützt das Interface IWmpEffects2 nicht. if Supports( ObjInstance, IID_IWMPEffects2, _IWmpEffects2 ) then _IWmpEffects = nil else // Versuch auf IWmpEffects zu casten. Bei einem Fehlschlag, // wird Nil zurück gegeben und die ObjInstance // unterstützt das Interface IWmpEffects nicht. Supports( ObjInstance, IID_IWMPEffects, _IWmpEffects); // Erstes Preset setzen. Das muss sein da es ansonsten bei // einigen Visualisierungen zu einer AccessViolation Exception führt. SetCurrentPreset(PresetIndex); Result := True; end; end; |
AW: Supports verständnis problem
Danke.. Aber verstehe immer noch nicht warum alle vergleiche zum gleichen Ergebnis führen.
Was ist falsch und was richtig. Hmmm :? In *.Net ist das so einfach und hier so kompliziert verstehen tut man das nicht so recht.
Code:
wenn fertig dann
TryCast(ObjInstance, IWmpEffects)
Code:
und gut ist.
TryCast(ObjInstance, IWmpEffects2)
gruss |
AW: Supports verständnis problem
Var-Parameter müssen immer vom selben Typ sein, weswegen Supports so nicht funktionieren könnte (außer man hätte mit bissl Compilermagic nachgeholfen).
Also wurde der Var-Parameter typlos angelegt und intern wird "blind" auf IInterface gegastet, da nicht geprüft werden kann, was wirklich als Parameter reingegeben wurde. Im Grunde bekommt man bei allem, was zufällig 4 Byte (8 bei Win64) groß ist, das Interface reingeschoben. Und bei Kleinerem bekommt man eventuelle Zugriffsverletzungen, oder zumindestens einen Buffer-Overrun. Fazit: Du mußt prüfen. PS: Bei meinem aktuellen Projekt geh ich einen anderen/neueren Weg. Es gibt da z.B. folgende Methoden und vorallem die Letzte ist Interessanter.
Delphi-Quellcode:
Dort wird dann vir RTTI die GUID ausgelesen und entsprechend verwendet.
function SupportsIDEService(Service: TGUID): Boolean; inline;
function GetIDEService (Service: TGUID): IInterface; inline; function TryGetIDEService (Service: TGUID; out Intf): Boolean; inline; property IDEServices: IBorlandIDEServices read GetIDEServices; function IDEService<I: IInterface>: I; Im Prinzip wäre auch sowas möglich, wie
Delphi-Quellcode:
, aber da Delphi die Interfaces bai Übergabe an einen GUD-Parameter automatisch "konvertiert", lohnt sich das nicht.
function Supports<I: IInterface>: Boolean;
Aber
Delphi-Quellcode:
müsste auch funktionieren.
function Supports<I: IInterface>(var Intf: I): Boolean;
Was macht TryCast? [edit] Achso, das ist fast wie ein AS (DirectCast), nur ohne Exception. Aber gibt es auch den "richtigen2 Interfacetyp als Result zurück? [edit2] Es ist also etwas wie mein IDEService<I: IInterface>: I; , nur daß ich eine Exception werfe und die stattdessen ein INothing (in Delphi wohl besser ein nil) zurückgeben. |
AW: Supports verständnis problem
Warum sollte das auch nicht gehen?
Delphi-Quellcode:
es geht ja auch das einfach so
IWmpEffects = interface( IUnknown )
... end; IWmpEffects2 = interface( IWmpEffects ) ... end; var ObjInstance : IUnknown; _IWmpEffects : IWmpEffects; _IWmpEffects2 : IWmpEffects2; // Wenn die Referenz in _IWmpEffects das Interface IID_IWMPEffects2 unterstützt // dann stelle eine Interface-Referenz in _IWmpEffects2, ansonsten NIL Supports( _IWmpEffects, IID_IWMPEffects2, _IWmpEffects2 ); // Wenn die Referenz in _IWmpEffects das Interface IID_IWMPEffects2 unterstützt // dann stelle eine Interface-Referenz in ObjInstance, ansonsten NIL Supports( _IWmpEffects, IID_IWMPEffects2, ObjInstance ); // Wenn die Referenz in _IWmpEffects das Interface IID_IWMPEffects unterstützt // dann stelle eine Interface-Referenz in ObjInstance, ansonsten NIL Supports( _IWmpEffects, IID_IWMPEffects, ObjInstance );
Delphi-Quellcode:
Fraglich ist ja nur, welchen Sinn
ObjInstance := _IWmpEffects;
// oder ObjInstance := _IWmpEffects2;
Delphi-Quellcode:
haben kann. Mit
Supports( _IWmpEffects, IID_IWMPEffects2, ObjInstance );
Delphi-Quellcode:
habe ich ja nur die Möglichkeit auf
ObjInstance
Delphi-Quellcode:
zuzugreifen und müsste schon wieder mit
IUnknown
Delphi-Quellcode:
prüfen/casten.
Supports
|
AW: Supports verständnis problem
Zitat:
Es gibt aber auch Plugins welche NUR das IWmpEffects verwenden und dann keinen zugriff auf das IWmpEffects2 haben dürfen. Deshalb muss ich casten. Mir geht es um den richtigen weg so das ich weis was zugehörig ist und nicht irgend etwas da reinklatsche.
Delphi-Quellcode:
Mit dem IWmpEffects2 kann ich dann alle Funktionen des IWmpEffects verwenden aber nicht umgekehrt.
IWMPEffects = interface(IUnknown)
['{D3984C13-C3CB-48e2-8BE5-5168340B4F35}'] // Render using the rectangle on the normalized device context //void Render(ref TimedLevel levels, IntPtr hdc, ref RECT r); function Render(var pLevels : TimedLevel; hdc : HDC; var prc : TRect): HRESULT; stdcall; // provides the no. channels, sample rate and title of the audio currently playing function MediaInfo(lChannelCount : longint; lSampleRate : longint; bstrTitle : WideString): HRESULT; stdcall; // called to retrieive the capabilities of the effect (fullscreen? property page?, etc.) function GetCapabilities(var pdwCapabilities : longint): HRESULT; stdcall; // retrieve the display title of the effect function GetTitle(var bstrTitle : WideString): HRESULT; stdcall; // retrieve the title for a preset function GetPresetTitle(nPreset : LongInt; var bstrPresetTitle : WideString): HRESULT; stdcall; // retrieve the number of presets this effect supports function GetPresetCount(var pnPresetCount : LongInt): HRESULT; stdcall; // set / get the current preset function SetCurrentPreset(nPreset : LongInt): HRESULT; stdcall; function GetCurrentPreset(var pnPreset : LongInt): HRESULT; stdcall; // display the property page of the effect (if there is one) function DisplayPropertyPage(hwndOwner : HWND): HRESULT; stdcall; // This method will be called when the effect is to start and stop full screen // rendering (if supported) function GoFullscreen(fFullScreen : BOOL): HRESULT; stdcall; // This method will get called after a successful call to GoFullScreen to render // the effect. Return failure from this method to signal loss of full screen. function RenderFullScreen(var pLevels : TimedLevel): HRESULT; stdcall; end; IWMPEffects2 = interface(IWMPEffects) ['{695386EC-AA3C-4618-A5E1-DD9A8B987632}'] // Called by Windows Media Player to provide visualization access to the // core Windows Media Player APIs. function SetCore(var pPlayer : IWMPCore): HRESULT; stdcall; // Called by Windows Media Player to instantiate a visualization window function Create(hwndParent : HWND): HRESULT; stdcall; // Called by Windows Media Player to destroy a visualization window // instantiated in the Create method. function Destroy: HRESULT; stdcall; //Called by Windows Media Player to inform the visualization that a new //media item has been loaded. function NotifyNewMedia(var pMedia : IWMPMedia): HRESULT; stdcall; // Called by Windows Media Player to pass window messages to a visualization. function OnWindowMessage(msg : UINT; WParam : WPARAM; LParam : LPARAM; var plResultParam : LRESULT): HRESULT; stdcall; // Called by Windows Media Player to render a windowed visualization. function RenderWindowed(var pData : TimedLevel; fRequiredRender : BOOL): HRESULT; stdcall; end; Habe da wirklich ein Verständnis Probleme. Die sich dann verständlicherweise auf Fehler auswirken. Zitat:
Wenn da so ein Kuddelmuddel ist. Ich glaube wenn ich da irgend etwas einfügen kann und zugriff auf das IWmpEffects2 Interface bekomme ist das sehr kritisch. Zitat:
gruss |
AW: Supports verständnis problem
Ja das mit dem Casten habe ich in #4 doch mal etwas umgeschrieben und macht doch genau das, was du möchtest mit weniger Code und ohne "um die Ecke" zu gehen.
Es macht doch aber keinen Sinn von etwas Speziellem (
Delphi-Quellcode:
) auf etwas Universelleres (
IWmpEffects
Delphi-Quellcode:
) zu casten, denn das kann man einfach zuweisen.
IUnknown
|
AW: Supports verständnis problem
Ich verstehe das Problem leider nicht. Wenn du bei Supports IID_IWMPEffects2 angibst, bekommst du zurück, ob dieses Interface unterstützt wird. Dementsprechend kannst du dann auch damit arbeiten. Und ansonsten setzt du die Interfacereferenz vom Typ IWMPEffects2 auf nil. Genauso mit IWMPEffects. Das as brauchst du überhaupt nicht.
Wenn du nun eine Aktion durchführen willst, die nur von IWMPEffects2 unterstützt wird, musst du nur schauen, ob das Assigned ist... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz