Visualizzazione dei risultati da 1 a 4 su 4
  1. #1

    [Delphi] Sfarfallio componente

    Ciao,
    sono sempre in ballo con il componente di un post di questi giorni.
    Il componente consiste in una progressbar in stile Windows XP con diversi colori (attualmente bcGreen e bcOrange).

    Questa è la parte di codice che disegna e aggiorna la progressbar.
    codice:
    procedure TJvXPProgressBar.Paint;
     var i: integer; Bmp: TBitmap; Step: real;
    begin
     Bmp := TBitmap.Create;
     Bmp.Transparent := True;
     Bmp.TransparentColor := clFuchsia;
    
     if FOrientation = pbHorizontal then
     begin
      Step := FMax / Round((Width - 6) / 8);
      Bmp.LoadFromResourceName(HInstance, 'LEFTCORNER_H');
      Canvas.Draw(0, 0, Bmp);
    
      for i := 0 to (Round((Width - 6) / 8)- 1) do
      begin
       if (Round(FPosition / Step) > i) then
        Canvas.Draw(3 + (8 * i), 0, DrawStep)
       else
       begin
        Bmp.LoadFromResourceName(HInstance, 'PROGRESSEMPTY_H');
        Canvas.Draw(3 + (8 * i), 0, Bmp);
       end;
      end;
    
      Bmp.LoadFromResourceName(HInstance, 'RIGHTCORNER_H');
      Canvas.Draw(Round((Width - 6) / 8) * 8 + 3, 0, Bmp);
      Width := Round((Width - 6) / 8) * 8 + 6;
     end
     else
     begin
      Step := FMax / Round((Height - 6) / 8);
      Bmp.LoadFromResourceName(HInstance, 'LEFTCORNER_V');
      Canvas.Draw(0, 0, Bmp);
    
      for i := 0 to (Round((Height - 6) / 8)- 1) do
      begin
       if (Round(FPosition / Step) > i) then
        Canvas.Draw(0, Height - 11 - (8 * i), DrawStep)
       else
       begin
        Bmp.LoadFromResourceName(HInstance, 'PROGRESSEMPTY_V');
        Canvas.Draw(0, Height - 11 - (8 * i), Bmp);
       end;
      end;
    
      Bmp.LoadFromResourceName(HInstance, 'RIGHTCORNER_V');
      Canvas.Draw(0, Round((Height - 6) / 8) * 8 + 3, Bmp);
      Height := Round((Height - 6) / 8) * 8 + 6;
     end;
    end;
    NB: la funzione DrawStep disegna "on the fly" e restituisce via TBitmap un quadratino che andrà a comporre la progressbar per il supporto "nativo" della grafica xpstyle. FOrientation è una proprietà del componente che determina l'orientamento della progressbar (pbHorizontal e pbVertical). FPosition è una proprietà del componente che ne determina lo stato di progressione su una scala da FMin a FMax.

    Le domande sono: 1. sapreste darmi qualche consiglio *pratico* per evitare che si manifesti quel fastidioso sfarfallio durante la progressione della barra? 2. sapreste indicarmi un tool simile ad Apiary OCX Expert per convertire componenti VCL in OCX?

    Screenshot senza supporto nativo

    Screenshot con supporto nativo


    Grazie!
    Stefano

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,296
    Per quanto riguarda il problema "sfarfallio", le tecniche per evitarlo sono molteplici e dipendono dal tipo di operazioni che si fanno, dal modo in cui si fanno e dalle funzioni utilizzate.

    Non ho avuto modo di osservare il codice del controllo (il tempo è tiranno, molto tiranno), pertanto potrei darti indicazioni già presenti nel codice oppure ininfluenti per la natura del controllo stesso.

    Innanzitutto, potresti verificare che il controllo non sia "opaco", cioè che non provveda automaticamente a cancellare la propria area di tracciamento ogni volta che deve essere disegnato; eseguita frequentemente, questa operazione porta ad un flickering abbastanza elevato. Se la tua procedura di disegno si occupa di disegnare l'intero controllo, incluso il fondale, allora elimina l'attributo csOpaque dalla proprietà ControlStyle, magari nel costruttore della classe.

    Un esempio:
    codice:
    constructor TMyControl.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      ControlStyle := ControlStyle - [csOpaque];
    end;
    Inoltre, i discendenti di TWinControl - se non sbaglio - hanno una funzionalità di "double buffering": l'aspetto grafico viene implicitamente tracciato in un bitmap interno che viene copiato nella sua interezza sul Canvas del controllo, eliminando alcuni effetti collaterali fastidiosi dovuti al disegno manuale dei particolari grafici del controllo nell'area occupata da quest'ultimo.

    Non è detto che questo meccanismo risolva il problema, ma si può tentare per ridurre al minimo l'effetto; per usarlo, imposta la proprietà DoubleBuffered a True, eventualmente nel costruttore.
    codice:
    constructor TMyControl.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      ControlStyle := ControlStyle - [csOpaque];
      DoubleBuffered := True;
    end;
    Al momento, non mi viene in mente nient'altro.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    Grazie mille!
    Lo sfarfallio è stato ridotto dopo aver rimosso csOpaque... anche se è ancora molto visibile.

    Il mio componente non è un discendente TWinControl e quindi non supporta il double buffering.

    Tuttavia ho provato già ieri ad implementare quel sistema cui ti riferisci... ma i risultati non sono stati eccezionali.

    Mumble... ti viene in mente altro?

    Argh non so come eliminare il problema
    Stefano

  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,296
    No, mi dispiace ma non mi viene in mente nient'altro.

    Molti controlli "flicker free" si basano su librerie grafiche e funzioni appositamente progettati allo scopo.

    Anche i controlli Win32 standard sono affetti da questo problema.

    L'unico suggerimento che posso darti è quello di ottimizzare il codice utilizzatore del controllo affinchè richiami il meno possibile l'aggiornamento della ProgressBar; accertati inoltre di invalidare il controllo solo quando il valore di Position viene effettivamente modificato.

    Come ultima indicazione, potresti cercare in rete sui soliti siti controlli ProgressBar che non abbiano flickering e che siano distribuiti con sorgente per vedere come sono stati realizzati, tentando poi di mettere in pratica la tecnica nel tuo controllo ProgressBar personalizzato.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

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.