Versión 3.0

800x600 mínimo
En esta lección:

La clase button
-----
Mensajes de controles estándar
-----
Botones de radio, casillas de verificación y cuadros de grupo
-----
Descargas
-----


Otras secciones:

Conceptos básicos
-----
Programando en C
-----
Programando en C++
-----
Programando Windows 9x.
-----
Teoría electrónica
-----
Circuitos electrónicos
-----
Actividades adicionales
-----
Hipervínculos
-----


Contácteme:

Dudas y comentarios
-----


Controles estándar

     Cuando un programa ejecutándose desde la línea de comandos necesita datos de entrada por parte del usuario es común que dicha petición se haga a través de una pregunta directa o bien utilizando un menú, generalmente en formato de texto plano, pero un programa para Windows es diferente pues éste sistema operativo permite que varios programas se ejecuten simultáneamente y por lo tanto no es posible que un solo programa acapare los recursos en espera de una respuesta del usuario. Cuando un programa Windows requiere datos de entrada o bién desplegar datos de salida, utiliza en términos generales los llamados controles estándar de Windows, éstos consisten en ventanas hijas, llamadas así porque se trata de ventanas que se ejecutan dentro de otra ventana, ésta a su vez llamada entonces ventana padre. La ventana hija procesa los mensajes de ratón y teclado notificando a su ventana padre de los cambios ocurridos, de ésta manera una ventana hija actúa como un dispositivo de entrada para la ventana padre. La ventana hija representa una característica específica independientemente de su apariencia gráfica en pantalla, su respuesta a la entrada del usuario y su método de notificar a otra ventana cuándo se produce un suceso importante.

     Si bién es posible crear nuestros propios controles de ventana hija, pero lo más común es utilizar las clases de ventana y sus respectivos procedimientos de ventana definidas en Windows para crear ese conjunto de controles que seguramente Usted ya habrá utilizado con anterioridad, éstos controles son los familiares botones, casillas de verificación, cuadros de edición, cuadros de lista, listas desplegables, texto estático y barras de desplazamiento. Cada uno de éstos controles se crean, como toda ventana en Windows, a partir de una llamada clase de ventana, éstas clases son parte del sistema operativo y por lo tanto no es necesario programar nada para utilizarlas excepto una llamada a la función CreateWindow() con los parámetros adecuados y unas cuantas acciones adicionales relativas a la captura de los respectivos mensajes que las ventanas hijas envían a la ventana padre.

     En éste artículo analizaremos las diferentes clases utilizadas para crear los controles comunes de Windows, además del método tradicional de programar utilizando C tal y como lo hemos hecho en los anteriores capítulos de éste tutorial de programación en Windows, Usted encontrará vínculos adicionales que le mostrarán la manera de programar los mismos controles utilizando Visual C++ version 6.0 y las Microsoft Foundation Classes (MFC).

La clase button 

     La clase button especifica una ventana hija rectangular que representa un botón donde el usuario hace clic para cambiar el estado, generalmente entre encendido y apagado. Los controles de la clase button se pueden utilizar solos ó en grupos y pueden llevar etiquetas o bien no llevar texto alguno. Para crear una ventana hija basada en la clase estándar llamada button se utiliza la función CreateWindow() especificando en el primer parámetro la cadena de texto "button", ésto le indica a Windows que se utilizará la clase predefinida llamada button. El programa control.c demuestra cómo crear dicho control en el área cliente de una ventana convencional. Recuerde que el código fuente de todos los programas mencionados en éste capítulo lo puede descargar en el hipervínculo al final de éste artículo, aquí presento el procedimiento de ventana correspondiente:


LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    HWND hwndboton1, hwndboton2;

    switch (iMsg)
    {
        case WM_CREATE:
        hwndboton1 = CreateWindow("button", "Mensaje",
          WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
          10, 10, 250, 40,
          hwnd, (HMENU) 1, hInst, NULL);
        hwndboton2 = CreateWindow("button", "Cerrar el programa",
          WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
          10, 70, 250, 40,
          hwnd, (HMENU) 2, hInst, NULL);
        return 0;

        case WM_COMMAND:
        switch(LOWORD(wParam))
        {
            case 1:  // botón 1
            MessageBox(hwnd, "Texto en el cuadro de mensaje",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OKCANCEL);
            break;

            case 2:  // botón 2
            SendMessage(hwnd, WM_CLOSE, 0, 0);
            break;

            default:
            break;
        }
        return 0;

        case WM_DESTROY:
        PostQuitMessage (0);
        return 0;
    }

    return DefWindowProc (hwnd, iMsg, wParam, lParam);
}

     Se aprecia que en el procedimiento de ventana y como respuesta al mensaje WM_CREATE se llama a la función CreateWindow() un par de veces, en la primera se construye una ventana hija (WS_CHILD) tomando las características predefinidas en la clase button, de 240 pixeles de ancho por 30 pixeles de alto, inicialmente visible (WS_VISIBLE), de estilo BS_PUSHBUTTON y con el texto Mensaje en la superficie del mismo. El identificador de nuestro botón es (HMENU) 1. En la segunda llamada a la función CreateWindow() se crea un botón similar que difiere solamnete en la posición, el texto en la superficie del botón y el identificador, que en éste caso es (HMENU) 2.

     En la función CreateWindow() se especificó el estilo de botón BS_PUSHBUTTON (BS significa Button Style). Usted puede especificar en la llamada a la función CreateWindow() cualquiera de los siguientes estilos para la clase button:

  • BS_PUSHBUTTON: Crea un botón rectangular.

  • BS_DEFPUSHBUTTON: Similar al anterior pero con un borde negro mas grueso. El usuario puede seleccionar éste botón al presionar la tecla enter.

  • BS_RADIOBUTTON: Crea un pequeño círculo con texto a la derecha del mismo, a menos que éste estilo se combine con el estilo BS_LEFTTEXT en cuyo caso el texto aparece a la izquierda del círculo. Los botones de radio se utilizan en grupos de al menos tres para especificar opciones que son mutuamente excluyentes.

  • BS_AUTORADIOBUTTON: Similar al anterior pero es Windows el encargado de marcar el botón seleccionado.

  • BS_CHECKBOX: Crea un pequeño cuadro vacío con texto a la derecha. Si se requiere texto a la izquierda entonces éste estilo se combina con el estilo BS_LEFTTEXT. Los controles checkbox se utilizan para seleccionar una o más opciones.

  • BS_AUTOCHECKBOX: Similar al anterior pero es Windows el encargado de la lógica de marcar ó desmarcar el cuadro.

  • BS_3STATE: Similar al botón checkbox pero con tres estados: sin marca, marca gris y marca negra. La marca gris generalmente indica un estado no definido.

  • BS_AUTO3STATE: Ídem al anterior pero Windows hace la lógica de marcado.

  • BS_GROUPBOX: Crea un rectángulo que se utiliza para agrupar a otros controles.

  • BS_OWNERDRAW: Crea un control con características definidas por el programador.

     Su primera tarea consiste en cambiar en la primera función CreateWindow() el estilo BS_PUSHBUTTON por cada uno de los estilos enlistados arriba y volver a compilar y ejecutar el programa control.c para que observe los resultados obtenidos. Particularmente con los estilos BS_RADIOBUTTON, BS_AUTORADIOBUTTON, BS_CHECKBOX, BS_AUTOCHECKBOX, BS_3STATE y BS_AUTO3STATE es evidente que los controles comunes fueron creados para utilizarse dentro de cuadros de diálogo, mas adelante resolveremos éste problema, mientras veamos cómo se comunican entre sí las ventanas hija con su ventana padre.

Volver al principio

Hola mundo

