Grafik in Dialog einfügen



  • Hallo zusammen,

    ich habe einen Dialg erstellt. Nun würde ich gerne in dem Dialog eine kleine Grafik anzeigen, wenn das möglich ist. Leider weiß ich überhaupt nicht, wie ich das anstellen soll. Wäre toll, wenn mir da jemand helfen könnte.

    Gruß
    Pepper



  • Hi Pepper1,

    wenn es sich bei deiner Grafik um ein Bitmap handelt müsste dir dieser Code (sogar mit hilfreichen Kommentaren ;-)) weiterhelfen:

    CClientDC dc(this); //Gerätekontext erzeugen
    
        CBitmap bitmap; //CBitmap Objekt erstellen und Bitmap
        bitmap.LoadBitmap(IDB_DEINEGRAFIK); //aus der Ressource in dieses laden
    
        BITMAP bm; 
        bitmap.GetObject(sizeof(bm), &bm); //Größe des Bitmaps ermitteln
    
        CDC speicherDC; //Speicherkontext erzeugen
        speicherDC.CreateCompatibleDC(&dc); 
        CBitmap* pOldBitmap = speicherDC.SelectObject(&bitmap); 
    
        RECT rect; //Blitten des Bitmaps 
        GetClientRect(&rect); 
    
        dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, 
                  &speicherDC, 0, 0, SRCCOPY); 
    
        speicherDC.SelectObject(pOldBitmap);
    

    Diesen Code musst du beispielsweise in die oninitdialog() schreiben.

    Hoffe ich konnte dir helfen,

    chiao cha-OS



  • mh und was muss ich nun hier eintragen? dennamen des bildes oder was...

    IDB_DEINEGRAFIK
    


  • das Bild muss als Ressource vorliegen und dort gibts du dann die RessourcenID des Bildes an



  • Das kannst du auch machen ohne code.



  • Hallo,

    wie kann ich das denn ohne Code anstellen?



  • Du gehst in die Ressourcenansicht, -> Rechtsklick -> Ressource importieren -> da suchst du dein Bild aus.
    Standardmässig erhält dein erstes Bild die ID: IDB_BITMAP1.



  • und auch auf dein dialog ein Bild einfügen und in Eiogenschaften soll type: bitmab sein und und Bild: IDB_BITMAP ...und fertig



  • Hi, ich hätte auch eine Frage dazu, wie kann ich ein solches Bild verschieben und kann ich auch andere Bildformate benutzten? Wäre es teoretisch möglich auf diese art und weise ohne beispielsweise DirectX ein Tetrisspiel zu programmieren, ich meine viel leistung braucht das spiel ja nicht gerade? Ich bin danbar auf alle hilfreichen antworten.



  • Verschieben tust Du es einfach, indem Du als Dest-X/Y immer was anderes anbigst und das Zeichnen ungefähr 20 mal in der Sekunde machst (also ca. alle 50 ms ein Invalidate aufrufen).



  • 50 ms ist dann auch schon die Grenze. Dafür einfach einen Timer anlegen und wie gesagt Invalidate() aufrufen. Auch wenn man bei Timern die Möglichkeit hat, 1 ms anzugeben, liegt das Minimum bei ca. 50 ms.



  • mhh, okay.
    AAALSO ich bin leider Anfänger, denn ich habe vorher nur mit ANSI-C gearbeitet. Deswegen brauch ich es "leider" etwas umfangreicher, ich schreibe schreibe als erstens

    CClientDC dc(this); //Gerätekontext erzeugen
    
        CBitmap bitmap; //CBitmap Objekt erstellen und Bitmap
        bitmap.LoadBitmap(IDB_DEINEGRAFIK); //aus der Ressource in dieses laden
    
        BITMAP bm;
        bitmap.GetObject(sizeof(bm), &bm); //Größe des Bitmaps ermitteln
    
        CDC speicherDC; //Speicherkontext erzeugen
        speicherDC.CreateCompatibleDC(&dc);
        CBitmap* pOldBitmap = speicherDC.SelectObject(&bitmap);
    
        RECT rect; //Blitten des Bitmaps
        GetClientRect(&rect);
    
        dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight,
                  &speicherDC, 0, 0, SRCCOPY);
    
        speicherDC.SelectObject(pOldBitmap);
    

    in die OnInitDialog funktion, natürlich habe ich IDB_DEINEGRAFIK ensprechend meiner Ressource angepasst. Wenn ich nun kompiliere kommt mein Dialog aber ohne grafik, was muss ich noch ändern bzw. hinzufügen?
    Bitte hilft mir, denn ich brauch das für die Schule 😉 Danke



  • Schreib das mal in die OnPaint()-Funktion. In diese Funktion sollten eigentlich fast alle Zeichnungen geschrieben werden.
    Ich glaube, zum Zeitpunkt von OnInitDialog() ist dein Dialog noch nicht erstellt und daher wird das Bild nicht mehr angezeigt.
    Korrigiert mich bitte, wenn ich falsch liege. Interessiert mich auch.

    EDIT: Ok, hatte Recht, muss in die OnPaint() oder später, aber nicht in die OnInitDialog(). Habe ich gerade mal ausprobiert. Habe es bisher immer in OnPaint() gemacht.



  • ahh, danke es hat funktioniert, ihr habt mir sehr geholfen.

    Ich habe jetzt auch ein 2tes Bild eingebaut und ich wollte gerne mal zeigen und fragen ob das so nicht vieleicht schlecht programmiert ist. Vieleicht gibt es ja eine bessere Möglichkeit oder ich habe etwas überflüssig gemacht.
    Hier mein Code:

    //////////////////////////////////////////////
    	/////////////Eigener Code, Anfang/////////////
    	//////////////////////////////////////////////
    
        CClientDC dc(this); //Gerätekontext erzeugen
    
        CBitmap bitmap; //CBitmap Objekt erstellen und Bitmap
        bitmap.LoadBitmap(IDB_BLOCK_ROT); //aus der Ressource in dieses laden
    
        BITMAP bm;
        bitmap.GetObject(sizeof(bm), &bm); //Größe des Bitmaps ermitteln
    
        CDC speicherDC; //Speicherkontext erzeugen
        speicherDC.CreateCompatibleDC(&dc);
        CBitmap* pOldBitmap = speicherDC.SelectObject(&bitmap);
    
        RECT rect; //Blitten des Bitmaps
        GetClientRect(&rect);
    
        dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight,
                  &speicherDC, 0, 0, SRCCOPY);
    
        speicherDC.SelectObject(pOldBitmap);
    
        //--------------------------------------------
        CClientDC dc2(this); //Gerätekontext erzeugen
    
        CBitmap bitmap2; //CBitmap Objekt erstellen und Bitmap
        bitmap2.LoadBitmap(IDB_BLOCK_BLAU); //aus der Ressource in dieses laden
    
        BITMAP bm2;
        bitmap2.GetObject(sizeof(bm2), &bm2); //Größe des Bitmaps ermitteln
    
        CDC speicherDC2; //Speicherkontext erzeugen
        speicherDC2.CreateCompatibleDC(&dc2);
        CBitmap* pOldBitmap2 = speicherDC2.SelectObject(&bitmap2);
    
        RECT rect2; //Blitten des Bitmaps
        GetClientRect(&rect2);
    
        dc2.BitBlt(3, 3, bm2.bmWidth, bm2.bmHeight,
                  &speicherDC2, 0, 0, SRCCOPY);
    
        speicherDC2.SelectObject(pOldBitmap);
    
    	//////////////////////////////////////////////
    	/////////////Eigener Code, Ende///////////////
    	//////////////////////////////////////////////
    

    Edit:
    Ah ich habe gerade herrausgefunden dass, das mit dem 2ten Bild auch so geht, kann mir einer erklären wieso?

    //////////////////////////////////////////////
    	/////////////Eigener Code, Anfang/////////////
    	//////////////////////////////////////////////
          .
          .        //wie oben
          .
    
        //--------------------------------------------
    		CClientDC dc2(this); //Gerätekontext erzeugen
    
        CBitmap bitmap2; //CBitmap Objekt erstellen und Bitmap
        bitmap2.LoadBitmap(IDB_BLOCK_BLAU); //aus der Ressource in dieses laden
    
        BITMAP bm2;
        bitmap2.GetObject(sizeof(bm2), &bm2); //Größe des Bitmaps ermitteln
    
        CBitmap* pOldBitmap2 = speicherDC.SelectObject(&bitmap2);
    
        RECT rect2; //Blitten des Bitmaps
        GetClientRect(&rect2);
    
        dc2.BitBlt(3, 3, bm2.bmWidth, bm2.bmHeight,
                  &speicherDC, 0, 0, SRCCOPY);
    
    	//////////////////////////////////////////////
    	/////////////Eigener Code, Ende///////////////
    	//////////////////////////////////////////////
    

    Ich habe das mit dem Speicherkontext wegelassen und hier:

    CBitmap* pOldBitmap2 = speicherDC.SelectObject(&bitmap2);
    

    einfach das vom ersten Bild genommen, also "&speicherDC" statt beispielsweise "&speicherDC2".

    Und hier auch:

    dc2.BitBlt(3, 3, bm2.bmWidth, bm2.bmHeight,
                  &speicherDC, 0, 0, SRCCOPY);
    


  • Du brauchst nichtmal ein dc2! Es reicht ein dc und ein SpeicherDC.
    Da du ja erst das erste Bild speicherst und ausgibst und dann erst das andere, kannst du ja nur jeweils ein Objekt benutzen.
    Ich hoffe es ist einiger maßen verständlich.
    Daher würde ich das folgendermaßen sortieren:

    // Initialisierungen
    CClientDC dc(this); //Gerätekontext erzeugen
    
    CDC speicherDC; //Speicherkontext erzeugen
    speicherDC.CreateCompatibleDC(&dc);
    
    CBitmap bitmap, bitmap2; //CBitmap Objekt erstellen und Bitmap
    CBitmap* pOldBitmap;
    BITMAP bm, bm2;
    
    RECT rect;                         
    GetClientRect(&rect);
    
    // Bitmap1 laden und ausgeben
    bitmap.LoadBitmap(IDB_BLOCK_ROT);  //aus der Ressource in dieses laden
    bitmap.GetObject(sizeof(bm), &bm); //Größe des Bitmaps 
    
    pOldBitmap = speicherDC.SelectObject(&bitmap);
    
    dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight,
             &speicherDC, 0, 0, SRCCOPY);
    
    // Und hier nun Bitmap2 laden und ausgeben
    bitmap2.LoadBitmap(IDB_BLOCK_BLAU); //aus der Ressource in dieses laden
    bitmap2.GetObject(sizeof(bm2), &bm2); //Größe des Bitmaps 
    
    speicherDC.SelectObject(&bitmap2);
    
    dc.BitBlt(3, 3, bm2.bmWidth, bm2.bmHeight,
             &speicherDC, 0, 0, SRCCOPY);
    
    // Speicher aufräumen
    speicherDC.SelectObject(pOldBitmap);
    

    😉



  • Paul_C. schrieb:

    Schreib das mal in die OnPaint()-Funktion. In diese Funktion sollten eigentlich fast alle Zeichnungen geschrieben werden.
    Ich glaube, zum Zeitpunkt von OnInitDialog() ist dein Dialog noch nicht erstellt und daher wird das Bild nicht mehr angezeigt.
    Korrigiert mich bitte, wenn ich falsch liege. Interessiert mich auch.

    in OnInitDialog existiert der dialog soweit ich weiss schon aber wenn du das nicht in die OnPaint() Methode schreibst wird es nicht gezeichnet.
    Bzw wenn du ne etra methode schreiben würdest die dir das Bild zeichnen würde und du sie nicht in der OnPaint() aufrufst wird sie eben nur einmal gezeichnet und sobald der Dialog neu gezeichnet werden muss (verschieben, resize, etc) ist das bild weg.
    Daher alles was permanent da sein soll in der OnPaint() zeichnen lassen bzw die entsprechende Funktion von dort aufrufen.

    So, ich hoffe ich hab nicht gelogen ^^



  • Kannst Recht haben. Vielleicht benötigt man ausserhalb noch die Funktionen BeginPaint() und EndPaint().
    Ich wußte das alles mal besser, ist aber nicht mehr viel hängen geblieben.
    Ich glaube ich teste das mal eben. 😉



  • So getestet: Also BeginPaint() und EndPaint() wird nicht benötigt.
    Habe eben einfach in einer Funktion:

    CDC* dc = GetDC();
    dc->MoveTo(500,150);
    dc->LineTo(500,300);
    Invalidate(false);
    

    geschrieben und es funktioniert. 😉



  • dein Code ist komisch

    CClientDC dc(this); //warum nimmst du GetDC ??
    

    zu GetDC gehört nämlich auch ReleaseDC, ansonsten is das ein ÜBELSTES Speicherleck, wws bei jedem Neuzeichnen größer wird
    Warum Invalidate? Wenn du auf dein Fenster zeichnest, wird das sofort umgesetzt.



  • Ja, ReleaseDC() ist schon richtig. Sollte hier nur ein Beispiel sein.
    Mit Invalidate() bin ich mir gerade nicht so sicher. Hatte es schon erlebt, dass nichts gezeichnet wurde, kann mich aber auch irren.

    Und GetClientDC() wollte er nicht annehmen, daher habe ich GetDC() genommen.
    Habe mich jetzt aber nicht drum gekümmert, warum nicht. 😉



  • hallo,

    ich habe nun ein bitmap zu den ressourcen hinzugefügt. nun weiß ich aber nicht, wie ich das auch in den dialog einfügen kann. geht das mit "picture control"? da kann ich dann aber nicht den typ der grafik angeben.

    wäre toll, wenn mir das nochmal jemand erklären könnte.

    gruß


Anmelden zum Antworten