NovaMonoFix
Errores PHP
X
Usuario
Password
0 FPS

Tutorial WinAPI C++ 3.5 (Creación del ObjetoComboBox)

06 de Noviembre del 2010 por Josep Antoni Bover, 0 visitas, 0 comentarios, 0 votos
Categorías : Windows, Programación, C y C++.
La web está en segundo plano, animación en pausa.
Cargando animación...
Tutorial WinAPI C++ 3.5 (Creación del ObjetoComboBox)

En windows un combobox es un control que consiste en un EDITBOX que tiene un BUTTON al lado, y que al presionar ese button despliega un LISTBOX con varias opciones.

En este tutorial veremos el funcionamiento básico del COMBOBOX, y lo encapsularemos dentro de la clase ObjetoComboBox. Esta clase heredara de ObjetoControlEstandar (La clase ObjetoControlEstandar se describe en el tutorial 3.3 Creación del ObjetoEditBox)

Tenemos que tener bien claro para que vamos a querer usar este control, ya que podemos usarlo como una forma de seleccionar opciones fijas, o tambien podria servirnos para otros fines que no requieran opciones fijas, como por ejemplo insertar un texto a buscar que nos muestre otras posibilidades, etc...

Veamos su declaración :

Archivo : ObjetoComboBox.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Clase que hereda ObjetoControlEstandar y se centra en las funciones del combobox
class ObjetoComboBox : public ObjetoControlEstandar {
public : //////// Miembros publicos
// -Constructor
ObjetoComboBox(void);
// -Destructor
~ObjetoComboBox(void);
// -Función para crear el ComboBox
void CrearComboBox(HWND hWndParent, const UINT nEstilos, const TCHAR *nTexto,
const int cX, const int cY,
const int cAncho, const int cAlto, const UINT nID );
// -Función para agregar un texto a la posición especificada
// Si omitimos nPos se agregara al final
void InstertarString(const TCHAR *nTxt, const UINT nPos = UINT_MAX);
// -Función para seleccionar un string de la lista
void Seleccion(const UINT nPos);
// -Función obtener la selección de la lista
UINT Seleccion(void);
// -Función para borrar el texto de la posición especificada
void BorrarString(const UINT nPos);
// -Función que borra todos los strings del ComboBox
void BorrarTodo(void);
// -Función que retorna el total de strings que tiene el ComboBox
const UINT TotalStrings(void);
// -Función para asignar el texto del combobox
BOOL AsignarTexto(const TCHAR *nTxt);
// -Función para obtener el texto del combobox
UINT ObtenerTexto(TCHAR *nTxt, const UINT TamTxt);
// -Función para obtener el texto de una posicion especificada dentro
// del LISTBOX de la COMBOBOX.
// Para estar seguros de que la función se ha realizado correctamente
// el resultado devuelto tiene que ser mas grande que cero.
UINT ObtenerTextoLista(const UINT Pos, TCHAR *nTxt, const UINT TamTxt);
protected :
HFONT _Fuente;
};

Lo primero que vemos es una función para crear la ComboBox, después tenemos varias funciones para manipular los strings de la lista interna del ComboBox : InsertarString, BorrarString, BorrarTodo, y ObtenerTextoLista. También tenemos un par de funciones que nos retornan el texto del editbox interno : AsignarTexto y ObtenerTexto. Y por ultimo tenemos dos funciones para asignar y obtener la selección dentro de la lista interna de la ComboBox.

Veamos la función CrearComboBox :

Archivo : ObjetoComboBox.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Función para crear el ComboBox
void ObjetoComboBox::CrearComboBox( HWND hWndParent, const UINT nEstilos, const TCHAR *nTexto,
const int cX, const int cY, const int cAncho, const int cAlto, const UINT nID ) {
// Iniciamos los CommonControls
ObjetoIniciarCommonControls::Iniciar();
// Creamos el control
_hWnd = CreateWindowEx( NULL, TEXT("COMBOBOX"), 0, nEstilos, cX, cY, cAncho, cAlto, hWndParent,
reinterpret_cast<HMENU>(IntToPtr(nID)), GetModuleHandle(NULL), NULL );
// Asignamos el texto al EDITBOX que tiene dentro la COMBOBOX
SetDlgItemText(hWndParent, nID, nTexto);
_ConectarControl();
// Creamos la fuente que usara el control
_Fuente = CreateFont( 13, 0, 0, 0, FW_NORMAL, false, false, false, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_ROMAN, TEXT("Tahoma") );
// Asignamos la fuente
SendMessage(_hWnd, WM_SETFONT, (WPARAM)_Fuente , 0);
}

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. Antiguamente en VC6 esto era necesario si queríamos trabajar con controles estándar, pero ahora mismo a decir verdad ya no se si es necesario, porque en mi maquina me funcionan igual los ejemplos tanto si llamo a InitCommonControlsEx como si no… y en la MSDN no dice nada.. Por lo que prefiero mantener este código por si las moscas.

Lo segundo que se hace es llamar a la API CreateWindowEx con el segundo parámetro “COMBOBOX” (que es el nombre de la clase). Esto hace que el control creado se convierta en un COMBOBOX. Para ver más nombres de control mira este enlace de la MSDN : CreateWindow (Casi al final hay una tabla que muestra los nombres de classe mas comunes)

