IPicure/Disp in Icon



  • Glücklicherweise kann man ein Icon ja auch aus einem HICON erstellen. Jetzt mache ich das erstmal so, scheint zu funktionieren:

    public new static Image GetPictureFromIPicture(object picture)
    {
        try
        {
            return System.Windows.Forms.AxHost.GetPictureFromIPicture(picture);
        }
        catch (InvalidCastException)
        {
            Type t = picture.GetType();
            IntPtr handle = (IntPtr)(Int32)t.InvokeMember("Handle", System.Reflection.BindingFlags.GetProperty, null, picture, null);
            return Icon.FromHandle(handle).ToBitmap();
        }
    }
    


  • Oh man
    Speicher doch das Ergebnis erstmal in eine Variable die von diesem Typen ist, und DANN kannst du das Ergebnis entsprechend bearbeiten.

    Keiner zwingt dich das du direkt ein return der Methode machst.

    Wenn du das Ergebnis der Methode in eine Variable des selben Type speichern läßt, dann gibt es auch kein Invalid Cast

    Was du da machst ist total schlechter und dreckiger Code.



  • CSL schrieb:

    Oh man
    Speicher doch das Ergebnis erstmal in eine Variable die von diesem Typen ist, und DANN kannst du das Ergebnis entsprechend bearbeiten.

    ES GIBT KEIN ERGEBNIS!

    // InvalidCastException
    object o = System.Windows.Forms.AxHost.GetPictureFromIPicture(picture);
    


  • Dann ruf doch diese Methode gar nicht erst auf, sondern geh gleich den richtigen Weg.



  • CSL schrieb:

    Dann ruf doch diese Methode gar nicht erst auf, sondern geh gleich den richtigen Weg.

    Welches ist der richtige Weg?



  • Signatur ändern von

    public new static Image GetPictureFromIPicture(object picture)
    

    zu

    public new static Image GetPictureFromIPicture(IPicture picture)
    
    public new static Image GetPictureFromIPicture(IPicture picture)
    {
        return System.Windows.Forms.AxHost.GetPictureFromIPicture(picture);
    }
    

    Wenn deine Methode ein IPicture erwartet, muss es das auch gegeben werden
    Andere Objekte bekommen andere Methoden:

    public new static Image GetPictureFromHandle(object picture)
    {
        Type t = picture.GetType();
        IntPtr handle = (IntPtr)(Int32)t.InvokeMember("Handle", System.Reflection.BindingFlags.GetProperty, null, picture, null);
        return Icon.FromHandle(handle).ToBitmap();
    }
    

    Kannst dir dann eine Helfsmethode bauen:

    public new static Image GetPicture(object picture)
    {
        var iPicture = picture as IPicture;
        if (iPicture != null)
            return GetPictureFromIPicture(iPicture);
        else
            return GetPictureFromHandle(picture);
    }
    

    Exceptions sind dafür da Fehlerfälle ab zu fangen, wenn bekannt ist das "picture" an der stelle auch mal kein "IPicture" sein kann, dann sollte man das beachten.
    Man arbeitet nicht mit Try & Catch im normalen Programmablauf, diese sollten nur Fehlerfälle abfangen.

    Anm.d.R.: GetPicture ist eigentlich Falsch, du möchtest ja ein Image, also währe GetImageFrom passender 😃

    PS. das die Exception innerhalb der aufgerufenen Methode System.Windows.Forms.AxHost.GetPictureFromIPicture geworfen wird, hattest du nicht erwähnt, daher die Verwirrung, ich nahm an das der Return nicht mit der Signatur übereinstimmt. Sorry wenn ich etwas ruppig antwortete.



  • CSL schrieb:

    Exceptions sind dafür da Fehlerfälle ab zu fangen, wenn bekannt ist das "picture" an der stelle auch mal kein "IPicture" sein kann, dann sollte man das beachten.

    Es ist ein IPicture, immer! Ein IPicture kann Bitmaps enthalten, aber eben auch Icons und MetaFiles. In meinem Fall ist nun eben ein Icon.

    CSL schrieb:

    Man arbeitet nicht mit Try & Catch im normalen Programmablauf, diese sollten nur Fehlerfälle abfangen.

    Ich mache das jetzt aber. In meine Augen ist es eher ein Fehler der Implemetierung von AxHost.GetPictureFromIPicture. Denn wenn der interne Cast nicht funktioniert, ist es wohl ein Leichtes, ToBitmap des Icon-Objektes aufzurufen. Und das ein Icon-Objekt bereits existiert, sagt die Exception eindeutig aus. Wer weiß, vielleichtg wird das ja irgendwann einmal nachgerüstet.

    Und ja, mir ist bekannt, dass IPicture auch ein Type-Property bereithält. Aber Late-Bound Calls sind ja nun irgendwie auch nicht so der Bringer...

    Aber das die Exception innerhalb von AxHost.GetPictureFromIPicture geworfen wird, hatte ich erwähnt. Jendenfalls bilde ich mir das ein.



  • Man könnte auch einfach ne Bitmap erzeugen und das IPicture mittels Render-Methode da rein zeichnen lassen, dann kann einem auch egal sein wass da nun fürn Typ drin ist...


  • Administrator

    Schon mal probiert über den COM IPicture Typ zu gehen? Wenn mich nicht alles täuscht, müsstest du das Interface zuerst selber erstellen:

    [GuidAttribute("7BF80980-BF32-101A-8BBB-00AA00300CAB")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IPicture
    

    Dann alle Methoden implementieren:
    http://msdn.microsoft.com/en-us/library/ms680761.aspx

    Am Ende hast du dann eine Methode get_Handle . Die sollte dir das HICON als IntPtr zurückgeben, sofern diese IPicture auf ein HICON verweist. Mit Bitmap.FromHICON kannst du dir dann ein Bitmap erstellen.

    Ich weiss, da fehlen noch ein paar Informationen, allerdings müsste ich die selber zuerst noch in der MSDN nachschlagen gehen. Aber als Lösungsansatz dürfte dies reichen. Ob es wirklich funktionieren wird, kann ich aber nicht sagen, selber gemacht habe ich es noch nicht.

    Grüssli



  • geeky schrieb:

    Man könnte auch einfach ne Bitmap erzeugen und das IPicture mittels Render-Methode da rein zeichnen lassen, dann kann einem auch egal sein wass da nun fürn Typ drin ist...

    Verliere ich dann aber nicht die Transparenz?



  • Dravere schrieb:

    Schon mal probiert über den COM IPicture Typ zu gehen? Wenn mich nicht alles täuscht, müsstest du das Interface zuerst selber erstellen:

    Das ist genau das, was ich hier habe. Das Picture implementiert sowohl IPicture als auch IPictureDisp und ich habe das auch selbst implementiert (allerdings in C++).

    Dravere schrieb:

    [GuidAttribute("7BF80980-BF32-101A-8BBB-00AA00300CAB")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IPicture
    

    Das ist so nicht ganz richtig. Für InterfaceIsIDispatch muss es 7BF80981-BF32-101A-8BBB-00AA00300CAB heissen, also IPicutreDisp. Oder Du änderst den Type auf InterfaceIsIUnknown.

    Dravere schrieb:

    Am Ende hast du dann eine Methode get_Handle . Die sollte dir das HICON als IntPtr zurück

    Das ist ein Property, keine Methode. Und genau dieses Property frage ich eben auch ab.

    Dravere schrieb:

    Mit Bitmap.FromHICON kannst du dir dann ein Bitmap erstellen.

    Und das mache ich nicht, diese Methode habe ich nämlich gänzlich übersehen. Da kann ich mir ja den Umweg über Icon schöne sparen. Cool, danke.


Anmelden zum Antworten