Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Una Nueva Barra de Progeso

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Tips & Tricks
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Una Nueva Barra de Progeso Responder citando

y bien que les parece esta barra,

(por tratar de que el usuario no se aburra, esperando un proceso se puede usar esta barra)



La Barra se Va, je je


La Barra Regresa j aja


bien ahora el codigo.

los componentes usados son
1.- Tlabel
Align = alTop;
Alignment = taCenter;
WordWrap = true
2.- TPanel
Align = alBottom
3.- TTimer
Enabled = true
Interval = 250

algunas variables, dentro del archivo .h del proyect
Código:
class TFBARRA_PROGRESO : public TForm
{
__published:   // IDE-managed Components
    TLabel *Label1;
    TPanel *Panel1;
    TTimer *Timer1;
    void __fastcall Timer1Timer(TObject *Sender);

private:   // User declarations
public:      // User declarations
    __fastcall TFBARRA_PROGRESO(TComponent* Owner);
    void DibujaBarra(HWND hWnd,int posLeft,bool Sentido);
    int Ancho_Barra;
    int Limite,Incremento;
    int PosBarra;
    bool terminar,Sentido;

};


y el codigo de las funciones

Código:
//---------------------------------------------------------------------------
__fastcall TFBARRA_PROGRESO::TFBARRA_PROGRESO(TComponent* Owner)
    : TForm(Owner)
{
  this->Ancho_Barra = 50;
  this->Limite = this->Panel1->Width-this->Ancho_Barra;
  this->PosBarra=1;
  this->terminar = false;
}
//---------------------------------------------------------------------------

void TFBARRA_PROGRESO::DibujaBarra(HWND hWnd,int posLeft,bool Sentido)
{
//---------------------
    TCanvas *ACanvas= new TCanvas;
    Graphics::TBitmap *Barra  = new Graphics::TBitmap;
    ACanvas->Handle = GetDC(hWnd);
    TColor c1,c2;
    TColor Fuerte = (TColor) 0x00D02D93 ;
    TColor Debil  = clWhite;//(TColor) 0x00DDC8CB;
    int Rf,Gf,Bf;
//-------------------------
    int Rd,Gd,Bd;
    int cR, cG, cB;
    float nTonos;
    float incremento ;
    //-------------------
    int i, X1, X2;
    RECT rectClient;        // Area Cliente
    ::GetClientRect(hWnd, &rectClient);
    // segun esto lo limpiamos
    ACanvas->Brush->Color = clWhite;
    ACanvas->Pen->Color = clBlack;
    ACanvas->FillRect(rectClient);

    // creamos la region para la barra
    Barra->Width  = this->Ancho_Barra;
    Barra->Height = rectClient.bottom-2;
    TRect RectTmp = Barra->Canvas->ClipRect;

    ACanvas->Brush->Color = clBlack;
    ACanvas->FrameRect(ACanvas->ClipRect);

//*************************
  // pintar el degradado
       // LADO DERECHO
        if (Sentido)
        {
            c2 = Fuerte;
            c1 = Debil;
        }
        else
        {
           c1 = Fuerte;
           c2 = Debil;
        }
        Rf = GetRValue(c1);
        Gf = GetGValue(c1);
        Bf = GetBValue(c1);
        Rd = GetRValue(c2)-Rf;
        Gd = GetGValue(c2)-Gf;
        Bd = GetBValue(c2)-Bf;
        nTonos = 7000;
        incremento = incremento = (float) nTonos / RectTmp.Width();
        for (i=RectTmp.Left; i<=RectTmp.Width()-3; ++i)
        {
            cR = Rf + MulDiv(incremento*i, Rd, nTonos);
            cG = Gf + MulDiv(incremento*i, Gd, nTonos);
            cB = Bf + MulDiv(incremento*i, Bd, nTonos);
            Barra->Canvas->Brush->Color = (TColor) RGB(cR, cG, cB);
            Barra->Canvas->Pen->Color   = (TColor) RGB(cR, cG, cB);
            Barra->Canvas->MoveTo(RectTmp.left+i, RectTmp.top);
            Barra->Canvas->LineTo(RectTmp.left+i, RectTmp.Bottom);
        }
//*************************

    ACanvas->Draw(posLeft,1,Barra);


}
//---------------------------------------------------------------------------

