Capítulo 59 Control IP Address

Dirección IP

Dirección IP

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 193