Mensajes de controles estándar 

     Cuando se hace clic con el ratón en uno de los controles estándar éstos envían un mensaje WM_COMMAND a su ventana padre, el procedimiento de ventana captura el mensaje en el cual el valor bajo (LOWORD) de la variable wParam representa el identificador del control, que en el programa control.c puede ser (HMENU) 1 ó (HMENU) 2. El valor alto (HIWORD) de la variable wParam representa el código de notificación que es un submensaje que utiliza el control para indicar a la ventana padre con más detalle lo que significa el mensaje. Los códigos de notificación son los siguientes:

  • BN_CLICKED: valor = 0
  • BN_PAINT: valor = 1
  • BN_HILITE: valor = 2
  • BN_UNHILITE: valor = 3
  • BN_DISABLE: valor = 4
  • BN_DOUBLECLICKED: valor = 5

     Los códigos de notificación de valor igual a 1 y hasta 5 son para un estilo de botón obsoleto llamado BS_USERBUTTON, por lo tanto solo requerimos el valor bajo de la variable wParam para saber qué control se está comunicando con la ventana padre, ésto se vé en el procedimiento de ventana del programa control.c en donde se utiliza un instrucción switch tomando el valor LOWORD(wParam) para capturar los mensajes WM_COMMAND provenientes de los controles, en la opción case: 1 utilizo la función MessageBox(), como consecuencia, al hacer clic con el ratón en el botón 1, el programa responde desplegando un cuadro de diálogo de mensaje. Similarmente, al hacer clic con el ratón en el botón 2 se genera un mensaje WM_CLOSE que el procedimiento de ventana por defecto captura y procesa obligando a terminar el programa.

     En este momento ya disponemos de la información necesaria que nos permite colocar un botón rectangular en el área cliente de la ventana de nuestro programa, una vez que el procedimiento de ventana captura el mensaje WM_COMMAND y se descrimina el control que generó dicho mensaje a través de una instrucción switch-case, podemos hacer prácticamente cualquier cosa que el programa requiera, en realidad es fácil poner a trabajar éste recurso de Windows en favor de nuestro programa. Analizando más de cerca la situación llegamos a la conclusión que en determinadas circunstancias es más laborioso establecer la ubicación física del control dentro del área cliente que la labor desempeñada por el mismo. La casa Microsoft está consciente de ello y ha facilitado enormemente ésta tarea en su conocido compilador de C/C++ llamado Visual C++, si Usted dispone de éste compilador puede seguir la ruta de Visual C++ 6.0 para el programa control.c, compare resultados y decida cuál herramienta se adapta mejor a sus necesidades.

La ruta de Visual C++ 6.0

Comparación de un programa en C (arriba) y otro en MFC (abajo)

     En la imagen de la derecha podemos apreciar los resultados obtenidos hasta el momento, arriba está el programa resultado de compilar control.c. Abajo tenemos el mismo programa, funcionalmente hablando, resultado de utilizar MFC en Visual C++ 6.0. La primera diferencia obvia es el color del área cliente de la ventana, ésto demuestra un hecho simple, los controles estándar de Windows fueron diseñados para utilizarse principalmente en cuadros de diálogo, esto, por supuesto, no significa que no podamos utilizar los controles de la manera en que lo hace control.c, debemos empero, utilizar los llamados colores de sistema. Windows reserva para sí 25 colores para dibujar varias partes de la pantalla de tal manera que en lugar de utiliar una brocha blanca para pintar el fondo del área cliente, podemos utilizar COLOR_BTNFACE que como su nombre sugiere, es el color de sistema que Windows utiliza para pìntar la superficie de los botones, así, para que control.c tenga la misma apariencia en el área cliente especificamos en la clase de ventana: wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1); en lugar de la clásica brocha blanca wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); Lo invito para que Usted haga éste cambio en control.c, vuelva a compilar y compare los resultados con el programa elaborado en Visual C++ 6.0

     Otras diferencias son menos obvias, está claro que control.c ofrece un mejor control sobre todos los aspectos del programa, Visual C++ y MFC nos ofrecen una programación enormemente simplificada, ideal para aquellos que no desean detenerse en espectos ya resueltos por los programadores de Microsoft. El conocimiento de los aspectos relacionados con la programación de la API de Windows utilizando C, como seguramente habrá observado, es una herramienta valiosa para comprender cómo funciona MFC, sigamos entonces estudiando a los otros miembros de la clase button.

Volver al principio

Hola mundo

Casillas de verificación, Botones de radio y Cuadros de grupo.

     Dada su apariencia, es difícil pensar en un cuadro de grupo como un elemento de la clase button, sin embargo así es, consiste en un rectángulo cuyo fin es agrupar a otros controles cuya funcionalidad está relacionada entre sí, el texto asociado con éste estilo de ventana se despliega en la esquina superior izquierda. Los otros dos elementos de la clase button discutidos en ésta sección guardan ciertas similitudes pero como veremos en el siguiente ejemplo cada uno desempeña una función propia muy interesante. El botón de radio consiste en un pequeño círculo con texto a su derecha, a menos que sea especificado el estilo BS_LEFTTEXT en cuyo caso el texto aparece a la izquierda del círculo. Se utiliza en grupos de tres o más botones de radio y su funcionalidad característica es la selección mutuamente excluyente de las opciones representadas por los diferentes botones del grupo, éste comportamiento es similar al operador booleano OR. Por otra parte, la casilla de verificación consiste en un pequeño rectángulo con texto a su derecha, a menos que se especifique la opción BS_LEFTTEXT, al contrario del botón de radio, la casilla de verificación se utiliza para seleccionar dos o más opciones que pueden ser incluidas mutuamente, es decir, su comportamiento es similar al operador booleano AND. Generalmente se utiliza un cuadro de texto para agrupar a las diferentes opciones representadas tanto por los botones de radio como por las casillas de verificación.

     En nuestro siguiente programa, control2.c, demuestro el uso de éstos tres estilos de ventana miembros de la clase button, el procedimiento de ventana es el siguiente:


LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    static HWND hwndgrupo1, hwndgrupo2, hwndcasilla1, hwndcasilla2,
      hwndcasilla3, hwndradio1, hwndradio2, hwndradio3, hwndboton1;
    static int casilla1, casilla2, casilla3, radio1, radio2, radio3;

    switch (iMsg)
    {
        case WM_CREATE:
        hwndgrupo1 = CreateWindow("button", "Alimento",
          WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
          10, 10, 160, 110,
          hwnd, (HMENU) 0, hInst, NULL);
        hwndgrupo2 = CreateWindow("button", "Hora",
          WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
          180, 10, 160, 110,
          hwnd, (HMENU) 0, hInst, NULL);
        hwndcasilla1 = CreateWindow("button", "Pollo frito",
          WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
          20, 40, 140, 20,
          hwnd, (HMENU) 1, hInst, NULL);
        hwndcasilla2 = CreateWindow("button", "Pescado fresco",
          WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
          20, 60, 140, 20,
          hwnd, (HMENU) 2, hInst, NULL);
        hwndcasilla3 = CreateWindow("button", "Croquetas",
          WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX,
          20, 80, 140, 20,
          hwnd, (HMENU) 3, hInst, NULL);
        hwndradio1 = CreateWindow("button", "Mañana",
          WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON|WS_GROUP,
          190, 40, 140, 20,
          hwnd, (HMENU) 4, hInst, NULL);
        hwndradio2 = CreateWindow("button", "Tarde",
          WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
          190, 60, 140, 20,
          hwnd, (HMENU) 5, hInst, NULL);
        hwndradio3 = CreateWindow("button", "Noche",
          WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON,
          190, 80, 140, 20,
          hwnd, (HMENU) 6, hInst, NULL);
        hwndboton1 = CreateWindow("button", "Presione Aquí",
          WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
          100, 130, 160, 30,
          hwnd, (HMENU) 7, hInst, NULL);

        SendMessage(hwndradio1, BM_SETCHECK, 1, 0);
        return 0;

        case WM_COMMAND:
        switch(LOWORD(wParam))
        {
            case 1:
            if(casilla1 == 0)
            casilla1 = 1;
            else
            casilla1 = 0;
            break;

            case 2:
            if(casilla2 == 0)
            casilla2 = 1;
            else
            casilla2 = 0;
            break;

            case 3:
            if(casilla3 == 0)
            casilla3 = 1;
            else
            casilla3 = 0;
            break;

            case 7:  // botón "Presione aquí"
            if(SendMessage(hwndradio1, BM_GETCHECK, 0, 0))
            radio1 = 1;
            else
            radio1 = 0;
            if(SendMessage(hwndradio2, BM_GETCHECK, 0, 0))
            radio2 = 1;
            else
            radio2 = 0;
            if(SendMessage(hwndradio3, BM_GETCHECK, 0, 0))
            radio3 = 1;
            else
            radio3 = 0;

            if(casilla1 && casilla2 && casilla3 && radio1 == TRUE)
            MessageBox(hwnd, "Pollo, pescado y croquetas por la mañana",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla1 && casilla2 && casilla3 && radio2 == TRUE)
            MessageBox(hwnd, "Pollo, pescado y croquetas por la tarde",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla1 && casilla2 && casilla3 && radio3 == TRUE)
            MessageBox(hwnd, "Pollo, pescado y croquetas por la noche",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla1 && casilla2 && radio1 == TRUE)
            MessageBox(hwnd, "Pollo y pescado por la mañana",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla1 && casilla3 && radio1 == TRUE)
            MessageBox(hwnd, "Pollo y croquetas por la mañana",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla2 && casilla3 && radio1 == TRUE)
            MessageBox(hwnd, "Pescado y croquetas por la mañana",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla1 && casilla2 && radio2 == TRUE)
            MessageBox(hwnd, "Pollo y pescado por la tarde",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla1 && casilla3 && radio2 == TRUE)
            MessageBox(hwnd, "Pollo y croquetas por la tarde",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla2 && casilla3 && radio2 == TRUE)
            MessageBox(hwnd, "Pescado y croquetas por la tarde",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla1 && casilla2 && radio3 == TRUE)
            MessageBox(hwnd, "Pollo y pescado por la noche",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla1 && casilla3 && radio3 == TRUE)
            MessageBox(hwnd, "Pollo y croquetas por la noche",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla2 && casilla3 && radio3 == TRUE)
            MessageBox(hwnd, "Pescado y croquetas por la noche",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla1 && radio1 == TRUE)
            MessageBox(hwnd, "Pollo por la mañana",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla1 && radio2 == TRUE)
            MessageBox(hwnd, "Pollo por la tarde",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla1 && radio3 == TRUE)
            MessageBox(hwnd, "Pollo por la noche",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla2 && radio1 == TRUE)
            MessageBox(hwnd, "Pescado por la mañana",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla2 && radio2 == TRUE)
            MessageBox(hwnd, "Pescado por la tarde",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla2 && radio3 == TRUE)
            MessageBox(hwnd, "Pescado por la noche",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla3 && radio1 == TRUE)
            MessageBox(hwnd, "Croquetas por la mañana",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla3 && radio2 == TRUE)
            MessageBox(hwnd, "Croquetas por la tarde",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            if(casilla3 && radio3 == TRUE)
            MessageBox(hwnd, "Croquetas por la noche",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            else
            MessageBox(hwnd, "Seleccione un alimento",
              "Título en el cuadro de mensaje",
              MB_ICONINFORMATION|MB_OK);
            break;

            default:
            break;
        }
        return 0;

        case WM_DESTROY:
        PostQuitMessage (0);
        return 0;
    }
    return DefWindowProc (hwnd, iMsg, wParam, lParam);
}

     El programa es muy sencillo, dependiendo de la selección que se haga se muestra un mensaje que refleja la decisión tomada. Como respuesta al mensaje WM_CREATE se llama nueve veces a la función CreateWindow() especificando, según sea el caso, los parámetros necesarios para crear dos cuadro de grupo, tres casillas de verificación, tres botones de radio y un botón convencional que nos servirá para desplegar un mensaje al usuario. Observe que en cada llamada a función se ha asignado un identificador para ventana hija numerado consecutivamente (parámetro 9 de la función CreateWindow()). Además, como respuesta al mensaje WM_CREATE se utiliza la función SendMessage() para enviar un mensaje BM_SETCHECK al botón de radio 1 especificando en el tercer parámetro el valor de 1, de ésta manera, al iniciar la aplicación, el botón de radio 1 aparecerá con una marca establecida. Observe que el primero de los botones de radio se creó además especificando el estilo WS_GROUP.

     La lógica para conocer cuál ó cuales opciones han sido seleccionadas es muy simple, consiste en una serie de instrucciones if-else tomando como valor de verdad el resultado de aplicar el operador lógico AND a la(s) variable(es) asociadas a los respectivos controles, es común ésta práctica al trabajar con éstos controles. Para saber si una casilla de verificación ó un botón de radio está marcado se envía al control un mensaje BM_GETCHECK, si el valor devuelto es diferente de cero (TRUE) entonces el control está marcado, éste método lo utilizo para verificar el estado de los botones de radio. Otro método es utilizar el identificador de ventana hija presente en la palabra baja (LOWORD) de la variable wParam, tal y como se hace para las casillas de verificación, opciones case 1 a la case 3 de la instrucción switch que se encuentra en respuesta al mensaje WM_COMMAND. Independientemente del método utilizado, el objetivo es capturar en una variable el estado, generalmente booleano, de los controles, es decir, están o no marcados.

     Compìle y ejecute el programa control2.c y aprenda cómo utilizar éstos importantes controles. Y para aquellas personas que cuentan con Visual C++ 6.0 pueden seguir La ruta de Visual C++ 6.0 para el programa control2.c y aprender cómo se hace el mismo programa, funcionalmente hablando, pero utilizando MFC.

La ruta de Visual C++ 6.0

Volver al principio

Hola mundo

Descargas 

     Aquí puede Usted descargar el código fuente de los programas discutidos en éste artículo, incluyendo los programas para Visual C++ 6.0, seleccione una opción:

  • Código fuente para los programas control.c y control2.c solamente, haga clic aquí

  • Código fuente para los programas de La ruta de Visual C++ 6.0, haga clic aquí.

  • Código fuente para todos los programas de éste artículo, haga clic aquí.

Volver al principio

Hola mundo

© 1999 Virgilio Gómez Negrete, Derechos Reservados