Die Windows GDI+ (Teil 1)



  • Das er gdiplus.h nicht findet, kann schlecht was mit der Compilerversion zu tun habe. Er findet ja nur die Datei nicht. Wenn er die Datei gefunden hat, und dann was von error faselt, kann es schon eher sein, das der Compiler zu alt ist. Wobei das nicht sein kann, weil als damals GDI+ erschien, es nur den VC++6 von MS gab!!! 2001 gab es WinXP mit GDI+ und 2002 erschien erst VC++7. Und ich bin der Meinung, ich hatte es damals selbst noch mit der 6er ausprobiert.

    Aber gut, ist deine Sache wie du weiter verfährst.



  • Ab sofort gibt es die Beispiele aus dem Tutorial auch als VisualC++ 2003 Projekte mit Sourcecode zum Download.

    Ebenfalls habe ich eine MFC-Beispielanwendung beigelegt, die die GDI+ nutzt. Da ja schon oft im MFC-Forum die Frage kam, ob man die GDI+ auch mit der MFC nutzen könnte.

    Hier das selbstentpackende Archiv (239 KB):
    http://www.kharchi.de/gdiplus/GDI-Plus-Tutorial.exe



  • vllt noch auf

    //--------------------------------------------------------------------------
    // Status return values from GDI+ methods
    //--------------------------------------------------------------------------
    
    enum Status
    {
        Ok = 0,
        GenericError = 1,
        InvalidParameter = 2,
        OutOfMemory = 3,
        ObjectBusy = 4,
        InsufficientBuffer = 5,
        NotImplemented = 6,
        Win32Error = 7,
        WrongState = 8,
        Aborted = 9,
        FileNotFound = 10,
        ValueOverflow = 11,
        AccessDenied = 12,
        UnknownImageFormat = 13,
        FontFamilyNotFound = 14,
        FontStyleNotFound = 15,
        NotTrueTypeFont = 16,
        UnsupportedGdiplusVersion = 17,
        GdiplusNotInitialized = 18,
        PropertyNotFound = 19,
        PropertyNotSupported = 20
    };
    

    kurz eingehen ... sonnst ganz nettes Tutorial



  • Im Turbo C++ meckert der Compiler bei Inkludierung von gdiplus.h und Einbindung von GdiPlus.lib:

    [C++ Fehler] GdiplusGraphics.h(34): E2015 Mehrdeutigkeit zwischen 'Gdiplus::Graphics::Graphics(void *)' und 'Gdiplus::Graphics::Graphics(void *,int)'

    Die zugehörige Zeile ist das return in:

    static Graphics* FromHDC(IN HDC hdc)
        {
            return new Graphics(hdc);
        }
    

    Es gibt auch eine Warnung:

    [C++ Warnung] GdiplusEnums.h(23): W8058 Präcompilierter Header: Initialisierte Daten im Header kann nicht erzeugt werden

    Was kann das alles zu bedeuten haben?



  • Also zum TurboC++ kann ich leider absolut nichts sagen. Die Frage wäre ja erstmal, ob dieser überhaupt mit den lib-Dateien von MS auskommt? 😕

    static Graphics* FromHDC(IN HDC hdc)
    

    Was bedeutet das IN?

    Komisch ist auch, das TurboC++ die Graphics-Ctors als void* erkennt? Obwohl der Parameter HDC ist... 😮 Hast du auch #include <windows.h> vor dem gdi-Include?

    Die zweite Meldung mit den Präcompiled-Headern (PCH) scheint bestimmt sowas zu sein, das du dein Projekt für PCHs konfiguriert hast. Beim MSVC muß man mind. einmal einen Build starten (nicht nur Kompilieren der einen cpp-Datei!). Ansonst einfach die PCH-Funktion für das Projekt abschalten, falls man sich damit nicht auskennt.



  • Artchi schrieb:

    Also zum TurboC++ kann ich leider absolut nichts sagen. Die Frage wäre ja erstmal, ob dieser überhaupt mit den lib-Dateien von MS auskommt? 😕

    Die Frage stellt sich gar nicht erst, denn alle SDK-LIBS und -Headers sind dabei.

    Artchi schrieb:

    static Graphics* FromHDC(IN HDC hdc)
    

    Was bedeutet das IN?

    Na, "rein", denke ich. 😉

    Artchi schrieb:

    Komisch ist auch, das TurboC++ die Graphics-Ctors als void* erkennt? Obwohl der Parameter HDC ist...

    #define HDC *void

    Artchi schrieb:

    Hast du auch #include <windows.h> vor dem gdi-Include?

    Ja, hab ich.

    Artchi schrieb:

    Die zweite Meldung mit den Präcompiled-Headern (PCH) scheint bestimmt sowas zu sein, das du dein Projekt für PCHs konfiguriert hast. Beim MSVC muß man mind. einmal einen Build starten (nicht nur Kompilieren der einen cpp-Datei!). Ansonst einfach die PCH-Funktion für das Projekt abschalten, falls man sich damit nicht auskennt.

    Danke, Artchi. Ich werd's mal versuchen.



  • OK, wenn das PSDK schon beim TC++ dabei ist, wird es auch damit laufen. 😉

    Naja, das IN "in" heißt, war mir schon klar. Nur es ist nicht gerade Standard-C++. Vielleicht erweitert es den HDC-Parameter um irgendwas, das es für den Graphics-Ctor undeutlich wird. Um genau zu sein: warum steht da das IN??? Ich würde es spontan weg lassen.



  • Nun, ich habe jetzt auf jeden Fall herausgefunden, wie ich den Fehler nicht mehr bekomme:

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-170397-and-highlight-is-gdi.html

    Die Warnung mit den vorkompilierten Headern bleibt. So sah sie aus:

    [C++ Warnung] GdiplusEnums.h(23): W8058 Präcompilierter Header: Initialisierte Daten im Header kann nicht erzeugt werden

    Wenn ich darauf doppelt klicke, markiert er mir im Code folgende Zeile:

    const float FlatnessDefault = 1.0f/4.0f;
    

    Vielleicht ist es nicht OK, const-Variablen in Header-Dateien zu erstellen? Die Turbo C++ Hilfe sagt zu der Warnung folgendes:

    Borland-Hilfe schrieb:

    (Die Kommandozeilenoption zur Unterdrückung dieser Warnung lautet -w-pch)

    Die vorcompilierte Header-Datei konnte aus einem der folgenden Gründe nicht angelegt werden:

    Grund Erklärung
    Schreiben fehlgeschlagen: Der Compiler konnte die vorcompilierte Header-Datei nicht abspeichern. Dies tritt auf, wenn Sie eine ungültige Position für die Zwischenspeicherung von Header-Dateien angegeben haben oder wenn die Platte voll ist.

    Quelltext in der Header-Datei: Eine der Header-Dateien enthält einen Funktionsrumpf, der nicht inline ist.

    Initialisierte Daten in der Header-Datei: Eine der Header-Dateien enthält die Definition einer globalen Variablen. (In C eine globale Variable, in C++ jegliche Variable, die nicht als extern deklariert wurde.)

    Header-Datei unvollständig: Die vorkompilierte Header-Datei endete in der Mitte einer Deklaration, zum Beispiel innerhalb einer Klassendefinition (dies passiert häufig, wenn eine schließende Klammer } fehlt).



  • Mußt du so machen:

    // HEADER
    extern const float FlatnessDefault;
    
    // CPP
    const float FlatnessDefault = 1.0f/4.0f;
    

    Wenn es aber eh global ist, würde ich noch static dazu schreiben.



  • Artchi schrieb:

    // CPP
    const float FlatnessDefault = 1.0f/4.0f;
    

    Es gibt aber keine GdiplusEnums.cpp. Soll ich das nun in jedem Projekt wieder neu schreiben, wenn ich GDI+ verwenden will?



  • achso, die Variable ist nicht von dir??? Das ist ne GDI+-Variable? Also an der GDI+ selbst sollte man nichts machen müssen. Das muß doch von Haus aus funktionieren!

    Prinzipiell inkludiert man gdiplus.h und gut ist. Die FlatnessDefault ist dann doch schon in gdiplus.lib drin. Der Header sagt ja nur, was in der Lib vorhanden ist.

    Ich habe jetzt momentan leider keinen Zugriff auf die GDI+ Files um selber nachzuschauen. Muß ich zu Hause machen. Kann dir jetzt da nichts weiter sagen. Da es sich aber um ein Warning handelt, kompiliert doch dein Projekt trotzdem. Warnings sollte man natürlich verhindern, aber benutze es erstmal.



  • Artchi schrieb:

    Warnings sollte man natürlich verhindern, aber benutze es erstmal.

    Ja, das tu ich ja auch. Wird schon nicht so schlimm sein. Trotzdem wüsste ich halt gerne, was hier das Problem ist.

    Und ja, das Problem ist die Datei GdiplusEnums.h. Hatte ich eigentlich aber auch schon geschrieben. Also, iregndwie scheint die zitierte Zeile der Grund dafür zu sein, dass ein vorkompilierter Header nicht erstellt werden kann. Auch wenn ich in den Optionen alle möglichen Häkchen für vorkompilierte Header wegnehme, bekomme ich immernoch dieselbe Warnung. Kenn mich mit vorkompilierten Headern einfach nicht so gut aus. 😞



  • Das sind aber alles eher TC++-bezogene Fehler. Da kann ich dir als MSVC-User leider nicht helfen. Du solltest am besten mal im Borland-Forum nachfragen. Vielleicht kann dir da jemand helfen.

    Die GDI+ ist nämlich ansonsten eher kein Problemkind. Und wenn sie beim TC++ im Lieferumfang war, müsste sie auch funktionieren.



  • Hallo,
    ich hab ein kleines Problem mit einem Graphics-Objekt...
    Ein Graphics-Objekt mit Gdiplus::Graphics::FromImage () erzeugt, läßt sich bei mir nicht mit delete löschen. Wie überzeuge ich GDI+ das Objekt freizugeben?



  • Was heißt, es lässt sich nicht mit delete löschen? (das ist nun wirklich keine Fehlerbeschreibung... mit über 300 Beiträgen in diesem Forum, müsste man es wissen)



  • Ich kriege zur Laufzeit die Fehlermeldung: "Der Heap wurde beschädigt" und dann hört es auch schon mit der Fehlerbeschreibung meines VS2005 auf.

    Das Objekt, wird in der Get-Routine mit der schon beschriebenen Routine angelegt und vom Destuktor des Hüllobjekts gelöscht. Es wird weder durch Kopierkonstruktor noch durch Zuweisungsoperator einem zweiten Objekt zugewiesen.

    Entschuldigung, dass ich das vergessen hab zu schreiben.



  • Also ich kann erstmal nur raten, auch wenn nachfolgendes sich erstmal banal anhört:

    Ist der Pointer gültig, der zurück gegeben wurde? (also nicht null?)
    War das Image-Objekt auch gültig?

    Mach mal folgendes, nachdem du FromImage() aufgerufen hast (kannst du aber immer machen, wenn du etwas in der GDI+ erzeugen lässt, also z.B. auch Images):

    Gdiplus::Status s = Gdiplus::GetLastStatus();
    if(s == Gdiplus::Ok)
        ok!
    else
        hier die Fehlerbehandlung bzw. eine eigene Exception werfen...
    

    Hier mal ne Übersicht, zu den Errorcodes:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/GDIPlusreference/enumerations/status.asp

    Falls das nicht besser ist, mußt du mal relevante Codeschnippsel posten.



  • Mein Problem war das Löschen des Objektes nicht das Anlegen.

    Selbst wenn ich beim Anlegen des Objekts eine Fehlermeldung bekomme, muss ich davon ausgehen können, dass ein zurückgeliefertes Objekt auch mit delete zu löschen ist.
    (Ein Objekt sollte nie in einen solchen Zustand versetzt werden können, dass man es nicht mehr löschen kann und genau das ist an der Stelle passiert.)

    Ich hab mittlerweile herausgefunden, dass beim Zeichnen das falsche Graphics-Objekt verwendet wurde und dadurch die Speicherverwaltung von GDI+ durcheinander gekommen ist. 🕶
    Damit ist der Fehler weg und das Vertrauen in GDI+ ungemein gefördert.



  • Hatte vor einiger Zeit GDI+ Pakete für MinGW und BC5.5 erstellt. Man kann sie unter http://www.dhost.info/voodoocpp/index.php?page=progs/libs downloaden. Header und import Bibliotheken sind enthalten. Dokumentation und gdiplus.dll muss man sich von MS besorgen.

    Das IN/OUT bei den Methodendefinitionen ist an sich überflüssig. Das sind defines die zu nichts expandieren.



  • Artchi schrieb:

    Die GDI+ ist nämlich ansonsten eher kein Problemkind. Und wenn sie beim TC++ im Lieferumfang war, müsste sie auch funktionieren.

    Naja, stimmt zwar in der Regel schon, aber ich hatte auch erst vor kurzem Probleme mit besagter GdiplusEnums.h. Und ich benutze MSVC 2005, und da sollte es eigentlich gar keine Probleme geben. Wie dem auch sei... hab halt massig Fehler gekriegt obwohl der Code korrekt war. Letztendlich hab ich dann einfach die afxdisp.h vor dem Gdiplus Header inkludiert und dann ging wieder alles. Lag halt wohl irgendwie daran dass ich auch die MFC teilweise benutze. Ist aber trotzdem nicht gerade toll 👎
    Wobei dass ja sogar noch geht wenn ich mir andere Sachen vom Platform SDK anschaue.. was MS da z.T. für ne Scheisse gebaut hat...


Anmelden zum Antworten