Lo siguiente es asignar el texto especificado al EditBox interno, y llamar a la función _ConectarControl, que re-emplazara el WindowProcedure del ComboBox por el nuestro.

Y por último creamos una fuente con la API CreateFont para el button, y le mandamos el mensaje WM_SETFONT al editbox con la API SendMessage, cosa que le dirá al ComboBox que debe usar esa fuente.

Ahora veamos las funciones para interactuar con el ListBox interno de la ComboBox :

Archivo : ObjetoComboBox.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// -Funcion para agregar un texto a la posición especificada
// Si omitimos nPos se agregara al final
void ObjetoComboBox::InstertarString(const TCHAR *nTxt, const UINT nPos) {
SendMessage(_hWnd, CB_INSERTSTRING, nPos, (LPARAM)nTxt);
}
// -Funcion para borrar el texto de la posición especificada
void ObjetoComboBox::BorrarString(const UINT nPos) {
SendMessage(_hWnd, CB_DELETESTRING, nPos, 0);
}
// -Función que borra todos los strings del combobox
void ObjetoComboBox::BorrarTodo(void) {
SendMessage(_hWnd, CB_RESETCONTENT, 0, 0);
};
// -Función que retorna el total de strings que tiene el combobox
const UINT ObjetoComboBox::TotalStrings(void) {
return static_cast<UINT>(SendMessage(_hWnd, CB_GETCOUNT, 0, 0));
}
// Función para obtener texto del LISTBOX interior del COMBOBOX
// Si la funcion retorna 0 es que ha sucedido un error
UINT ObjetoComboBox::ObtenerTextoLista(const UINT nPos, TCHAR *nTxt, const UINT TamTxt) {
// Comprobamos que nTxt tenga el suficiente tamaño para obtener el texto especificado
UINT TamTextoLista = SendMessage(_hWnd, CB_GETLBTEXTLEN, nPos, NULL);
if (TamTextoLista > TamTxt) {
// Error, el buffer introducido no tiene tamaño suficiente para el texto que se quiere obtener
return 0;
}
// Obtenemos el texto de la posición especificada
return SendMessage(_hWnd, CB_GETLBTEXT, nPos, reinterpret_cast<LPARAM>(nTxt));
}

Podemos ver 5 funciones diseñadas para trabajar con el contenido del ListBox interno de la ComboBox :

Ahora veamos las funciones de Selección :

Archivo : ObjetoComboBox.cpp
1
2
3
4
5
6
7
8
9
// -Función para seleccionar un string de la lista
void ObjetoComboBox::Seleccion(const UINT nPos) {
SendMessage(_hWnd, CB_SETCURSEL, nPos, 0);
}
// -Función para seleccionar un string de la lista
UINT ObjetoComboBox::Seleccion(void) {
return SendMessage(_hWnd, CB_GETCURSEL, 0, 0);
}

La primera función se usa para asignar la selección, y en ella mandamos el mensaje CB_SETCURSEL con la API SendMessage. La segunda función se usa para obtener la selección, y en ella mandamos el mensaje CB_GETCURSEL con la API SendMessage para hacer el trabajo.

Ya solo nos queda ver las funciones ObtenerTexto y AsignarTexto :

Archivo : ObjetoComboBox.cpp
1
2
3
4
5
6
7
8
9
// Función para obtener el texto del combobox
UINT ObjetoComboBox::ObtenerTexto(TCHAR *nTxt, const UINT TamTxt) {
return GetDlgItemText(GetParent(_hWnd), GetWindowLongPtr(_hWnd, GWL_ID), nTxt, TamTxt);
}
// Función para asignar el texto del combobox
BOOL ObjetoComboBox::AsignarTexto(const TCHAR *nTxt) {
return SetDlgItemText(GetParent(_hWnd), GetWindowLongPtr(_hWnd, GWL_ID), nTxt);
}

Para obtener el texto del ComboBox utilizamos la API GetDlgItemText, y para asignarlo utilizamos la API SetDlgItemText. Además utilizamos la API GetWindowLongPtr para obtener la ID del button que necesitamos a la hora de asignar / obtener su texto.

Ahora solo nos falta saber como responder a los eventos de la ComboBox. Para ello normalmente se tiene que mirar el mensaje WM_COMMAND, o en este caso como lo tenemos encapsulado lo recibiremos por Evento_Comando de su ventana padre. Observad el siguiente ejemplo :

Archivo : 3.5 Tutorial crear ObjetoComboBox.cpp
1
ERROR!! no se ha encontrado el archivo : './Tutoriales_WinAPI/3.05 Tutorial crear ObjetoComboBox/3.5 Tutorial crear ObjetoComboBox.cpp'

Como podeis ver, comparamos la ID con ID_COMBO y la Notificación con CBN_SELCHANGE, para determinar si ha cambiado la selección dentro del listbox interno de la ComboBox. Si la comparación es positiva mostramos un mensaje con el texto de la selección.

Para mas información referente al control ComboBox consulta el siguiente enlace de la MSDN : ComboBox Control.

Siguiente tutorial : 3.6 Creación del ObjetoProgressBar.