void __fastcall TFBARRA_PROGRESO::Timer1Timer(TObject *Sender)
{
    this->Timer1->Enabled=false;
    this->Canvas->TryLock();
    Application->ProcessMessages();
    this->DibujaBarra(this->Panel1->Handle,this->PosBarra,this->Sentido);

    if(this->PosBarra>=this->Limite)
    {
        this->Incremento=-15;
        this->Sentido = false;
    }
    if(this->PosBarra<=1)
    {
        this->Incremento=15;
        this->Sentido = true;
    }
    this->PosBarra+=this->Incremento;

    if(this->terminar)
        this->Close();

    this->Timer1->Enabled=true;
}
//---------------------------------------------------------------------------


una manera de usarla seria la siguiente
Código:
TFBARRA_PROGRESO *Fbp = new TFBARRA_PROGRESO (this);
    Fbp->Show();
    //{realizamos algunos proeceso }
    Fbp->terminar=true; //activamos el terminar
    delete Fbp;


Si me preguntan, por que la hice, bien, por que NUNCA PUDE HACER QUE LA BARRA "PROGRESS_BARR" REGRESARA Evil or Very Mad

al no saber como hacerlo, invente una

se aceptan opiniones y mejoras!!
_________________
Cool


Ultima edición por Cesar C. Salazar Gonzalez el Jue 16 Ago, 2007 5:59 am, editado 3 veces
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

Hola César C. Salazar González,

Estoy mirando tu codigo de barra, esta genial ... pero ademas muestras una forma completa ( los dos dibujos izquierda y derecha ) . en la que muestras una forma redonda en las puntas y con distintos colores y la verdad es que ando buscando algo de ese estilo para.. mi consulta seria, sabes como cambiar la forma y color de las formas??

si tienes algo, me podrias ayudar.

att. vrodriguez
Volver arriba
Ver perfil de usuario Enviar mensaje privado MSN Messenger
Mensaje    Asunto: Responder citando

la apariencia es la de windows xp, con el xp.rc, que se ha dejado por aqui en el foro, para realizar formas, con diferenetes vistas, tambien dentro del foro se ha dejado..


un saludo y date una vuelta, por la opcion buscar, si no llegaras a econtrarlo dime, ya que la barra, se debe meter en un hilo, para su correcta ejecucion..

saludos..
_________________
Cool
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

César C. Salazar González ...Gracias por responder
la verdad que despues que pregunte, me di cuenta que en esta parte "tips & Trick" es solo para codigos y no consulta asi que MIL DISCULPAS A TODOS... NUNCA MAS....

Tratare de ver lo que me indicas, pero un fin de semana que me quede solo en casa, me dedique a ver el foro en forma COMPLETITAAA.. y no vi mucho del tema al respecto... quisas fueron muchos de un viaje... pero de que hay tema ... hay tema... algunos muy repetidos y vi quienes son los mas solicitados... asi que MIS RESPETOS PARA TI... estas entre los mas consultados... al que no vi mucho y lo tengo tambien bien considerado es a mi compatriota VIKTOR.. para aparecera en VIKTOR CONTRATACA... JA JA JA JA.. asi que animo para ustedes que son los que responden y nos estaremos comunicando.. ojala tenga suerte.. adios...

att. Victor R.
Volver arriba
Ver perfil de usuario Enviar mensaje privado MSN Messenger
Mensaje    Asunto: Ahora con Hilo (Thread) Responder citando

Bien se ha cambiado, para trabajar de manera concurrente

esto es el codigo del Form donde se dibuja la barra
TLabel *Label1; // mostrar un msg
TPanel *Panel1; // donde dibujamos la barra
TBevel *Bevel1; // una linea
TLabel *Label2; // otro label para poner otro msg.

Archivo .cpp del Form que dibuja la Barra,
Código:
//---------------------------------------------------------------------------

#include <vcl>
#pragma hdrstop

#include "UBarra.h"


