Avatar billede xenocypraz Nybegynder
19. august 2004 - 13:14 Der er 12 kommentarer og
1 løsning

Flimmer under invalidate C++

Hejsa,

Jeg har en Static control jeg skal have opdateret, hvis jeg opdaterer den flimrer det et kort sekund på skærmen, fordi den tegner hele den del af vinduet igen.

Jeg har kigget på noget double buffering men kunne ikke få det hen,

jeg har kigget på invalidaterect, og den syntes heller ikke og køre.
og vil nu kigge lidt på RedrawWindow.

Nogle af jer der har en ide til hvad jeg kan gøre, eller komme med nogle kode eksempler på de andre funktioner ?

det kunne jo være mig der var dum.

- XenoCypraZ
Avatar billede bertelbrander Novice
19. august 2004 - 21:54 #1
Det virker  somom du bruger InvalidateRect og tegner din Static i OnPaint, det vil give noget/meget flimmer.

Du bør i stedet tegne fra det sted du vil have opdateret. Hent en DC med GetDC og brug den med de samme funktioner som du bruger i OnPaint. Du vil stadig have brug for at tegne i OnPaint.

Hvis ikke det hjælper nok skal du oprette en memory DC som du tegner på, og som du derpå BitBlt'er på den rigtige (skærm) DC.

Jeg går ud fra at det er en static på en DialogBox under Visual C++ med MFC? Jeg kan godt prøve at lave et eksempel.
Avatar billede xenocypraz Nybegynder
19. august 2004 - 22:20 #2
Øh, jeg er lidt ny i c++, men lærer hver dag, jeg vil prøve og forklare hvad jeg laver....

Jeg har lavet en static box i et dialog. den nedarver jeg så til min egen klasse som hedder CTemperature. Iden bruger jeg onpaint til at tegne med, i den har jeg lagt tre funktioner som for dc med som reference altså (CDC &dc).

det jeg er ved at lave er et termometer, når temperaturen så skifter, kalder den en funktion der hedder set temperature, den sætter så en variabel med den korrekte temperatur og kalder invalidaterect, og det er det jeg ikke kan få til at spille....

men det du siger med bitblt har nogle andre snakket om at det nok er det rigtigt,

jeg kan sende min kode i morgen når jeg kommer på arbejde, men vil meget gerne se et eksempel
Avatar billede xenocypraz Nybegynder
19. august 2004 - 22:21 #3
og ja

Jeg går ud fra at det er en static på en DialogBox under Visual C++ med MFC? Jeg kan godt prøve at lave et eksempel.

det er korrekt, jeg nedarver den bare og har lavet lidt flere funktioner.
Avatar billede bertelbrander Novice
20. august 2004 - 00:26 #4
Jeg har lavet en lille funktion:

void CNg56Dlg::DrawIt()
{
  static int Counter;
  CStatic *Static = (CStatic *)GetDlgItem(IDC_STATIC_1);
  ASSERT(Static);
  CDC *dc = Static->GetDC();
  ASSERT(dc);

  char Buf[124];

  time_t Now;
  time(&Now);
  sprintf(Buf, "%s", ctime(&Now));
  // Create a memory DC and a "bitmap" for it to draw on
  CDC MemoryDc;
  MemoryDc.CreateCompatibleDC(dc);
  CBitmap Bitmap;
  Bitmap.CreateCompatibleBitmap(dc, 200, 200);
  MemoryDc.SelectObject(&Bitmap);

  // Draw whatever on this memory dc
  CBrush Brush(RGB((Counter & 1) ? 160 : 0, (Counter & 2) ? 160 : 0, (Counter & 4) ? 160 : 0));
  CRect R(0, 0, 200, 200);
  MemoryDc.SetBkColor(RGB((Counter & 4) ? 160 : 0, (Counter & 2) ? 160 : 0, (Counter & 1) ? 160 : 0));
  MemoryDc.SetTextColor(RGB(255, 255, 255));
  MemoryDc.FillRect(R, &Brush);
  MemoryDc.TextOut(20, 20, Buf, strlen(Buf));

  // BitBlt it onto the real DC, ie. the screen
  dc->BitBlt(0, 0, 200, 200, &MemoryDc, 0, 0, SRCCOPY);
  Counter++;
  ReleaseDC(dc);
}

Funktionen kaldes når static'en skal opdateres, i mit tilfælde gjorde jeg det ved ved WM_TIMER og ved OnPaint.

Pointen er at man tegner på MemoryDc'en, og når man er færdig overføres det hele på én gang til skærmen, derved minimeres flimmer.
Avatar billede xenocypraz Nybegynder
20. august 2004 - 08:11 #5
Vil det sige at jeg efter jeg har lavet memory dcén, skal kalde de 3 funktioner jeg har i mit termometer ?
Avatar billede xenocypraz Nybegynder
20. august 2004 - 10:22 #6
lige nu gør jeg

