59 Control IP Address
El control IP Address permite capturar o modificar direcciones IP4 y máscaras subred. Hasta la fecha no exite un control para editar direcciones IP6.
El control nos permiteestablecer márgenes para cada campo de la IP.
Insertar durante la ejecución
Como todos los controles, los controles IP también se pueden insertar en una ventana o diálogo durante la ejecución. Igual que con el resto de controles, tan sólo tendremos que usar las funciones CreateWindow o CreateWindowEx indicaando en la clase de ventana el valor HOTKEY_CLASS:
hFont = CreateFont(-14, 0, 0, 0, 0, FALSE, FALSE, FALSE, 1, 0, 0, 0, 0, ("Ms Shell Dlg")); CreateWindowEx(0, WC_IPADDRESS, NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP, 80,10,160,20, hwnd, (HMENU)ID_IPADDRESS, hInstance, NULL); SendDlgItemMessage(hwnd, ID_IPADDRESS, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(FALSE, 0));
Estos controles no tienen estilos específicos, tan sólo podremos usar los estilos más genéricos.
En el parámetro hMenu, como siempre, indicaremos el identificador del control.
Si queremos modificar la fuente usaremos el mensaje WM_SETFONT, y hay que recordar liberar el recurso antes de terminar el programa, usando DeleteObject.
Insertar desde fichero de recursos
Se usa un control general CONTROL, con la clase WC_IPADDRESS, y los estilos generales que queramos aplicar.
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG1 DIALOG 0, 0, 186, 47 STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU CAPTION "Dialog" FONT 8, "Ms Shell Dlg" { LTEXT "Dirección IP:", IDC_STATIC, 15, 6, 42, 9, SS_LEFT, WS_EX_LEFT CONTROL "", ID_IPADDRESS, WC_IPADDRESS, WS_TABSTOP, 15, 20, 100, 15, WS_EX_LEFT DEFPUSHBUTTON "OK", IDOK, 129, 7, 50, 14, 0, WS_EX_LEFT PUSHBUTTON "Cancel", IDCANCEL, 129, 24, 50, 14, 0, WS_EX_LEFT }
Asignar valor al control
Para asignar un valor a un control IP Address usaremos el mensaje IPM_SETADDRESS.
En lParam indicaremos la dirección IP en formato empaquetado. Para calcular el valor de la IP en formato empaquetado se puede usar la macro MAKEIPADDRESS.
SendDlgItemMessage(hwnd, ID_IPADDRESS, IPM_SETADDRESS, 0, (LPARAM)MAKEIPADDRESS(127,0,0,1));
Vaciar el contenido del control
Para vaciar los valores de los campos de la dirección IP en un control podemos usar el IPM_CLEARADDRESS
SendDlgItemMessage(hwnd, ID_IPADDRESS, IPM_CLEARADDRESS, 0, 0);
El mensaje IPM_ISBLANK devuelve un valor distinto de cero (TRUE), si el control tiene los cuatro campos en blanco.
Recuperar valor IP del control
Para recuperar el valor actual de un control IP usaremos el mensaje IPM_GETADDRESS, indicando en LPARAM un puntero a un valor DWORD que recibirá el valor de la IP almacenada en el control, en formato empaquetado.
El valor de retorno indicará cuántos de los campos están vacíos.
Si queremos recuperar el valor de los campos a partir de una dirección IP empaquetada disponemos de las macros FIRST_IPADDRESS, SECOND_IPADDRESS, THIRD_IPADDRESS y FOURTH_IPADDRESS, que recuperan los campos primero, segundo, tercero y cuarto, respectivamente.
vacios = SendDlgItemMessage(hwnd, ID_IPADDRESS, IPM_GETADDRESS, 0, (LPARAM)&ip); campo1 = FIRST_IPADDRESS(ip); campo2 = SECOND_IPADDRESS(ip); campo3 = THIRD_IPADDRESS(ip); campo4 = FOURTH_IPADDRESS(ip);
Asignar el foco a un campo
Cuando se introducen valores en un control IP, se pueden teclear números entre 0 y 255 en cada campo. Si se introducen tres dígitos se avanzará automáticamente al siguiente campo, pero si sólo se introducen uno o dos dígitos, para avanzar al siguiente campo se puede usar el punto.
Alternativamente podemos situar el foco del teclado en cualquiera de los cuatro campos mediante un mensaje IPM_SETFOCUS, indicando en wParam el índice del campo que recibirá el foco, entre 0 y 3. Si se usa un valor diferente, se asignará el foco al primer campo vacío, y si ninguno está en blanco, al primer campo.
SendDlgItemMessage(hwnd, ID_IPADDRESS, IPM_SETFOCUS, 2, 0);
Notificaciones
Los controles de IP address envían un código de notificación IPN_FIELDCHANGED cada vez que el usuario modifica un campo o cuando se desplaza de un campo a otro.
En lParam se envía un puntero a una estructura NMIPADDRESS que a su vez contiene una estructura NMHDR con información sobre la notificación, y dos campos iField que identifica el campo, y iValue que contiene el valor del campo.
Podemos usar estas notificaciones para procesar los valores introducidos por el usuario de modo que se ajusten a las especificaciones de nuestra aplicación.
Rangos
Para cada campo se puede establecer un rango de valores válidos mediante un mensaje IPM_SETRANGE, indicando en wParam el índice del campo, entre 0 y 3, y en lParam el rango. Este rango es un valor WORD en el que el byte de menor peso indica el límite inferior y el byte de mayor peso el límite superior. Se puede usar la macro MAKEIPRANGE para construir el valor de un rango.
SendDlgItemMessage(hwnd, ID_IPADDRESS, IPM_SETRANGE, 0, MAKEIPRANGE(20,40));
En este ejemplo se establece un rango para el primer campo entre 20 y 40, ambos valores incluídos. Si el usuario introduce un valor menor de 20, se modificará el valor a 20, y si introduce un valor mayor de 40, se modificará el valor a 40.
Pero además, podemos procesar en código de notificación IPN_FIELDCHANGED para hacer un procesamiento más complejo que un simple rango.
NMHDR *lpNmhdr; NMIPADDRESS *lpnmIpaddress; ... case WM_NOTIFY: lpNmhdr = (NMHDR*)lParam; switch(lpNmhdr->code) { case IPN_FIELDCHANGED: lpnmIpaddress = (NMIPADDRESS*)lParam; if(lpnmIpaddress->iField == 1) { if(lpnmIpaddress->iValue < 20) lpnmIpaddress->iValue = 22; if(lpnmIpaddress->iValue > 40) lpnmIpaddress->iValue = 38; } if(lpnmIpaddress->iField == 2) { if(lpnmIpaddress->iValue != 15 && lpnmIpaddress->iValue != 25) lpnmIpaddress->iValue = 15; } break; } break;
Ejemplo 101
Nombre | Fichero | Fecha | Tamaño | Contador | Descarga |
---|---|---|---|---|---|
Ejemplo 101 | win101.zip | 2021-11-27 | 8032 bytes | 539 |