Verständnisfrage GDI: DeviceContext + Bitmap



  • Hallo Leute,

    Ich habe eine Fenster (CWnd) unter MFC, und darin die OnPaint Calback, in der ich mit der GDI Zeichnen kann, indem ich die API des DeviceContext vewende. (PaintDC)

    void Foo::OnPaint() 
    {
    	CPaintDC dc(this); 
    	CRect rect;
    	GetClientRect (&rect);
          CBrush white (RGB (224, 224, 224));
           dc.FillRect(CRect(0,0,50,50),&white);
     }
    

    Jetzt kann ich ja eine zweiten DeviceContext erstellen:

    CPaintDC dc(this);
    
    CDC hDCMem;
    hDCMem.CreateCompatibleDC(&dc);
    

    aber in in diesem kann ich ja nicht direkt malen, sondern ich muss diesem quasi erst sagen wohin (bitmap) die GDI funktion malen sollen:

    CBitmap bmp;
    bmp.CreateCompatibleBitmap( dc, rcBounds.right, rcBounds.bottom );
    CBitmap* pOldBitmap = hDCMem.SelectObject( &bmp );
    

    so nun meine Frage: is die DeviceContext quasi der Farbkasten und die Malwerkzeuge und das Bitmap das Blatt ?

    Wenn ich nun in dem zweiten DC über die darunter liegende Bitmap zeichne was passiert dann?

    Wenn ich zur Laufzeit die Größe des Blattes (Bitmap) vergrößern will, muss ich dann dann ein neues erzeugen, und das alte rein kopieren?

    Also Kurz der DC braucht immer ein Speicherbereich in dem er seine Zeichen ops speichert?



  • @SoIntMan sagte in Verständnisfrage GDI: DeviceContext + Bitmap:

    is die DeviceContext quasi der Farbkasten und die Malwerkzeuge und das Bitmap das Blatt ?

    Ja, kann man so sagen, s.a. Device Contexts.

    Und wenn du eine größere Bitmap erzeugen möchtest, mußt du, wie von dir beschrieben, vorgehen (also "ein neues erzeugen, und das alte rein kopieren"), denn eine Bitmap muß ein zusammengehöriger Speicherbereich sein.



  • @SoIntMan sagte in Verständnisfrage GDI: DeviceContext + Bitmap:

    Wenn ich nun in dem zweiten DC über die darunter liegende Bitmap zeichne was passiert dann?

    Na dann übermalst du die Bitmap.
    Der DC ist nur ein abstraktes Ding auf das man Zeichenoperationen anwenden kann. Wenn der DC als Ziel ne Bitmap hat, dann wendet er die Zeichenoperationen halt auf die Bitmap an. D.h. er färbt die Pixel der Bitmap den Zeichenoperationen entsprechend um.

    Also Kurz der DC braucht immer ein Speicherbereich in dem er seine Zeichen ops speichert?

    Jain. Wenn du einen DC verwendest der eine Bitmap als Ziel hat, dann speichert der DC keine Operationen, er führt sie direkt aus. D.h. er ändert direkt die Pixel der Bitmap. (Ich bin mir nicht 100% sicher, aber ich denke das ist anders wenn der DC z.B. ein Metafile als Ziel hat. Ich denke in dem Fall werden wirklich die Operationen im Metafile gespeichert. Musst du die aber keine Gedanken darüber machen so lange du mit Bitmaps arbeitest.)



  • @hustbaer sagte in Verständnisfrage GDI: DeviceContext + Bitmap:

    Jain. Wenn du einen DC verwendest der eine Bitmap als Ziel hat, dann speichert der DC keine Operationen, er führt sie direkt aus. D.h. er ändert direkt die Pixel der Bitmap. (Ich bin mir nicht 100% sicher, aber ich denke das ist anders wenn der DC z.B. ein Metafile als Ziel hat. Ich denke in dem Fall werden wirklich die Operationen im Metafile gespeichert. Musst du die aber keine Gedanken darüber machen so lange du mit Bitmaps arbeitest.)

    hmm Ok , wenn ich also die Zeichen Operation auf dem DC ausführe (welche von dem original DC erzeugt wurde) kann ich diese dann nachträglich auf ein Bitmap oder DIB speichern/mappen? Müsste ich dann nochmal einen neuen Ziel DC mit bitmap erzeugen und ein BitBlt machen!?

    EDIT ; Beispiel , Gerade ausprobiert: (lasse ich zeile 8-10 weg, wird nichts gemalt)

    CPaintDC dc(this); 
    	CRect rect;
    	GetClientRect (&rect);
    	
    	CDC mem;
    	mem.CreateCompatibleDC(&dc);
    
    	CBitmap bmp;
    	bmp.CreateCompatibleBitmap(&dc,rect.Width(), rect.Height());
    	CBitmap* pOldBitmap = mem.SelectObject( &bmp );
    
    	CBrush red (RGB (255, 0, 0));
    	mem.FillRect(CRect(CPoint(0,0),CSize(50,50)),&red);
    
    	::BitBlt(dc, 0,0, rect.Width(), rect.Height(), mem, 0, 0, SRCCOPY);
    

Anmelden zum Antworten