Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    [C++] problemi con Invalidate Rect

    Ciao ragazzi, ho questo problema a creare un semplice editor di testo di allenamento (senza l'uso delle editbox).

    Allora posto solo il WM_CHAR, questo codice fa in modo che ogni tasto premuto venga aggiunto ad uno std::string sText.
    Dopo di che chiama InvalidateRect,hwnd,NULL,FALSE).
    Fin qui tutto bene.

    Poi quando viene premuto backspace, se la stringa ha 0 caratteri, fa ritornare la procedura, poichè non si può eliminare un carattere da una string vuota!
    Fin qui tutto bene.

    Dopo di che con sText.assign(CSTR(sText),sText.size() - 1), viene eliminato l'ultimo carattere di sText.
    Tutto bene anche qui

    Ecco che i problemi sorgono:
    se io chiamo InvalidateRect(hwnd,NULL,FALSE), non viene elimanata dalla finestra l'ultima lettera,
    se chiamo InvalidateRect(hwnd,NULL,TRUE), dato che c'è il TRUE, viene pitturata la finestra del colore di background e poi viene disegnata la stringa senza l'ultima lettera, ma così NON va bene perchè si ottitene un effetto a lampeggio.

    Sto cercando una funzione che invalida solo la zona che cambierebbe, non so come fare!

    Codice:
    codice:
    case WM_CHAR:
             switch(wParam)
                 {
                 case '\b': //backspace
                 if(sText.size() == 0)
                     return 0;
                     
                 sText.assign(CSTR(sText),sText.size() - 1);
                 InvalidateRect(hwnd,NULL,TRUE);
                 UpdateWindow(hwnd);
                 return 0;       
                 }
             sText += (TCHAR)wParam;
             InvalidateRect(hwnd,NULL,FALSE);
             break;
    Aiuto perfavore!

  2. #2
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Dovresti invalidare solo il rect che ti interessa cancellando il background.
    Per gli Spartani e Sparta usa spartan Il mio github

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    ho provato

    ci ho provato ma è praticamente impossibile cancellare il rect relativo all'ultima lettera di sText dato che 'i' e 'W' hanno larghezza diversa, e quindi non esiste un metodo per capire i pixel impegnati da una lettera (o almeno io non lo soXD)

  4. #4
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Molto probabilmente il tuo ultimo carattere sara nell'angolo su a sinistra, Quindi cancella grosso modo un 0,0,10,10.
    Per gli Spartani e Sparta usa spartan Il mio github

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    mmm

    mmm, ho provato il tuo ma senza esiti positivi, buona notizia, ho avuto un vero "colpo di cu*o", come si dice da noi:

    quasi per caso ho scritto questo codice, funziona, ma non riesco a capire perchè!!!!!
    In teoria quando stampo su ScreenDC e poi uso la BitBlt non dovrebbe cambiare nietne, e invece! Roba da non credere!
    codice:
        case WM_CHAR:
             switch(wParam)
                 {
                 case '\b': //backspace
                 if(szText.size() <= 0)
                     return 0;
                     
                 szText.assign(CSTR(szText),szText.size() - 1);
                 
    
                 
                 ScreenDC = GetDC(hwnd);
                 hdc = GetDC(hwnd);
                 
                 DrawText(ScreenDC,CSTR(szText),szText.size(),&rcText,DT_LEFT);
                 BitBlt(hdc,0,0,xClient,yClient,ScreenDC,0,0,SRCCOPY);
                 
                 ReleaseDC(hwnd,ScreenDC);
                 ReleaseDC(hwnd,hdc);
                 InvalidateRect(hwnd,NULL,TRUE);
                 UpdateWindow(hwnd);
                 return 0;                       
                 }
    
             szText += (TCHAR)wParam;
             InvalidateRect(hwnd,NULL,FALSE);
             break;

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    mmm

    e devo dire che non funziona poi troppo bene, se qualcuno ha un altra soluzione è molto meglio!

  7. #7
    Posta il codice relativo a WM_PAINT.
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    ecco

    ecco il codice:


    Questa funzione disegna un rettangolo leggermente staccato dal bordo (10 pixel (ifig)) e un po' più verso giù dalla parte alta (20 pixel (ifig + yDistac)).
    Poi disegna il testi di un pixel più spostato verso il centro rispetto al rettandolo disegnato
    codice:
        case WM_PAINT:    
             hdc = BeginPaint(hwnd,&ps);
     
             rc.left   = 0;
             rc.right  = xClient;
             rc.top    = 0;
             rc.bottom = y + yCh;
             DrawText(hdc,"Command Choiser",15,&rc,DT_CENTER);
             
             ifig = 10; 
             yDistac = 20;
             
             apt[0].x = 0 + ifig;
             apt[0].y = 0 + ifig + yDistac;  
             apt[1].x = xClient - ifig;
             apt[1].y = 0 + ifig + yDistac;; 
             apt[2].x = xClient - ifig;
             apt[2].y = yClient - ifig;
             apt[3].x = 0 + ifig;
             apt[3].y = yClient - ifig;
             apt[4].x = 0 + ifig;
             apt[4].y = 0 + ifig + yDistac;;         
                
             Polyline(hdc,apt,ELEMENT(apt));
             
             //rcText è uguale alle coordinate di apt[] eccetto che ha un pixel in più verso lo   schermo
             DrawText(hdc,CSTR(szText),szText.size(),&rcText,DT_LEFT);
             
             EndPaint(hwnd,&ps);
             break;

  9. #9
    In primo luogo, quando chiami InvalidateRect invalida solo l'area utilizzabile dalla tua "casella di testo"; questo già dovrebbe ridurre il flickering.
    Inoltre, potresti evitare di forzare il ridisegno del fondo, e disegnare invece il fondo della sola casella di testo nel WM_PAINT, usando la Polygon invece della Polyline. Questo dovrebbe ridurre il flickering alla sola area della casella di testo.
    Se ancora non bastasse, puoi ricorrere alla tecnica del double buffering; la trovi spiegata (assieme ad altri utili consigli sull'argomento) qui.
    Amaro C++, il gusto pieno dell'undefined behavior.

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    Perfetto, funziona

    Perfetto, funziona alla perfezione, grazie.

    In questo momento sto studiando edit box, e scrivere senza edit box in parallelo...e ho trovato anche un problema usando le edit box..... lo posto in un nuovo topic

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.