Bild dauerhaft im Hintergund?!



  • JAAAAHHHHHHHHHHH!!!!

    Es funktioniert, wenn ich den Gerätekontext nur einmal erzeuge! Big THX@Pellaeon 🕶

    chiao cha-OS



  • Ok, über diesen Konstrukt hatte ich mich auch schon gewundert, aber seltsamerweise schien das Programm doch am Anfang das Hintergrundbild zu malen, hm?!



  • Hi,

    ich habe die Funktion jetzt so umgesetzt, wie es mir Paul_C. empfohlen hat (http://www.c-plusplus.net/forum/viewtopic-var-t-is-131579.html). Es funktioniert auch, aber jetzt ist das anfängliche Problem wieder aufgetaucht, was bedeutet, dass das Hintergrundbild nach dem Minimieren immer über die Kreise gezeichnet wird!

    In der OnPaint steht jetzt:

    CClientDC dc(this); 
    		CBitmap bitmap; 
    		bitmap.LoadBitmap(IDB_Hintergrund);
    		BITMAP bm; 
    		bitmap.GetObject(sizeof(bm), &bm); 
    		CDC speicherDC; 
    		speicherDC.CreateCompatibleDC(&dc); 
    		CBitmap* pOldBitmap = speicherDC.SelectObject(&bitmap); 
    		RECT rect;
    		GetClientRect(&rect); 
    		dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, 
    				  &speicherDC, 0, 0, SRCCOPY); 
    		speicherDC.SelectObject(pOldBitmap);
    
    OnKreise(0,0,0,110,110,150,150);
    

    OnKreise sieht so aus:

    void CVisuDlg::OnKreise(int r, int g, int b, int x1, int y1, int x2, int y2) 
    {
    CPaintDC dc(this);
    CPen pen;
            pen.CreatePen(PS_SOLID,1,RGB(236,233,216));
            dc.SelectObject(pen);
    		CBrush brush;
    		brush.CreateSolidBrush(RGB(r,g,b));
    		dc.SelectObject(brush);		
            dc.Ellipse(x1, y1, x2, y2);
    

    Die einfache Lösung den Gerätekontext nur einmal zu erzeugen (THX an Pellaeon), funktioniert in diesem Fall nicht mehr, da ansonsten "dc" ein nicht-deklarierter Bezeichner ist!

    Bin ein wenig ratlos - helft mir bitte weiter,

    chiao cha-OS



  • Versuch mal den dc auch als Parameter zu übergeben.
    😉



  • Paul_C. schrieb:

    Versuch mal den dc auch als Parameter zu übergeben.
    😉

    jo und zwar als Zeiger pder Referenz 🙂
    Du hast wieder das gleiche Problem wie vorher: 2 DCs auf ein Fenster. Alternativ musst du den ersten mit new erzeugen und vor Aufruf der Funktion wieder freigeben. Das mit dem Parameter ist aber besser.



  • Danke für die Tipps - sie klingen einleuchtend 😉

    Ich habe jetzt für meine Kreise folgenden Code:

    void CKreise::OnKreise(CDC* pDC,int r, int g, int b, int x1, int y1, int x2, int y2) 
    {
    CPen pen;
            pen.CreatePen(PS_SOLID,1,RGB(236,233,216));
            pDC->SelectObject(pen);
            CBrush brush;
            brush.CreateSolidBrush(RGB(r,g,b));
            pDC->SelectObject(brush);       
            pDC->Ellipse(x1, y1, x2, y2);   	
    }
    
    OnKreise(pDC,0,0,0,110,110,150,150);
    

    Dieser Teil müsste passen, leider schaffe ich es nicht den Code zum Laden des Bildes so anzupassen, das AUCH der Zeiger auf den Gerätekontext verwendet wird.

    Bitte um einen kleinen weiteren Hinweis, ich hab das Gefühl das wir uns dem Ziel endlich nähern 😉 😃

    EDIT: Ok, der gepostete Code funktioniert doch nicht -> wird zwar ausgeführt aber Problem mit dem Speicher (=Absturz). Für euch sicher einleuchtend, wo liegt der Fehler??

    chiao cha-OS



  • muss das nicht

    [cpp]pDC->SelectObject(**&pen);
    pDC->SelectObject(
    &**brush);
    [/cpp]

    heissen?

    edit: warum formatiert der das nun nicht?



  • THX an Paul_C.! Jetzt stürzt meine Anwendung nicht mehr ab! Leider wird der Kreis mit dem momentanen Code gar nicht angezeigt 😮

    So siehts in der OnPaint aus:

    CClientDC dc(this);
            CBitmap bitmap;
            bitmap.LoadBitmap(IDB_Sensorhintergrund);
            BITMAP bm;
            bitmap.GetObject(sizeof(bm), &bm);
            CDC speicherDC;
            speicherDC.CreateCompatibleDC(&dc);
            CBitmap* pOldBitmap = speicherDC.SelectObject(&bitmap);
            RECT rect;
            GetClientRect(&rect);
            dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight,
                      &speicherDC, 0, 0, SRCCOPY);
            speicherDC.SelectObject(pOldBitmap); 
    
    OnKreise(pDC,0,0,0,110,110,150,150);
    

    Die beiden Fehler die du mir gezeigt hast habe ich ausgebessert. Irgendetwas fehlt noch bzw. ist zu viel - aber was??? 😕

    chiao und Danke

    cha-OS



  • Schreib mal deinen Funktionsaufruf OnKreise(pDC,0,0,0,110,110,150,150)
    bevor du

    dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight,&speicherDC, 0, 0, SRCCOPY);
    

    ausführst.



  • EDIT:

    Also wieder was neues:

    Eigenartigerweise funktioniert das Minimieren mit folgendem Code in der OnPaint:

    else
    	{
    
    CClientDC dc(this); 
    		CBitmap bitmap; 
    		bitmap.LoadBitmap(IDB_Sensorhintergrund);
    
    		BITMAP bm; 
    		bitmap.GetObject(sizeof(bm), &bm); 
    
    CDC speicherDC; 
    		speicherDC.CreateCompatibleDC(&dc); 
    		CBitmap* pOldBitmap = speicherDC.SelectObject(&bitmap); 
    
    RECT rect;
    		GetClientRect(&rect); 
    
    		dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, 
    				  &speicherDC, 0, 0, SRCCOPY); 
    
    		speicherDC.SelectObject(pOldBitmap);
    
    OnKreis(0,0,0,110,110,150,150);
    
    CDialog::OnPaint();
        }
    

    Bleibt nur noch folgendes Problem:
    Schiebe ich beispielweise das Fenster über den Bildschirmrand hinaus, so zeichnet sich der Hintergrund wieder über die Kreise oder aber die Kreise werden gar nicht neu gezeichnet??!

    Bitte wiedereinmal um Hilfe 🙄

    chiao cha-OS



  • Hat wirklich keiner eine Lösung?? 😕

    Bitte helft mir das Problem zu lösen.



  • cha-OS schrieb:

    Hat wirklich keiner eine Lösung?? 😕

    Wie???? Die Lösung wurde doch schon zig-mal gesagt: Du darfst Nur einmal ein DC erzeugen!!!



  • ich erzeuge ihn ja auch nur einmal, aber ich bekomme es nicht hin, den Code für das Laden des Bildes so anzupassen, dass ich auch dort den Zeiger verwenden kann???!
    Hast du eine Idee??



  • Was ist denn Dein Problem? Wenn Du es schon in eine eigene Methode packen willst, dann übergibt einfach den dc... das wurde auch schon oft gezeigt...
    Ich perönlich würde es so machen:

    void CKreise::OnKreise(CDC &dc,int r, int g, int b, int x1, int y1, int x2, int y2) 
    {
    
      // jetzt mach was Du willst)
    }
    


  • JJJIIIIPPPPYYYYYYYYYY!!!!

    Ich habs endlich thx Jochen für den A**tritt -> hab neu angefangen, probiert und jetzt funktionierts wie am Schnürchen.

    Danke an alle für eure Geduld 🕶 😃

    c u
    cha-OS



  • Jochen Kalmbach schrieb:

    Ich perönlich würde es so machen:

    void CKreise::OnKreise(CDC &dc,int r, int g, int b, int x1, int y1, int x2, int y2) 
    {
    
      // jetzt mach was Du willst)
    }
    

    Eigentlich hatte Cha-os das doch so 'ähnlich' gemacht:

    void CKreise::OnKreise(CDC* pDC,int r, int g, int b, int x1, int y1, int x2, int y2)
    

    Naja, wie dem auch sei, ist wohl gelöst. 👍


Anmelden zum Antworten