5 WinAPI
5 WinAPI
Explorador de
soluciones > Archivos
de origen
Agregar > Nuevo
elemento
Archivo C++ (.cpp)
Configurar que sea Windows
cout<<“bye world, see you soon”; int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hInstPrev,
cout<<“…maybe?” PSTR cmdline, int cmdshow){
int: tipo de retorno. WINAPI: Indica la convención de llamada, ayuda a indicar WinMain: Nombre de la función principal
específicamente en qué lugar adecuado se va a almacenar en para un programa creado en WinApi. (Como
memoria para las funciones de WinAPI (optimizar memoria). el main en consola)
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow)
HINSTANCE: Puntero que tiene la dirección de la instancia, o sea, toda la aplicación que estamos ejecutando. Todo lo que compone el
programa como las ventanas y controles.
hInst: Puntero que hace referencia a la aplicación actual cuando se ejecuta.
hInstPrev: Al momento de ejecutar, nos dice si la instancia de la aplicación ya se había creado, o sea, la aplicación ya se
ejecutó y esto nos ayuda para evitar que se abra mas de 1 vez el programa al mismo tiempo.
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow)
PSTR: Puntero a string. Es una línea de comandos que se cmdshow: Código que el SO nos devuelve para indicarnos cómo se
ejecutan en el cmd y que el sistema operativo dice si algo debe mostrar la ventana. Ponerla en frente o detrás de otra ventana,
se necesita antes de ejecutar el programar. Como crear en pantalla completa o minimizada, etc.
carpetas, archivos, movernos de carpeta,etc.
Valores que puede tener el cmdshow
SW_SHOWDEFAULT SW_HIDE
10 0
SW_SHOWMAXIMIZED SW_SHOWMINIMIZED
3 2
https://conclase.net/winapi/curso/wincte/nCmdShow
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-
showwindow
Todos los códigos para cmdShow y lo que hace cada uno.
Nosotros no le pasamos valores a esta función.
int WINAPI WinMain(HINSTANCE hInst,
Como es la primera función que se va a ejecutar al momento de
HINSTANCE hInstPrev, PSTR
abrir el programa, quien le va a asignar los valores que necesita, es
cmdline, la maquina, el sistema operativo.
int cmdshow)
Registrar la Crear la
ventana ventana
> HWND
Handler de Window.
HWND: Handler/puntero de la ventana padre, en caso de que esta ventana sea hijo.
MAKEINTRESOURCE: Convierte un valor entero a un valor compatible con las funciones de WinAPI. Hacer
un recurso utilizando un entero.
Función para mostrar una ventana
ShowWindow( HWND hwnd, int nCmdShow);
https://conclase.net/winapi/curso/wincte/
nCmdShow
https://docs.microsoft.com/en-us/windows/
win32/api/winuser/nf-winuser-showwindow
Nuevo tipo de dato
> MSG
MESSAGE – Mensaje
Las variables de este tipo de dato, van a estar Cuando el sistema operativo debe informar de un
escuchando todos los mensajes que se reciban de la evento, lo que hace es enviar un mensaje para
aplicación cuando suceda un evento. comunicar que ha pasado dicho evento.
Esta función retorna False si el mensaje es WM_QUIT (cerrar el programa) y TRUE cualquier otro
mensaje.
Ciclo que escuche los mensajes
while (GetMEssage(&Mensaje, 0,0,0)){
if(HWND == 0 || !IsDialogMessage(HWND, LPMSG){
TranslateMessage( LPMSG );
DispatchMessage( LPMSG );
}
}
Const MSG *: Puntero o dirección de una estructura MSG que contiene los mensajes.
Ciclo que escuche los mensajes
while (GetMEssage(&Mensaje, 0,0,0)){
TranslateMessage( LPMSG );
DispatchMessage( LPMSG );
}
Const MSG *: Puntero o dirección de una estructura MSG que contiene los mensajes.
return mensaje.wparam;
La función WinMain regresa un int. Cuando el programa se cierra por completo, es porque se hizo el
evento de WM_QUIT (terminar el programa) y regresó 0, entonces, ese 0 es el que regresamos antes
de finalizar la función WinMain, diciendo que el programa se cerró/finalizó.
Procedimiento de
ventana
Windows Procedure
CALLBACK: Es una función que se puede pasar como parámetro en otra función. Cuando esta
función termina de ejecutarse, llama a la función callback.
BOOL CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
switch(msg){
case WM_INITDIALOG:{
}break;
case WM_COMMAND:{
}break;
case WM_DESTROY:{
}break;
}
return false;
}
Mensajes
WM – Windows Message
Los mensajes, una vez traducidos, tienen una nomenclatura base que
es WM_ seguido del nombre del mensaje. Con esto sabemos que es
un mensaje y qué tipo de mensaje es, para dependiendo del mensaje,
saber qué hacer.
WM_CLOSE
> Este mensaje se envía cuando se recibe un comando de cerrar, o sea, el usuario quiere salir de la
aplicación, ya sea por menú o el icono de X en la esquina de la ventana.
> Aquí el cierre se puede cancelar preguntandole al usuario si está seguro de querer salir de la
aplicación o guardar datos antes de enviar el mensaje de cerrar la aplicación o destruir la ventana.
WM_CLOSE
case WM_CLOSE:{
int opc = MessageBox(0,“¿Seguro que desea salir?”,“AVISO”,MB_YESNO|MB_ICONQUESTION);
switch(opc){
case IDYES:
DestroyWindow(hwnd);
break;
}break;
}break;
case WM_DESTROY:{
PostQuitMessage(0);
}break;
WM_CREATE
> Aquí se crean los controles, menús u otro elemento en la ventana manualmente.
case WM_CREATE:{
HMENU hMenu1;
hMenu1 = CreateMenu();
AppendMenu(hMenu1,MF_STRING|MF_POPUP,(UINT)hMenu2,“&Principal”);
SetMenu(hWnd, hMenu1);
}break;
WM_INITDIALOG
> En este mensaje se inicializan ciertos controles como
combobox, listbox.
> Habilitar o deshabilitar controles.
case WM_INITDIALOG:{
for (int a = 0; a < 31; a++){ SendMessage(GetDlgItem(hAGALUMNO,IDC_COMBO2CB_INSERTSTRING,(WPARAM)a,
(LPARAM)combodias[a]);
}
}break;
WM_COMMAND
> Este mensaje es enviado cuando el usuario case WM_COMMAND:{
selecciona una opción de un menú, cuando switch(LOWORD(wParam)){
interactua con un controlador (como al dar clic case ID_CANCEL:
DestroyWindow(hwnd);
en un botón).
break;
}
}break;
WM_COMMAND
> Dentro de este mensaje, hay otro switch donde cada case es el case WM_COMMAND:{
ID correspondiente al control o menú. switch((LOWORD(wParam)){
case ID_CANCEL:
LOWORD: Extrae la palabra de la variable wParam que es un DestroyWindow(hwnd);
número. break;
}break;
}break;
Controles
Controles
BOOL numOK;
int num;
case WM_INITDIALOG:{
SendDlgItemMessage(hWnd,IDC_ENOMBRE,EM_LIMITTEXT,5,0);
}
}break;
case WM_INITDIALOG:{
SetDlgItemText(hWnd,IDC_ENOMBRE,”Nombre”);
}
}break;
Enviar un mensaje
#include <Commctrl.h>
::Obtener la fecha seleccionada::
SYSTEMTIME st;
SendDlgItemMessage(hWnd, IDC_DATETIMEPICKER, DTM_GETSYSTEMTIME, 0, (LPARAM) &st;
* Hay que crear una variable del tipo SYSTEMTIME donde se va a guardar la fecha que el usuario seleccionó.
Este tipo de dato es una estructura que contiene las siguientes variables:
st.wYear
st.wMonth
st.wDay
st.wHour
st.wMinute
st.wSecond
st.wMilliseconds
* Hay que crear una variable del tipo SYSTEMTIME que tendrá la fecha y hora a poner en el date time picker.
* El mensaje DTM_SETSYSTEMTIME, indica que queremos colocar la fecha y hora que tiene st.
case WM_INITDIALOG:{
SendDlgItemMessage(hWnd, IDC_IDC_RO, BM_SETCHECK, (WPARAM)BST_CHECKED,0);
}
}break;
case WM_INITDIALOG:{
SendDlgItemMessage(hWnd, IDC_IDC_RO, BM_SETCHECK, (WPARAM)BST_UNCHECKED,0);
}
}break;
Obtener radio seleccionado
IsDlgButtonChecked(hWnd, IDC_RadioButton);
char meses[12][11] = “Enero”, “Febrero”, “Marzo”, “Abril”, “Mayo”, “Junio”, “Julio”, “Agosto”, “Septiembre”, “Octubre”,
“Noviembre”, “Diciembre”};
case WM_INITDIALOG:{
for( int a = 0; a < 12; a++){
SendMessage(GetDlgItem(hWnd,IDC_COMBO1),CB_INSERTSTRING,(WPARAM)a,(LPARAM)meses[a];
//Otra Manera
SendDlgItemMessage(hWnd,IDC_COMBO1,CB_INSERTSTRING,(WPARAM)a,(LPARAM)meses[a]);
}
}break;
Obtener texto o índice de combobox
//Obtener texto
char mesTexto[13] = {};
//Otra manera
SendDlgItemMessage(hWnd, ID_COMBO1, WM_GETTEXT, 128, (LPARAM)mesTexto);
//Obtener índice
int índice = 0;
indice = SendMessage(GetDlgItem(hwnd, IDC_COMBO1), CB_GETCURSEL, 0, 0);
SendDlgItemMessage(hWnd, ID_COMBO1, WM_GETTEXT, 128, (LPARAM)mesTexto);
Obtner el handle de un control
LoadImage ( HINSTANCE hinst, LPCTSTR lpszName, UINT uType, int cx, int
cy, UINT fuLoad, );
Esta función carga un icono, cursor o un mapa de bits y regresa el handle de la imagen
cargada.
hinst: Instancia que contiene la imagen a cargar. En este caso ponemos NULL.
lpszName: Dirección/path de la imagen a cargar.
uType: Tipo de imagen a cargar. IMAGE_BITMAP
cx/cy: Anchura y altura en pixeles de la imagen a mostrar.
fuLoad: LR_LOADFROMFILE y/o LR_MONOCHROME
Listbox
ListBox
char meses[12][11] = {“Enero”, “Febrero”, “Marzo”, “Abril”, “Mayo”, “Junio”, “Julio”, “Agosto”, “Septiembre”, “Octubre”,
“Noviembre”, “Diciembre”};
case WM_INITDIALOG:{
for( int a = 0; a < 12; a++){
//Manera 1
SendMessage(GetDlgItem(hWnd,IDC_LIST1),LB_INSERTSTRING, a ,(LPARAM)meses[a]);
//Manera 2
SendMessage(GetDlgItem(hWnd,IDC_LIST1),LB_ADDSTRING,0,(LPARAM)meses[a]);
}
}break;
Obtener datos de listbox
char textoList[20];
int índice = 0;
LB_GETTEXT: Con este mensaje, obtenemos el texto que está en el índice indicado en el 4to parámetro
(WPARAM).
LB_GETCURSEL : Con este mensaje, obtenemos el índice del texto seleccionado.
Clic o doble clic en la lista
Para detectar estos movimientos, dentro del case del ID del LISTBOX en el COMMAND, agregamos otro
switch, pero ahora lo que vamos a “valorar” es el HIWORD del wParam.
LBN_DBLCLK LBN_SELCHANGE
case ID_LIST1:{ case ID_LIST1:{
switch(HIWORD(wParam)){ switch(HIWORD(wParam)){
case LBN_DBLCLK:{ case LBN_SELCHANGE:{
}break; }break;
} }
}break; }break;
::Vaciar/resetear listbox por completo::
SendMessage(GetDlgItem(hwnd, IDC_IDC_LIST3), LB_RESETCONTENT, 0, 0);
case WM_COMMAND:{
switch(LOWORD(wParam)){
case ID_BotonAbrir:{
DialogBox(hInstance, MAKEINTRESOURCE(IDD_AGREGAR), 0, vRegistrar);
}break;
}
}break;
DialogBox
DialogBox ( HINSTANCE hInstance, LPCTSTR idVentana, HWND
hWndParent,
Ventana modal DLGPROC dlgProcFunc);
Crea una cuadro de diálogo modal a partir de un recurso de plantilla.
case WM_COMMAND:{
switch(LOWORD(wParam)){
case ID_ALUMNOS_REGISTRAR:{
DialogBox(hInstance, MAKEINTRESOURCE(IDD_AGREGAR), 0, vRegistrar);
}break;
}
}break;
Cerrar ventana
DestroyWindow
DestroyWindow(HWND hWnd);
Destruye/cierra una ventana creada con la funcion CreateDialog.
DestroyWindow(hV1);
Cuando usamos la funcion DestroyWindow, se manda el mensaje de WM_DESTROY, entonces lo que haya en ese mensaje en la
función de la ventana a cerrar, es lo que pasará.
EndDialog
EndDialog ( HWND hWnd, int nReturn);
Destruye/cierra una cuadro de dialogo modal, creado con la funcion DialogBox.
EndDialog(hWnd, 0);
La X de las ventanas
case WM_CLOSE:{
int opc = MessageBox(0, “Seguro que desea salir?”, Cuando el usuario le da clic a la X de la
“AVISO”, MB_YESNO | MB_ICONQUESTION); ventana, se manda el mensaje de
WM_CLOSE.
if(opc == IDYES){
DestroyWindow(hWnd);
PostQuitMessage(0); En la CALLBACK/función de la
} ventana se pone lo que queremos que
suceda cuando el usuario le de clic:
}break; > Cerrar la ventana actual y abrir otra.
> Cerrar por completo el programa/dejar
case WM_CLOSE:{
de ejecutar.
DialogBox(hInstGlobal,
MAKEINTRESOURCE(IDD_LISTAS), NULL,
vListas);
}break;
Quitar la X
Para quitar la X de la ventana que aparece
en la esquina superior derecha hay que ir a
las Propiedades de la ventana y en la
propiedad Menú del Sistema y de valor de
dejamos en False.
Cerrar por completo el
programa
case WM_CLOSE:{
La función para cerrar completamente el
int opc = MessageBox(0, “Seguro que desea salir?”,
programa o dejar de ejecutarlo es la
“AVISO”, MB_YESNO | MB_ICONQUESTION);
función:
if(opc == IDYES){
DestroyWindow(hWnd);
PostQuitMessage(0); PostQuitMessage(0);
}
Esta función manda el mensaje
}break;
WM_QUIT que en el while de los
mensajes, la función GetMessage(); case ID_SALIR:{
obtentrá un 0 o false, y por lo tanto,
dejará de escuchar los mensjes y se sale PostQuitMessage(0);
del programa.
}break;
MessageBox
MessageBox
MessageBox(HWND hWnd, LPCTSTR text, LPCTSTR caption, UINT uType);
Crea, muestra y ejecuta una cuadro de mensaje. Contiene un mensaje definido y un título, combinación
de iconos y botones predefinidos.
#include <CommDlg.h>
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hWnd;
ofn.lpstrFilter = “ALL\0*.*\0Bitmaps\0*.bmp\0”;
ofn.lpstrFile = zFile;
ofn.lpstrFile[0] = ‘\0’;
ofn.nMaxFile = sizeof(zFile);
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
ofn.nFilterIndex = 2;
If(GetOpenFileName(&ofn) == TRUE){
//Si el usuario seleccionó una imagen, qué se debe de hacer?
}else{
//Si el usuario no seleccionó una imagen, qué se debe de hacer?
}
La función GetOpenFileName crea y abre un diálogo que deja al usuario específicar el disco, el directorio
y el nombre de un archivo o conjunto de archivos a abrir.
GetOpenFileName
GetOpenFileName ( OPENFILENAME &ofn);
La función GetOpenFileName crea y abre un diálogo que deja al usuario específicar el disco, el directorio
y el nombre de un archivo o conjunto de archivos a abrir.
ofn: Un puntero a una estructura de tipo OPENFILENAME que contiene la información usada para inicializar el
diálogo.
Valor de retorno
True: Si el usuario seleccionó un archivo y dio clic en el botón OK. La variable lpstrFile de ofn contendrá
la dirección/path completa y el nombre del archivo especificado.
False: Si el usuario cancela o cierra la ventana o un error ocurre.