//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFBarra *FBarra;
//---------------------------------------------------------------------------
__fastcall TFBarra::TFBarra(TComponent* Owner)
    : TForm(Owner)
{
    pBarra = new THBarra(this->Panel1->Handle,this->Panel1->Width,false);;
}
//---------------------------------------------------------------------------
void __fastcall TFBarra::FormDestroy(TObject *Sender)
{
    pBarra->Terminate();   
}
//---------------------------------------------------------------------------


Cita:
//PARA QUE LA BARRA SE DIBUJE CORRECTAMENTE DEBE
// ESTABLECERSE EL SIGUIENTE CODIGO DESPUES DE
//ACTIVARSE
void __fastcall TFBarra::::FormActivate(TObject *Sender)
{
Application->ProcessMessages();
}
//---------------------------------------------------------------------------



Dentro del .h del Form que dibuja la barra
//---------------------------------------------------------------------------

Código:
#ifndef UBarraH
#define UBarraH
//---------------------------------------------------------------------------
#include <Classes>
#include <Controls>
#include <StdCtrls>
#include <Forms>
#include <ExtCtrls>
#include "THBarra.h"  // encabezado del Thread
//---------------------------------------------------------------------------
class TFBarra : public TForm
{
__published:   // IDE-managed Components
    TLabel *Label1;
    TPanel *Panel1;
    TBevel *Bevel1;
    TLabel *Label2;
    void __fastcall FormDestroy(TObject *Sender);
private:   // User declarations
public:      // User declarations
    __fastcall TFBarra(TComponent* Owner);
    THBarra *pBarra; // Declaracion del Thread

};
//---------------------------------------------------------------------------
extern PACKAGE TFBarra *FBarra;
//---------------------------------------------------------------------------
#endif



y ahora si el codigo del Thread, para que funcione correctamente.


dentro del Cpp del Thread

Código:

//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

#include <vcl>
#pragma hdrstop

#include "HBarra.h" //unidad del Thread
#include "UBarra.h"  // unidad del Form donde se dibuja la barra
#pragma package(smart_init)
//---------------------------------------------------------------------------

__fastcall THBarra::THBarra(HWND hWnd,int AnchoComponente,bool CreateSuspended)
    : TThread(CreateSuspended)
{
    Priority             = tpNormal;
    FreeOnTerminate      = false;
    this->hwndPanel      = hWnd;
    this->Ancho_Barra    = 45;
    this->Limite         = AnchoComponente - this->Ancho_Barra;
    this->PosBarra       = 1;
    this->terminar       = false;
    this->Sentido        = true;
    this->ACanvas        = new TCanvas;
    this->Barra           = new Graphics::TBitmap;
    this->ACanvas->Handle = GetDC(this->hwndPanel);

    this->Fuerte = (TColor) 0x00FFAA00;  // color del Tumb
    this->Debil  = clWhite;//(TColor) 0x00DDC8CB;

}
//---------------------------------------------------------------------------

void __fastcall THBarra::Execute()
{
    //---- Place thread code here ----
     while (!Terminated)
     {
          if (this->PosBarra >= this->Limite)
          {
               this->Incremento = -15;
               this->Sentido    = false;
          }
          if (this->PosBarra < 1)
          {
               this->Incremento = 15;
               this->Sentido    = true;
          }
          this->PosBarra += this->Incremento;

          //this->Synchronize(MoverBarra);
          try
          {
               MoverBarra();
          }
          catch(...)
          {}
          Sleep(150);
     }
}
//---------------------------------------------------------------------------

