GDI+ & Instanzen

  • C++

Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von Gonger96.

    GDI+ & Instanzen

    Hey,
    ich arbeite im Moment an einer Lib mit diversen Controls. Um mir das schön einfach zu machen benutz ich GDI+ und nicht GDI ^^ Das Problem ist Folgendes: Vor GDI+ Zeichenoperationen & Co muss ich GdiplusStartup aufrufen und vor beenden des Programms GdiplusShutdown. Das kann ich aber nicht im Konstruktor & Destruktor machen, weil ich mehrere Instanzen hab und die Funktionen öfters aufgerufen werden würden. Gibt es eine elegantere Lösung als in WinMain als erstes StartUp und vorm return ShutDown aufzurufen ?

    Ist übrigens natives C++, kein CLI
    Naja, am einfachsten würde ich mir vorstellen, ne Statische Variable mitzuzählen, wie viele Instanzen du hast. Wenn die erstellte die erste Instanz ist, dann rufst du Startup auf, und wenn sie die letzte zerstörte Instanz ist, dann rufst du Shutdown auf.
    Ist dann halt so, dass wenn du die letzte Instanz zerstörst und du danach wieder ne neue erstellst, zwischendurch Shutdown und dann wieder Startup aufgerufen wird. Ich weiß nicht, ob das irgendwie nicht erwünscht sein könnte.
    Das geht leider nicht. Den Zähler müsst ich ja wieder in die Maindatei packen und da kann ichs gleich in WinMain machen. Ich hab etliche Klassen die untereinander auch erben, die können nicht Instanziert ja schlecht auf einander zugreifen
    (Edit: Artentus hatte wahrscheinlich genau die gleiche Idee.)

    Ich kenne mich nicht mit C++ direkt aus, aber ich hätte ein Konzept, das Du verwenden kannst:

    VB.NET-Quellcode

    1. Class DeineKlasse
    2. Public Sub New()
    3. InstanceCreated()
    4. End Sub
    5. Public Sub Dispose() 'Oder wie der Destruktor halt in C++ aussieht
    6. InstanceDestroyed()
    7. End Sub
    8. '...
    9. Private Shared InstanceCounter As Integer = 0
    10. Private Shared Sub InstanceCreated()
    11. If InstanceCounter = 0 Then
    12. GdiplusStartup()
    13. End If
    14. InstanceCounter += 1
    15. End Sub
    16. Private Shared Sub InstanceDestroyed()
    17. InstanceCounter -= 1
    18. If InstanceCounter = 0 Then
    19. GdiplusShutdown()
    20. End If
    21. End Sub
    22. End Class


    Sobald die erste Instanz erstellt wird, wird GdiplusStartup() aufgerufen. Und sobald alle Instanzen zerstört wurden, wird GdiplusShutdown() aufgerufen.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    @Gonger96: Lagere die statischen Funktionen aus.

    VB.NET-Quellcode

    1. Class DeineKlasse
    2. Public Sub New()
    3. GDIHelper.InstanceCreated()
    4. End Sub
    5. Public Sub Dispose() 'Oder wie der Destruktor halt in C++ aussieht
    6. GDIHelper.InstanceDestroyed()
    7. End Sub
    8. End Class
    9. Class GDIHelper
    10. Private Shared InstanceCounter As Integer = 0
    11. Public Shared Sub InstanceCreated()
    12. If InstanceCounter = 0 Then
    13. GdiplusStartup()
    14. End If
    15. InstanceCounter += 1
    16. End Sub
    17. Public Shared Sub InstanceDestroyed()
    18. InstanceCounter -= 1
    19. If InstanceCounter = 0 Then
    20. GdiplusShutdown()
    21. End If
    22. End Sub
    23. End Class

    Dann geht's von jeder Klasse aus.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Da es sich dabei ja um (zumindest so ne Art) Controls handelt, werden diese Klassen ja alle von der gleichen Basisklasse erben. In dieser legst du eine static-Variable an. In ihrem Konstruktor prüfst du, ob diese Variable 0 ist, wenn ja, rufst du die Methode auf, dann inkrementierst du die Variable. Im Desruktor dekrementierst du die Variable und prüfst anschließen, ob sie 0 ist. Wenn ja, dann rufst du die zweite Methode auf.

    So in etwa:

    C-Quellcode

    1. Class Conrol
    2. int count;
    3. Control()
    4. {
    5. if (count == 0)
    6. GdiplusStartup();
    7. count++;
    8. }
    9. ~Control
    10. {
    11. count--;
    12. if (count == 0)
    13. GdiplusShutdown()
    14. }
    15. }
    Ich wollte das eigentlich viel früher posten, hatte aber verbindungsprobleme. Ich möchte euren Kommentarfluss nicht unterbrechen, aber ich poste es einfach, damit es gesagt ist.

    Im Laufe des Programmes darf die Situation nicht auftreten, dass alle Klassen verworfen werden und dann nochmal eine neue erstellt wird. Sonst wird GdiplusStartup() nochmal aufgerufen.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Klasse A und B erben beispielsweise von Control & von InstanceCounter. Im Konstruktor von A wird der Counter inkrementiert und im Destruktor dekrementiert, sowie bei Klasse B. Wenn im Konstruktor der Counter == 0 ist wird StartUp aufgerufen. A wird instanziert, war noch nie da also StartUp, B wird instanziert und der Counter ist ebenfalls 0 dann wird StartUp erneut aufgerufen
    Ich hab das zwar nicht ausprobiert, aber da die Variable ja static ist müssten doch eigentlich alle Instanzen, egal ob von A oder B, auf die selbe Variable zugreifen, oder irre ich mich da?
    Wenn ich mich da täusche tuts mir leid, ich hab noch nie mit Mehrfachvererbung gearbeitet.
    @Gonger96: Ich hätte erwartet, Du weißt, was Shared (bzw. Static)-Variablen sind.
    Beispiel:

    VB.NET-Quellcode

    1. Sub Main()
    2. MessageBox.Show(TestClass.InstanceCounter.ToString) '0
    3. Dim Instance1 As New TestClass
    4. MessageBox.Show(TestClass.InstanceCounter.ToString) '1
    5. Dim Instance2 As New TestClass
    6. MessageBox.Show(TestClass.InstanceCounter.ToString) '2
    7. Instance1.Dispose()
    8. MessageBox.Show(TestClass.InstanceCounter.ToString) '1
    9. Instance2.Dispose()
    10. MessageBox.Show(TestClass.InstanceCounter.ToString) '0
    11. End Sub
    12. Class TestClass
    13. Public Sub New()
    14. InstanceCreated()
    15. End Sub
    16. Public Sub Dispose()
    17. InstanceDestroyed()
    18. End Sub
    19. Public Shared InstanceCounter As Integer = 0
    20. Private Shared Sub InstanceCreated()
    21. If InstanceCounter = 0 Then
    22. GdiplusStartup()
    23. End If
    24. InstanceCounter += 1
    25. End Sub
    26. Private Shared Sub InstanceDestroyed()
    27. InstanceCounter -= 1
    28. If InstanceCounter = 0 Then
    29. GdiplusShutdown()
    30. End If
    31. End Sub
    32. End Class
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Klar weiß ich was statische Variablen/Funktionen sind. Ich probier Artentus Vorschlag grad aus, müsste nicht der Counter nicht jeweils in den erbenden Klassen statisch sein, oder ist der für die Beerbte statisch ? Wahrscheinlich hab ich grad n ziemlichen Gedankenfehler :/
    Genaugenommen erben die abgeleiteten Klassen den Counter garnicht. Denn statische Variablen sind eben keine Instanz-Variablen.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils