Como pudiste aprender en el tutorial de arriba son en esencia ventanas con clases predefinidas que nos ayudan a convertirlas en el control que queramos, es muy importante no confundir la "clase de ventana" con las clases de programación orientada a objetos, si tienes dudas en cuanto a esto te recomiendo revisar el tutorial anterior donde se habla de esto en profundidad, a continuación los enlaces:
Un nuevo concepto trabajado en este tutorial, se refiere a que cada control puede tener asociado un estilo especifico, como vimos entonces "estilo" es quizás una palabra algo confusa en este sentido, para que no te confundas simplemente recuerda que "estilo de ventana" no solo se refiere a apariencia si no también a comportamiento, comparto contigo la referencia en la página de la microsoft, para los estilos de cada uno de los controles:
El video que encabeza esta entrada fue un tutorial publicado hace bastante tiempo, lastimosamente en el momento no me di cuenta de que el código no estaba estandarizado, por lo que solo funcionaba bajo el compilador que yo estaba usando, que en este caso era MinGW, algunos usuarios que vieron el tutorial intentaron compilar ese código en visual studio y como era de esperar no les funcionó.
La buena noticia es que los cambios son realmente mínimos y continuación les explico con detalle cada punto, como verán no es para nada largo.
LPCWSTR
Estas son las iniciales en inglés de: Long Pointer to Constant Wide String, que básicamente en español denota una cadena de texto muy larga, MinGW no establece ninguna diferencia entre un array de caracteres y cualquier otro tipo de string, pero el compilador de Visual Studio si lo hace y casi todo el texto que se usa en la aplicación es de este tipo por lo tanto tendremos que crearlo de esta forma:
LPCWSTR mitexto = L"Hola mundo";
o si lo vamos a colocar de forma anónima simplemente: L"Hola mundo"
A continuación voy a listar los sectores en el código que deben ser modificados:
Nombre de la clase de ventana: en codeblocs hacemos algo así: char claseVtn[] = "clase de ventana", pero en VS deberemos crearla variable de esta forma : LPCWSTR claseVtn = L"clase de ventana";
El segundo y tercer parámetro de MessageBox, como bien saben, el primer parámetro indica el texto que va a aparecer en el dialogo, y el segundo, el texto que aparece en la parte de arriba. los podemos pasar directamente de forma anónima, pero debemos hacerlo de la siguiente forma: L"Texto en el message box", la llamada completa debería quedar así : MessageBox(HWND_DESKTOP, L"Texto en el message box", L"Titulo", MB_OK); si aún tienes dudas con esta función te dejo este enlace a la referencia completa en microsoft: MessageBox function
El segundo parámetro en "CreateWindow", o tercero si usamos "CreateWindowEx", este parámetro indica el texto que aparece como título de nuestra ventana, al igual que en el punto anterior lo podemos pasar de forma anónima agregandole una "L" al principio y fuera de las comillas, de la siguiente forma: L"Mi ventana", la llamada a la función debería quedar de la siguiente forma: CreateWindow(claseVtn, L"Mi ventana" .........) con el método tradicional pero si usamos la versión extendida sería así: CreateWindowEx(NULL, claseVtn, L"Mi ventana"........) Para más información te dejo la referencia para ambas funciones: CreateWindow()CreateWindowEx()
stdafx.h
Esta es una cabecera pre-compilada que se agrega por defecto en todos los proyectos de visual studio, hay que colocarla de otro modo nuestro código no va a compilar.
#include "stdafx.h"
Si por alguna razón no queremos usarla, debemos hacer lo siguiente:
Clic con el botón secundario en el nombre del proyecto (no es donde dice "Solution") y hacemos clic en "Propiedades" (Properties si lo tienes en inglés)
Expande la sección que dice C/C++
Busca la sección que dice "Cabeceras precompiladas" ó "Precompiled Headers"
En la ventana principal, la opción "Cabecera precompilada" (Precompiled header si lo tienes en iglés) establece la opción de no usar cabeceras precompiladas
Es de hacer notar que esa opción no afecta en nada el comportamiento de nuestra ventana, por lo que podemos dejar las opciones tal cual están por defecto y simplemente hacer el include.
LNK2019
Una vez intentas realizar la compilación, te aparece el siguiente error:
LNK2019unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)
Mas hacia la derecha te aparece, en la columna "File": MSVCRTD.lib
Este es un error del enlazador, VS diferencia muy bien que archivos enlazar para una aplicación win32, hay dos formas de solucionar este error:
Al momento de crear nuestro proyecto especifica: Win32 Project y no Win32 console Project
Si ya creaste tu proyecto como aplicación de consola, haz lo siguiente: Haz clic secundario en el nombre de tu proyecto, luego en propiedades, expande la sección que dice "Linker" y en la ventana principal, donde dice : "Subsystem" cambia el valor que aparece "Console (/SUBSYSTEM:CONSOLE)" por "Windows (/SUBSYSTEM:WINDOWS)"
winProc must return a value
Esto si se podría decir que es un error mío, ya que de la forma en la cual lo hice no es lo correcto, sin embargo no es algo grave para MinGW y por lo tanto no muestra ningún error. Sin embargo si nos fijamos "winProc" debería retornar un valor, ya que no comienza con "void", la forma de subsanarlo es muy simple, la función "DefWindowProc" la llamamos desde el "return", de la siguiente manera, al final de nuestro "proceso de ventana" :
return DefWindowProc(hwnd, msj, wparam, lparam);
Esto como dije antes, es mas un error mío que una diferencia de compiladores, por lo que deberían hacerlo así siempre, sin importar si usas visual studio o no.
Eso es todo por ahora
Con estas correcciones debería funcionar perfectamente en Visual Studio, si tienen algún otro problema, solo comenten tanto aquí como en el canal de youtube y yo con mucho gusto les aclaro lo antes posible.
Ambas forman parte del grupo de librerías que en Java nos permiten construir nuestra propia interfaz gráfica, pero ¿Acaso una de ellas es mejor que la otra? empecemos diciendo que AWT es realmente el método "viejo", ya que fue la primera librería proporcionada por Java para crear nuestra propia GUI, Swing por otro lado sería el método "nuevo" ya que llegó con la intención de subsanar los inconvenientes que representaba AWT, estos inconvenientes solo se evidenciaban bajo el concepto de multiplataforma de Java, observa la tabla a continuación :
AWT
Swing
Usa componentes del S.O.
Dibuja sus propios componentes
El S.O. maneja los eventos
Java maneja los eventos
La apariencia cambia con el S.O
Tienen la misma apariencia en cualquier S.O.
La apariencia es estática
Se puede personalizar con los Look & Feel
Luego de ver esta tabla y el video que encabeza esta entrada, nos queda claro el principal inconveniente al usar AWT, en cada sistema operativo nuestra interfaz va a tener una apariencia diferente y es posible que incluso parte del comportamiento sea diferente también, ya que los eventos son manejados por el sistema operativo, esto hacía que desarrollar aplicaciones con interfaz gráfica en Java fuera algo tedioso, había que verificar que servía y que no en cada sistema, por lo que el eslogan de java: "Escribe una vez y ejecútalo donde quieras" se veía un poco afectado.
Algo que pareciera obvio mencionar es que cada vez que colocamos imágenes en nuestra web esta va a tardar mas en descargar, esto no solo se debe al peso agregado de estos archivos de imagen, si no también al aumento en el número de peticiones hacia el servidor web, por supuesto que no tiene sentido simplemente dejar de utilizar imágenes, estas no son imprescindibles para el funcionamiento de nuestra página, pero sin ellas perdería atractivo y con ello dejaría de atraer visitantes. Peticiones adicionales al servidor se crean cuando, por ejemplo, hacemos un efecto de "hover" con imágenes, ya que javascript solicitaría una nueva imagen al servidor.
Nos podemos ahorrar muchas peticiones al servidor usando una técnica muy sencilla, que es mas que todo útil a la hora de trabajar con iconos en nuestra web, simplemente posicionemos todos nuestros iconos en una sola imagen grande y con CSS la movemos para mostrar solamente el icono que queremos usar, esta imagen grande la podemos denominar "Sprite" y a continuación te muestro dos de los ejemplos usados en el videotutorial de arriba:
En el tutorial de arriba aprenderás no solo implementar los Sprites en Css, sino como también a hacer tu propio sprites desde Photoshop
En este tutorial principalmente se enseña a hacer una ventana básica, esto a modo de introducción a la creación de interfaces gráficas. Existen 3 modos de crear ventanas en Java, en el video se tratarán los 3, la primera con swing, luego con awt y por último usando el diseñador de Netbeans, en este caso estamos usando igualmente swing pero con la ayuda del diseñador es mucho más simple.
Elementos Swing
Aquí solo compartiré una referencia para que observen los diferentes elementos Swing que se pueden colocar en una ventana, la página está en inglés pero es una guía visual así que no es necesario leer mucho, en el tutorial dedicado al tema de los componentes profundizaremos mas al respecto
Las layouts son simplemente una forma de decirle a Java como organizar los elementos que vamos colocando en cada ventana, cada layout de dice el tamaño y la ubicación que debe tener cada elemento, a continuación las layouts mas comunes:
BoderLayout: Permite organizar los elementos usando puntos cardinales, norte, sur, este y oeste
BoxLayout: Crea columnas o filas de elementos
FlowLayout: Organiza los elementos en lineas, con tamaño justo para su contenido
GridLayout: Podemos crear una matriz para colocar los elementos en ella, el tamaño será lo que ocupe cada celda
GridBagLayout: Es uno de los mas sofisticados, al igual que el de arriba nos permite crear una matriz, pero aquí podemos especificar que un elemento ocupe dos celdas, o que su tamaño no cubra la celda entera
Aquí se intentó explicar las layouts de forma muy resumida, en futuras clases se hablará mas profundamente acerca de este tema, faltaron algunos layouts por mencionar, puedes ver una referencia completa en este enlace (está en inglés):