void __fastcall THBarra::MoverBarra(void)
{
     ::GetClientRect(this->hwndPanel, &this->rectClient);

     // segun esto lo limpiamos
     this->ACanvas->Brush->Color = clWhite;
     this->ACanvas->Pen->Color   = (TColor) 0x00FFAA00;
     this->ACanvas->FillRect(this->rectClient);

     this->ACanvas->Brush->Color = clBlack;
     this->ACanvas->FrameRect(this->ACanvas->ClipRect);

     // creamos la region para la barra
     this->Barra->Width  = this->Ancho_Barra;
     this->Barra->Height = this->rectClient.bottom - 3;
     this->RectTmp       = this->Barra->Canvas->ClipRect;

     //*************************
     // pintar el degradado
     // LADO DERECHO

     if (Sentido)
     {
          this->c2 = this->Fuerte;
          this->c1 = this->Debil;
     }
     else
     {
          this->c1 = this->Fuerte;
          this->c2 = this->Debil;
     }

     this->Rf = GetRValue(this->c1);
     this->Gf = GetGValue(this->c1);
     this->Bf = GetBValue(this->c1);
     this->Rd = GetRValue(this->c2) - this->Rf;
     this->Gd = GetGValue(this->c2) - this->Gf;
     this->Bd = GetBValue(this->c2) - this->Bf;
     this->nTonos = 700;
     this->incremento = (float) this->nTonos /  this->RectTmp.Width();

     for (this->i = this->RectTmp.left; this->i < this->RectTmp.Width(); ++ this->i)
     {
          this->cR = this->Rf + MulDiv(this->incremento*i, this->Rd, this->nTonos);
          this->cG = this->Gf + MulDiv(this->incremento*i, this->Gd, this->nTonos);
          this->cB = this->Bf + MulDiv(this->incremento*i, this->Bd, this->nTonos);
          this->Barra->Canvas->Brush->Color = (TColor) RGB(this->cR, this->cG, this->cB);
          this->Barra->Canvas->Pen->Color   = (TColor) RGB(this->cR, this->cG, this->cB);
          this->Barra->Canvas->MoveTo(this->RectTmp.left+this->i, this->RectTmp.top);
          this->Barra->Canvas->LineTo(this->RectTmp.left+this->i, this->RectTmp.Bottom);
     }

     //*************************
     this->ACanvas->TryLock();
     this->ACanvas->Draw(this->PosBarra,1,this->Barra);
     this->ACanvas->Unlock();
}
//---------------------------------------------------------------------------




y Dentro del .H del Thread

Código:

//---------------------------------------------------------------------------
#ifndef THBarraH
#define THBarraH
//---------------------------------------------------------------------------
#include <Classes>
//---------------------------------------------------------------------------


class THBarra : public TThread
{
private:
protected:
    void __fastcall Execute();
    void __fastcall MoverBarra(void);
    HWND hwndPanel;
public:
    __fastcall THBarra(HWND hWnd,int AnchoComponente,bool CreateSuspended);
    int Ancho_Barra;
    int Limite,Incremento;
    int PosBarra;
    bool terminar,Sentido;
    TCanvas *ACanvas;
    Graphics::TBitmap *Barra;
// variables************************
    TColor c1,c2;
    TColor Fuerte;  // color del Tumb
    TColor Debil;//(TColor) 0x00DDC8CB;
    int Rf,Gf,Bf;
//-------------------------
    int Rd,Gd,Bd;
    int cR, cG, cB;
    float nTonos;
    float incremento ;
    //-------------------
    int i, X1, X2;
    RECT rectClient;        // Area Cliente
    TRect RectTmp;
//********************************************
};
//---------------------------------------------------------------------------
#endif



haa!! se me olvidada, esta es la manera de llamar al form para crear la barra, en alguna parte de algun form que necesites mostrarla

Código:
   
//Calculamos las direcciones al iniciar para comparar despues
// creamos el form dinamicamente
   TFBarra *FB = new TFBarra(this);     
    FB->Label1->Caption = "Calculando IP's"; //metes el msg
    FB->Show();// muestras el form

// realizas operaciones
// En este caso pongo un SLEEP(2000) para que la barra se vea

    Sleep(2000);

// despues de realizar tus operaciones..

    delete FB; // borramos la barra

y esta es la muestra, ya corriendo



Saludos...
_________________
Cool


Ultima edición por Cesar C. Salazar Gonzalez el Mie 17 Oct, 2012 7:54 pm, editado 6 veces
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

Cesar,

Excelente barra de progreso. Sin embargo, me he encontrado con un problemilla que tal vez no se haya tenido en cuenta. El tiempo el cual podemos tener la barra activa no es infinito; resulta que para mi aplicacion, en la cual realizo una bateria de tests a un dispositivo (y que puede durar horas) activo la barra de progreso y a los 20 minutos o asi me salta un error de falta de recursos.

