Fehler bei Bild auf Button



  • Hi,

    ich habe für ein Kniffelspiel Buttons mit Bildern belegt, die Würfelaugen darstellen sollen.
    Der button wird je nachdem welche Zufallszahl genenriert wurde, auf diese Art mit dem Würfelbild belegt:
    m_wuerfel1.SetBitmap(LoadBitmap(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_WURF1)));

    Soweit so gut, funzt auch alles. Bei mir jedenfalls. Denn wenn ich das Spiel bei Freunden starte, wird nach unterschiedlicher Laufzeit einfach der Button mit den Würfeln komplett weiss. es ist keine Augenzahl mehr erkennbar sondern der Würfel is einfach weiss. wenn man dann nochmal würfelt, werden alle Würfelbuttons weiss. Jedoch tritt das nicht bei jedem auf, bei manchen meiner Kumpels geht auch alles so wies sein soll.

    Woran kann das liegen? Muss man vielleicht bevor man ein neues Bild auf den Würfel legen will das alte wieder irgendwie entfernen, also aus dem Speicher nehmen oder so?

    ich bin da schon ziemlich am verzweifeln

    thx Tie



  • lädst du das bitmap immer neu bei jedem wurf? das sind wahrscheinlich irgendwelche resource oder memory leaks



  • die bilder sind alle in der ressource als feste bitmaps gespeichert.
    bei jedem wurf wird immer nur sowas ausgeführt:

    [code type="C++" tabs="3"]zahl[1] = rand() % 6 + 1; //für 1. Würfel Zufallszahl bestimmen
    switch(zahl[1]) //wenn zahl:
    {
    case 1: m_wuerfel1.SetBitmap(LoadBitmap(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_WURF1))); break;
    //Bild Augenzahl1 ->Würfel 1
    case 2: m_wuerfel1.SetBitmap(LoadBitmap(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_WURF2))); break;
    //analog
    case 3: m_wuerfel1.SetBitmap(LoadBitmap(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_WURF3))); break;
    case 4: m_wuerfel1.SetBitmap(LoadBitmap(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_WURF4))); break;
    case 5: m_wuerfel1.SetBitmap(LoadBitmap(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_WURF5))); break;
    case 6: m_wuerfel1.SetBitmap(LoadBitmap(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_WURF6))); break;
    }
    [/code}
    ausgeführt



  • Die MSDN ist auch Dein Freund:

    The application must call the DeleteObject function to delete each bitmap handle returned by the LoadBitmap function.



  • außerdem kannst du doch am anfang des programms alle bitmaps laden und nicht immer neu!!



  • erstmal zu DeleteObject hab ich das hier gefunden, und auch gleich ne Frage:

    CBitmap m_bitmap; //...
    CStatic m_static; // ctrl auf picture..//on was auch immer
    m_bitmap.DeleteObject(); //alte löschen
    m_bitmap.LoadBitmap(IDB_BITMAP2); // neue laden
    m_static.SetBitmap(m_bitmap); // neue setzen

    ich benutze bei mir sowas wie m_bitmap ja nich, da ich die bitmaps in keiner variable speicher. wie muss ich das DeleteObject dann bei mir anwenden?

    und wenn ich das halt mit variablen machen, dann mach ich z.b. eine CBitmap augenzahl1 und augenzahl1.LoadBitmap(IDB_WURF1). und dann wenn ne 1 gewürfelt wird dann halt m_wuerfel1.SetBitmap(augenzahl1)

    wo muss ich dann da die DeleteObject benutzen?



  • LoadBitmap() gibt ein HBITMAP zurück. Das musst Du Dir irgendow merken, und wenn Du damit feritg bist DeleteObject( handle_des_bitmap ); aufrufen.

    Am besten Du machst beim Programmstart ein Array:

    CBitmap zahlenBilder[6];

    zahlenBilder[0] = LoadBitmap(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_WURF1) );
    //usw...

    Dann kannste auch den ganzen switch-Kram weglassen und einfach über zahl-1 auf das richtige Bild zugreifen.



  • das mit dem bitmaparray is nich schlecht, spart viel quelltext 🙂
    aber das mit dem DeleteObject hab ich immernoch nicht kapiert. Deshalb hier noch ein paar kleine Programmausschnitte, das ihr mir das am besten auch so erklären könnt, das sogar ich das verstehe 😛

    als globale variable: CBitmap augzahl[13];
    in der oninitdialog:
    augzahl[1].LoadBitmap(IDB_WURF1);
    augzahl[2].LoadBitmap(IDB_WURF2);
    augzahl[3].LoadBitmap(IDB_WURF3);
    //......
    //die werden später auch nicht mehr verändert

    wird bei jedem klick auf den würfeln-button ausgeführt:
    if (!invertiert[1]) { //wenn würfel nicht angeklickt(=neu würfeln) dann:
    zahl[1] = rand() % 6 + 1; //für 1. Würfel Zufallszahl bestimmen
    m_wuerfel1.SetBitmap(augzahl[zahl[1]]);
    }
    if (!invertiert[2]) { //analog zu !invertiert[1]
    zahl[2] = rand() % 6 + 1;
    m_wuerfel2.SetBitmap(augzahl[zahl[2]]);
    }
    if (!invertiert[3]) {
    zahl[3] = rand() % 6 + 1;
    m_wuerfel3.SetBitmap(augzahl[zahl[3]]);
    }
    //.....

    beim klick auf einen würfel:
    if (invertiert[1]) { //invertiert Zustand und Bild
    m_wuerfel1.SetBitmap(augzahl[zahl[1]]); invertiert[1]=false; }
    else {
    m_wuerfel1.SetBitmap(augzahl[zahl[1]+6]); invertiert[1]=true; }

    Wie muss ich da mit dem DeleteObject rangehen?



  • Gelöscht werden sollen die Bilder ja wohl beim Beenden, also schreibst Du zB in dem Destruktor der Klasse die das Array enthält:

    for( int i=1 ; i<13 ; ++i )// anscheindend benutzt Du den 0ten Eintrag nicht, also lass ich ihn auch weg
    {
      augzahl[i].DeleteObject();
    }
    


  • ah ok danke, ich habs kapiert 🙂


Anmelden zum Antworten