Gitternetz flackert



  • Hi

    Bin gerade dabei in eine SDI-Anwenung mit einem Gitternetz zu erstellen. Nun habe ich aber das Problem das wenn ich das Programm starte das Gitternetz flackert und die Zwischenräume der Linien auf einmal weiß sind.

    Hier mein Code, den ich in OnDraw drin habe

    CPen gridPen (PS_DOT, 1, RGB(81,81,81));
    pDC->SelectObject (&gridPen);
    // Vertikal
    for (int i=1; i<=20; i++) 
    { 
    pDC->MoveTo (8, i*30); 
    pDC->LineTo (1012, i*30); 
    }
    // Horizontal
    for (int i=1; i<=33; i++) 
    { 
    pDC->MoveTo (i*30, 8); 
    pDC->LineTo (i*30, 605);
    }
    


  • Ich denke, das Flackern kriegst du weg, indem du dir einen Memory DC erzeugst, in den du dein Gitter zeichnest. Danach kannst du es in einem Rutsch in deinen DC 'reinblitten (findest du hier über die Forensuche).



  • Aha 😕 ich hab null verstanden.
    Sorry aber ich bin noch eine Anfängerin auf dem Gebiet, lerne Visual C++ in meiner Ausbildung bzw. für meinen Betrieb und von MemoryDC höre ich das erste mal. 😞



  • Shona schrieb:

    Aha 😕 ich hab null verstanden.
    Sorry aber ich bin noch eine Anfängerin auf dem Gebiet, lerne Visual C++ in meiner Ausbildung bzw. für meinen Betrieb und von MemoryDC höre ich das erste mal. 😞

    Ein MemoryDC ist nicht weiter als ein Gerätekontext, der im Speicher erzeugt wird. Wenn du in den PaintDC zeichnest, dann wird dies sofort auf dem Bildschirm dargestellt. Damit kommt auch das Flackern zustande, da ja mit jedem geänderten Pixel bzw. mit jeder neuen geometrischen Figur (Linie, Fläche, ...) ein Neuzeichnen erzwungen wird. Bei der Technik mit dem MemDC (wird auch als OffScreen-Technik bezeichnet) zeichnest du erst in dem im Speicher liegenden Gerätekontext und blittest den nur einmal auf den Schirm. Damit reduziert man das Flackern. Google mal nach MemDC, CreateCompatible.... , ....



  • Hier ist ein alter Thread von mir. Der sollte dir weiterhelfen. Sieh dir die Screenshot-Funktion an (memory dc erzeugen, füllen, per BitBlt/StretchBlt umkopieren).

    http://c-plusplus.net/forum/viewtopic-var-t-is-188601-and-highlight-is-memdc.html

    Die MSDN bietet auch Beispiele:

    http://msdn.microsoft.com/de-de/library/kwxzck32(VS.80).aspx



  • AndyDD schrieb:

    Ein MemoryDC ist nicht weiter als ein Gerätekontext, der im Speicher erzeugt wird. Wenn du in den PaintDC zeichnest, dann wird dies sofort auf dem Bildschirm dargestellt. Damit kommt auch das Flackern zustande, da ja mit jedem geänderten Pixel bzw. mit jeder neuen geometrischen Figur (Linie, Fläche, ...) ein Neuzeichnen erzwungen wird. Bei der Technik mit dem MemDC (wird auch als OffScreen-Technik bezeichnet) zeichnest du erst in dem im Speicher liegenden Gerätekontext und blittest den nur einmal auf den Schirm. Damit reduziert man das Flackern. Google mal nach MemDC, CreateCompatible.... , ....

    Danke, das habe ich verstanden aber wie verwende ich das auf meinen Code?
    Wo, Wie und Was muss ich den einfügen?

    Habe nach Beispielen über Google gesucht aber keines gefunden das mir weiter hilft, das diese immer über Bitmaps sind.

    @_matze
    Verstehst du überhaupt das ich noch Anfänger bin und das noch nie gemacht habe bzw. darüber gelesen habe. Wie soll mir da dein Code helfen? 😉

    MFG
    Shona



  • Shona schrieb:

    @_matze
    Verstehst du überhaupt das ich noch Anfänger bin und das noch nie gemacht habe bzw. darüber gelesen habe. Wie soll mir da dein Code helfen? 😉

    Klar, verstehe ich. 🙂 Ich bin da ja auch kein Experte. Und wenn ich so überlege, habe ich memory dc's eigentlich immer nur mit Bitmaps benutzt. Ich hab dir mal was gebastelt (mit Bitmap), aber das Ergebnis ist nicht das gleiche (Hinergrund ist schwarz). Vielleicht kannst du ja damit was anfangen (z.B. herausfinden, wie man da 'ne Transparenz reinkriegt).

    CDC memDC;
        memDC.CreateCompatibleDC(pDC);
        CBitmap memBmp;
        memBmp.CreateCompatibleBitmap(&memDC,1012,605);
        memDC.SelectObject(memBmp);
        CPen gridPen (PS_DOT, 1, RGB(81,81,81)); 
        memDC.SelectObject (&gridPen); 
        // Vertikal 
        for (int i=1; i<=20; i++) 
        { 
          memDC.MoveTo (8, i*30); 
          memDC.LineTo (1012, i*30); 
        }
        // Horizontal 
        for (int i=1; i<=33; i++) 
        { 
          memDC.MoveTo (i*30, 8); 
          memDC.LineTo (i*30, 605); 
        }
        RECT rc;
        pDC->GetWindow()->GetClientRect(&rc);
        if(!pDC->BitBlt(rc.left,rc.top,(rc.right-rc.left),(rc.bottom-rc.top),&memDC,0,0,SRCCOPY)) {
          //error!
        }
    

    P.S.: Dein Code hat bei mir überhaupt nicht geflackert! Was für einen Rechner nutzt du denn?

    EDIT: Ok, ich hab's. ersetze einfach die Zeile mit BitBlt durch die folgende:

    if(!pDC->TransparentBlt(rc.left,rc.top,1012,605,&memDC,0,0,1012,605,RGB(0,0,0))) {
    

    GetClientRect brauchst du auch nicht, da du ja feste Werte für Höhe und Breite verwendest. Je nachdem, was du machen willst, kannst du das ja ändern, so dass das Gitter immer das ganze Fenster ausfüllt.



  • Der PC ist in meiner Signatur (2. Link)

    Flackert bei mir immer noch und der Hintergrund muss Weiß sein und darf nur in der Fläche 6,6,1012,605 (x1,y1,x2,y2) sein, da sonst alles andere weg ist.

    das flackern tritt erst dann auf wenn ich das eigentlichtliche programm starte (über Aufzeichnung - Starten)

    Habe auch noch mal über Google gesucht und dieses MemDc von Codeproject geladen. dies funktioniert auch und es flackert nicht aber ich kann es nicht auf eine fläche begrenzen.



  • Shona schrieb:

    Flackert bei mir immer noch und der Hintergrund muss Weiß sein und darf nur in der Fläche 6,6,1012,605 (x1,y1,x2,y2) sein, da sonst alles andere weg ist.

    Der Hintergrund ist mit TransparentBlt so, wie er ohne Gitter ist, da transparent. Das sollte also passen. Warum es bei dir flackert, weiß ich nicht. Dein Code, in ein frisches Projekt kopiert, flackert bei mir halt nicht. Vielleicht zeichnest du noch tausend andere Sachen, die das Flackern bewirken.

    Shona schrieb:

    das flackern tritt erst dann auf wenn ich das eigentlichtliche programm starte (über Aufzeichnung - Starten)

    😕 Was meinst du damit? Wann sollte es sonst flackern, als nach dem Programmstart? Vorher passiert ja nicht viel... 😉

    Shona schrieb:

    Habe auch noch mal über Google gesucht und dieses MemDc von Codeproject geladen. dies funktioniert auch und es flackert nicht aber ich kann es nicht auf eine fläche begrenzen.

    Kenn ich nicht.



  • Das einzigste was ich noch zeichne ist eine Linie (ein kleines Osziloskop) wobei ich dazu sagen muss das es bis jetzt nur eine ist, am Ende müssen es aber 8 sein.

    Hier mal ein Bild

    Wenn ich nur rausfinden würde wie ich das links und oben noch verkleinere dann kann ich dieses MemDc verwenden, aber solange ich das nicht rausfinde zeigt der mir das nicht richtig an bzw. der voherige Hintergrund flackert an den stellen immer durch.

    Hab auch erhausgefunden das man mit IntersectClipRect(x1,y1,x2,y2) den Bereich bestimmen kann der nur gezeichnet werden soll. funktioniert auch aber alles andere ist dann schwarz aussenrum.

    Eigentlich bin ich schon weiter aber doch noch am Anfang weil alles nicht so will wie es eigentlich soll.

    MFG
    Shona

    PS: Ich mach jetzt ertmal feierabend 😉



  • Ich hab das mit MemDC auch nur in Verbindung mit Bitmaps genommen. In der OnDraw wird nur der MemDC erzeugt und die Bitmap reingeschoben sowie dann geblittet.
    Das Erstellen und das Zeichnen in die Bitmap erfolgt in den einzelnen Methoden der Doc-Klasse. Jetzt kann man sagen: zeichnen in der Doc, das verstößt doch gegen das Doc-/View-Prinzip? Nicht ganz, denn gezeichnet (in dem Falle das Anzeigen oder blitten der Bitmap auf dem Bildschirm) wird ja weiterhin in der OnDraw und die ist ja eine Methode der View-Klasse.


Anmelden zum Antworten