Observando el Administrador de Tareas de XP, observo que la carga de transacciones va ascendiendo debido a la barra de progreso hasta que llego al maximo.

Alguna solucion al respecto?

Gracias

Juan M. Roldan
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

mirando medio por arriba el código, parece ser por estas dos líneas:

Código:

TCanvas *ACanvas= new TCanvas;
Graphics::TBitmap *Barra  = new Graphics::TBitmap;


declaralos como variables globales.
_________________
Crandel

"hay 10 tipos de personas, las que ven en binario y las que no"

Angel Zeitoune - Artículo: Generación de eventos en C++Builder
Volver arriba
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor MSN Messenger
Mensaje    Asunto: Responder citando

Se ha modificado el codigo prueben, el que ahora se encuentra mas arriba ahora si funciona mas rapido y no consume recursos
_________________
Cool


Ultima edición por Cesar C. Salazar Gonzalez el Jue 28 Jul, 2005 9:23 pm, editado 1 vez
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

Cesar,

La barra funciona a las mil maravillas sin consumir recursos.

Un saludo y gracias!

Juan M. Roldan
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

uhmm , la barra falla, es un error del canvas, con el gdi, no entender

Se ha usado siguiendo estos pasos.
Se apertura la barra
Se ejecuta el Proceso
Se finaliza la Barra

Si el proceso a realizar se hace en muy poco tiempo la barra falla.

¿Como se podría agregar un tiempo de espera antes de que la barra se muestre?

Por ejemplo se apertura la barra, se ejecuta el proceso pero la barra no se muestra hasta que halla pasado un tiempo prudencial como de medio o un segundo
en el caso de finalizar el proceso antes de mostrarse la barra simplemente se finaliza la barra.

Creo que para resolverlo de esta forma, debemos crear primero el Thread y este encargarse de crear al formulario( al reves de como se ha implementado)

Mi fuerte no son los Threads, alguien podria hacer la modificación que se sugiere? Rolling Eyes
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Se ha corregido el error para que la barra se muestre correctamente


//PARA QUE LA BARRA SE DIBUJE CORRECTAMENTE DEBE
// ESTABLECERSE EL SIGUIENTE CODIGO DESPUES DE
//ACTIVARSE en el form donde se dibuja el panel que sirve de barra
void __fastcall TFBarra::::FormActivate(TObject *Sender)
{
Application->ProcessMessages();
}
//---------------------------------------------------------------------------
_________________
Cool
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Muy buena,, pero.... Responder citando

Hola Cesar.

Super buena tu barra de espera.
Pero te queria comentar un detalle visual, a lo mejor me pasa solo a mi.

Pero cada 2 segundos... mas o menos.... se nota demasiado el repintado de la barra decolorada..... entre medio, se vé el desplazamiento suavemente y agradable, pero a los dos segundos, se nota ese repintado que hace que en un momento la parte decolorada se vea blanca por una fraccion de segundo.

Hay una forma en que todo el momento en que la barra esté activa se vea suavemente el desplazamiento?....

No se si a ti te pasa, pero es lo que yo pude observar al momento de correr la barra.

De antemanos muchas gracias.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

verifica el Application->ProcessMessage(), en las lineas que debe llevarlo, generalmente es dentro de un ciclo,para que la ejecucion no sea haga lenta
_________________
Cool
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

César: Me está dando un par de errores el código y no veo la razón. En el Execute() del thread, al compilar me da un error E2277 Lvalue required en la línea
Código:
if(this->PosBarra<1>Incremento=15;

Veo que tiene un punto y coma al final, por lo que imagino que es una errata. He probado este código:
Código:
if(this->PosBarra<1>this->Incremento=15)
if(this->PosBarra<1>Incremento=15)

y me sigue dando el mismo error, que también aparece al compilar esta línea:
Código:
for (this->i=this->RectTmp.left; this->i<this>RectTmp.Width(); ++this->i)


Por otro lado, en ese mismo Execute() creo que sobra una llave de cierre, peor no sé cual, si la que va detrás de este if que comentao antes o la que va detrás del Sleep.
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.