URLDownloadToFile(): Welche Callbacks von IBindStatusCallback nutzt es?



  • Hey!

    Ich frage mich, welche Callbacks von IBindStatusCallback die Funktion URLDownloadToFile() nutzt.

    Hier sind erstmal die Callbacks des Interfaces aufgelistet:
    http://msdn.microsoft.com/en-us/library/ms775060(VS.85).aspx

    Dazu kommen noch QueryInterface(), AddRef() und Release() von IUnknown.
    Muss ich diese implementieren?

    In diesem sample...
    http://www.codeguru.com/cpp/i-n/internet/generalinternet/article.php/c3467
    ...wird das nämlich implementiert, mit ++m_ulObjRefCount usw...

    Habe ich leaks, wenn ich das nicht implementiere, also NULL oder so zurückgebe?

    Ich bitte um eine Beschreibung, was ich implementieren muss und was ich implementieren kann und welche dieser Funktionen überhaupt von URLDownloadToFile() genutzt werden.

    Danke sehr!

    😕



  • AddRef & Release würde ich schon implementieren, vielleicht wertet URLDownloadToFile ja den Rückgabewert von AddRef oder Release aus.
    Soweit ich der MSDN entnehmen kann, brauchst du sonst als Callback nur OnProgress, was bei mir bis jetzt auch immer gereicht hat.

    edit: Und bei QueryInterface gibst du halt immer E_NOINTERFACE zurück.



  • Danke erstmal.
    Allerdings wüsste ich es gerne ganz genau.
    Das codeguru-Beispiel implementiert zB. für QueryInterface() in etwa sowas:

    *ppvObject = NULL;
    
    	if (::IsEqualIID(riid, __uuidof(IUnknown)))
    		*ppvObject = this;
    	else if (::IsEqualIID(riid, __uuidof(IBindStatusCallback)))
    		*ppvObject = static_cast<IBindStatusCallback *>(this);
    
    	if (*ppvObject)
    	{
    		(*reinterpret_cast<LPUNKNOWN *>(ppvObject))->AddRef();
    		return S_OK;
    	}
    
    	return E_NOINTERFACE;
    

    Mit "implementieren" meine ich eigentlich "mehr tun als nur returnen".
    In die Klasse muss es sowieso, sonst gibt es Compilerfehler. Das Interface muss halt komplett sein.

    Also was soll ich bei den ganzen Funktionen machen? Wo return und was? Wo bestimmten Code?

    Und noch eine Frage:
    Kann ich den Download abbrechen, indem ich IBinding::Abort() (jederzeit) aufrufe? IBinding* bekomme ich von OnStartBinding().

    😕



  • Also IBinding::Abort() funktioniert, aber was bedeutet das genau:

    MSDN schrieb:

    This method cannot be called from an implementation of the IBindStatusCallback::OnStartBinding method

    Nur, dass ich Abort() nicht IN OnStartBinding() aufrufen darf? Aber ausserhalb bevor oder während OnStartBinding() aufgerufen wird?

    Ist IBinding::Abort() eigentlich thread-safe? Denn URLDownloadToFile() läuft bei mir in einem separaten Thread, während ich IBinding::Abort() von einem anderen Thread (Mainthread mit einer message loop) aufrufen würde (WndProc).

    Muss ich irgendwas synchronisieren?

    😕



  • Zum Abbrechen gibst du in OnProgress einfach E_ABORT zurück (steht auch in der MSDN zu URLDownloadToFile).

    Bind0r schrieb:

    Das codeguru-Beispiel implementiert zB. für QueryInterface() in etwa sowas

    Ja, stimmt. Genau so machst du's dann auch.



  • Tja, aber wenn der Download hängt, möchte ich trotzdem abbrechen können.

    Ja, aber warum soll ich es so machen? Ich will halt wissen, was ich programmiere. Copy&Paste ist gut, wenn es richtig ist und man es dann auch versteht.

    Danke trotzdem.



  • Bind0r schrieb:

    Ja, aber warum soll ich es so machen? Ich will halt wissen, was ich programmiere.

    Dann schau mal in der MSDN nach, da ist alles ausreichend beschrieben, auch mit Hintergründen (z.B. hier, insbesondere von da ausgehende Links).

    Bind0r schrieb:

    Tja, aber wenn der Download hängt, möchte ich trotzdem abbrechen können.

    Müsste man mal ausprobieren/herausfinden, wie sich URLDownloadToFile verhält, also ob beim Hänger kein OnProgress mehr kommt, oder ob's dann immer mit dem gleichen Prozentwert aufgerufen wird (aber halt immer noch regelmäßig).



  • Ich versteh's nicht so ganz. Ruft der Client (URLDownloadToFile) den Callback zusätzlich zu seinem eigenen Interface-Callback auf? Warum sollte mich ein AddRef/Release-Callback interessieren? Aufgerufen werden sie nämlich.
    QueryInterface wäre in dem Fall ja auch unnötig, ich könnte ja nur bestimmen, ob ein Interface supported wird.
    Also kann ich hier ja einfach immer S_OK zurückgeben und gut ist's, nicht?

    Wegen OnProgress, wenn der Download hängt, wird es auch nicht aufgerufen. Ist ja kein "Progress", wenn der Server länger für ne Antwort braucht oder gar abschmiert.

    Wäre jetzt aber auch eher unsinnig, wenn IBinding::Abort() nicht threadsafe wäre.



  • Warum wird im codeguru-Beispiel einmal...

    *ppvObject = this;
    

    ...und einmal...

    *ppvObject = static_cast<IBindStatusCallback *>(this);
    

    ...geschrieben? Das macht doch keinen Unterschied, weils eh ein void-Pointer ist, oder kommt es da auf den übergebenen Pointertypen an?
    Aber welchen Sinn hat es, das zu unterscheiden?

    Und das...

    (*reinterpret_cast<LPUNKNOWN *>(ppvObject))->AddRef();
    

    ...ist mir auch nicht klar. Wozu soll das gut sein?

    Es funktioniert auch ohne all dem. Es funktioniert sogar, wenn ich immer E_NOINTERFACE zurückgebe und auch wenn ich vorher noch...

    *ppvObject = 0;
    ppvObject = 0;
    

    ...schreibe...

    😕



  • Ich fand jetzt auch eine Implementierung von QueryInterface(), mit einfach nur:

    if(GetInterface(IID, Obj))
        return S_OK;
    else
        return E_NOINTERFACE;
    

    Ich kenn mich einfach nicht aus... warum wird QueryInterface() überhaupt aufgerufen, und warum so oft. Angeblich (wo gelesen) werden mehrere Interfaces requested. Die müssten dann aber doch alle einzeln behandelt werden... ach kA mehr 😞


Anmelden zum Antworten