void CTemperatureCtrl::MemoryDC()
{
    static int Counter;
    CStatic *Static = (CStatic *)GetDlgItem(IDC_TEMPERATURE_STATIC);
    ASSERT(Static);
    CDC *dc = Static->GetDC();
    ASSERT(dc);

    char Buf[124];

    time_t Now;
    time(&Now);
    sprintf(Buf, "%s", ctime(&Now));

    // Create a memory DC and a "bitmap" for it to draw on
    CDC MemoryDc;
    MemoryDc.CreateCompatibleDC(dc);
    CBitmap Bitmap;
    Bitmap.CreateCompatibleBitmap(dc, 100, 300);
    MemoryDc.SelectObject(&Bitmap);

    //Draw whatever on this memory dc
    CBrush Brush(RGB((Counter & 1) ? 160 : 0, (Counter & 2) ? 160 : 0, (Counter & 4) ? 160 : 0));
    CRect R(0, 0, 100, 300);
    MemoryDc.SetBkColor(RGB((Counter & 4) ? 160 : 0, (Counter & 2) ? 160 : 0, (Counter & 1) ? 160 : 0));
    MemoryDc.SetTextColor(RGB(255, 255, 255));
    MemoryDc.FillRect(R, &Brush);
    MemoryDc.TextOut(20, 20, Buf, strlen(Buf));

//    PaintTermometer(&MemoryDc);

//    PaintLines(&MemoryDc);

//    PaintTemp(&MemoryDc);


    // BitBlt it onto the real DC, ie. the screen
    dc->BitBlt(0, 0, 100, 300, &MemoryDc, 0, 0, SRCCOPY);
    Counter++;
    ReleaseDC(dc);

}
¨
hvor

//    PaintTermometer(&MemoryDc);

//    PaintLines(&MemoryDc);

//    PaintTemp(&MemoryDc);

er de funktioner hvor i mine tegne instrukser ligger,

men jeg får nogle fejl når jeg kører programmet, blandt andet omkring assert.
Avatar billede bertelbrander Novice
20. august 2004 - 23:51 #7
Så vidt jeg kan se er det du gør rigtigt.

Er IDC_TEMPERATURE_STATIC en static på din dialogbox, og er CTemperatureCtrl class'en for dialog boxen der arver fra CDialog?

Du skriver at du får fejl bl.a. ved assert, hvilke assert, hvor i koden?

Hvorfra bliver din MemoryDC() funktion kaldt?

Du må gerne sende koden, så skal jeg se om jeg kan få det til at spille.
Avatar billede xenocypraz Nybegynder
21. august 2004 - 00:51 #8
hejsa, jeg kommer først på arbejder på mandag, så der sender jeg koden, CTemperatureCtrl er den klasse jeg laver der nedarver fra cdialog static,

og IDC_TEMPERATURE_STATIC, er det static felt det hele drejer sig om,

jeg kalder min MemoryDC() fra onpaint,

men skal vi ikke sige vi snakkes på mandag ?
Avatar billede xenocypraz Nybegynder
23. august 2004 - 08:36 #9
Godmorgen, her har du lidt kode :-)

void CTemperatureCtrl::MemoryDC()
{
    CDC *dc = GetDC();
    ASSERT(dc);
   
    GetClientRect(m_cRect2);

    // Create a memory DC and a "bitmap" for it to draw on
    CDC MemoryDc;
       
    MemoryDc.CreateCompatibleDC(dc);

   
    MemoryDc.SetMapMode(MM_ANISOTROPIC);                           
    MemoryDc.SetWindowExt(m_cRect2.Width(), m_cRect2.Height());                               
    MemoryDc.SetViewportExt(m_cRect2.Width(), m_cRect2.Height());   
   
    CBitmap Bitmap;

    Bitmap.CreateCompatibleBitmap(dc, m_cRect2.Width(), m_cRect2.Height());

    MemoryDc.SelectObject(&Bitmap);

    ////////////////////////////////////////////////////////////////
    // Draw whatever on this memory dc

    PaintTermometer(&MemoryDc);

    PaintLines(&MemoryDc);

    PaintTemp(&MemoryDc);

    /////////////////////////////////////////////////////////////////
    // BitBlt it onto the real DC, ie. the screen
   
    dc->BitBlt(0,0, m_cRect2.Width(), m_cRect2.Height(), &MemoryDc, 0, 0, SRCCOPY);

    ReleaseDC(dc);

}
Avatar billede xenocypraz Nybegynder
23. august 2004 - 09:27 #10
Juhuu, det ser faktisk ud til at virke nu,
Problemet var at alt blev sort, men så startede jeg som det første bare med
pDC->Rectangle(Rect). og male den grå, så var det jo faktisk det...

Jeg syntes faktisk du fortjener nogle points, så hvis du gider smide et svar...
Avatar billede bertelbrander Novice
23. august 2004 - 20:44 #11
Jeg gider ikke smide svar, jeg forsøger at undgå point.
Avatar billede xenocypraz Nybegynder
23. august 2004 - 22:25 #12
jeg takker i hvertfald 1000 gange.
Avatar billede xenocypraz Nybegynder
18. februar 2005 - 09:03 #13
svar til mig selv
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester