Tutorial WinAPI C++ 3.6 (Creación del ObjetoProgressBar)
Categorías : Windows, Programación, C y C++.

Estareis pensando... pero bueno, si ya hemos hecho nuestro propia barra de progreso hace 5 tutoriales... pues si.. pero creo interesante que tambien veais el funcionamiento del ProgressBar de windows.
Pues nada, vamos a hacer lo mismo que en los anteriores controles estandar y encapsularemos en una clase que tendrá de nombre ObjetoProgressBar, y que heredara de ObjetoControlEstandar (La clase ObjetoControlEstandar se describe en el tutorial 3.3 Creación del ObjetoEditBox).
Veamos su declaración :
// Clase que hereda ObjetoControlEstandar y se centra en las funciones de la progressbarclass ObjetoProgressBar : public ObjetoControlEstandar {public : //////// Miembros publicos// -ConstructorObjetoProgressBar(void);// -Destructor~ObjetoProgressBar(void);// -Función para crear la progressbarvoid CrearProgressBar( HWND hWndParent, const UINT nEstilos, const int cX,const int cY, const int cAncho, const int cAlto,const UINT nID, const int nMin = 0,const int nMax = 100, const int nValor = 0 );// -Función para asignar el minimo y el maximo para la progressbar// (PBM_SETRANGE)void AsignarRango(const int Minimo, const int nMaximo);// -Función para obtener el minimo y el maximo de la progressbar// (PBM_GETRANGE)void ObtenerRango(int &nMinimo, int &nMaximo);// -Función para obtener el minimo de la progressbar// (PBM_GETRANGE)const int Minimo(void);// -Función para obtener el maximo de la progressbar// (PBM_GETRANGE)const int Maximo(void);// -Función para asignar el valor de la progressbar (PBM_GETPOS)void Valor(const int nValor);// -Función para obtener el valor de la progressbar (PBM_SETPOS)// (ojo que devuelve UINT)const UINT Valor(void);};
Lo primero que vemos es una función para crear la ProgressBar, después tenemos varias funciones para asignar / obtener el mínimo, el máximo y el valor de la barra, que son : AsignarRango, ObtenerRagon, Mínimo, Máximo y Valor.
Veamos la función CrearProgressBar :
// Función para crear la progressbarvoid ObjetoProgressBar::CrearProgressBar( HWND hWndParent, const UINT nEstilos, const int cX,const int cY, const int cAncho, const int cAlto, const UINT nID,const int nMin, const int nMax, const int nValor ) {// Iniciamos los controles estandarObjetoIniciarCommonControls::Iniciar();// Creamos la ProgressBar_hWnd = CreateWindowEx( NULL, PROGRESS_CLASS, NULL, nEstilos, cX, cY, cAncho, cAlto, hWndParent,reinterpret_cast<HMENU>(IntToPtr(nID)), GetModuleHandle(NULL), NULL );// Enlazamos el windowprocedure_ConectarControl();// Establecemos los valores iniciales de la ProgressBarif (nMin != 0 || nMax != 100) AsignarRango(nMin, nMax);if (nValor != 0) Valor(nValor);}
Lo primero que se hace es llamar a la función ObjetoIniciarCommonControls::Iniciar. Esta función llama a la API InitCommonControlsEx para iniciar los controles estándar de windows para nuestra aplicación. Al iniciar los CommonControlEx podemos utilizar controles que no son estandar de windows 95, y adoptar el aspecto grafico del sistema operativo (siempre que la aplicacion tenga su archivo .manifest).
Lo segundo que se hace es llamar a la API CreateWindowEx con el segundo parámetro "PROGRESS_CLASS" (que es una macro para identificar la clase). Esto hace que el control creado se convierta en un PROGRESSBAR.
Lo siguiente es llamar a la función _ConectarControl, que re-emplazara el WindowProcedure de la ProgressBar por el nuestro.
Y por último asignamos los valores mínimo, máximo y valor. Para ello utilizamos la función AsignarRango, y la función Valor.
Ahora veamos como funcionan las funciones AsignarRango y ObtenerRango :
// Función para asignar el minimo y el maximo para la progressbarvoid ObjetoProgressBar::AsignarRango(const int nMinimo, const int nMaximo) {SendMessage(_hWnd, PBM_SETRANGE, 0, MAKELPARAM(nMinimo, nMaximo));}// Función para asignar el minimo y el maximo para la progressbarvoid ObjetoProgressBar::ObtenerRango(int &nMinimo, int &nMaximo) {PBRANGE Rango;SendMessage(_hWnd, PBM_GETRANGE, 0, reinterpret_cast<LPARAM>(&Rango));nMinimo = Rango.iLow;nMaximo = Rango.iHigh;}
La función AsignarRango manda el mensaje PBM_SETRANGE con la API SendMessage, especificando en el LPARAM el mínimo y el máximo. Para especificar el mínimo y el máximo podemos utilizar la macro MAKELPARAM. Y la función ObtenerRango manda el mensaje PBM_GETRANGE con la API SendMessage especificando en el LPARAM una estructura del tipo PBRANGE en la que nos devolvera el valor mínimo y máximo.
También puede que necesitemos obtener solo el mínimo o solo el máximo, para ello se han implementado las funciones Minimo y Maximo :
// -Función para obtener el minimo de la progressbarconst int ObjetoProgressBar::Minimo(void) {return SendMessage(_hWnd, PBM_GETRANGE, FALSE, NULL);}// -Función para obtener el maximo de la progressbarconst int ObjetoProgressBar::Maximo(void) {return SendMessage(_hWnd, PBM_GETRANGE, TRUE, NULL);}
Para obtener el mínimo y el máximo en estas funciones se manda el mensaje PBM_GETRANGE con la API SendMessage. La única diferencia entre estas dos funciones es que en el wParam la función Minimo especifica FALSE, y la función Maximo especifica TRUE. El mismo mensaje PBM_GETRANGE puede funcionar de varias formas : puede obtener el mínimo y el máximo en la misma llamada, o solo obtener el mínimo o el máximo.
Por último nos queda ver las funciones para asignar y obtener el valor :
// -Función para obtener el maximo de la progressbarconst UINT ObjetoProgressBar::Valor(void) {return SendMessage(_hWnd, PBM_GETPOS, TRUE, NULL);}// -Función para asignar el maximo de la progressbarvoid ObjetoProgressBar::Valor(const int nValor) {SendMessage(_hWnd, PBM_SETPOS, static_cast<WPARAM>(nValor), NULL);}
Como podéis ver el funcionamiento es bastante fácil, se utiliza la API SendMessage, y se le pasa el parámetro PBM_GETPOS para obtener el valor, o el parámetro PBM_SETPOS para asignarlo.
Para mas información referente al control ProgressBar consulta el siguiente enlace de la MSDN : ProgressBar Control.
Siguiente tutorial : 3.7 Creación del ObjetoListView.