C/Visual C - Problema con WINAPI y VS2005

 
Vista:

Problema con WINAPI y VS2005

Publicado por rdzulc (5 intervenciones) el 26/04/2007 23:36:53
Hola:
Estoy tratando de aprender un poco de programación en Win32, así que entre a la página conclase.net y empece a hacer uno de los ejemplos que dan ahí.
El problema es que no los peudo compilar, me marca error al mandar el nombre de la clase como una cadena, también trate de compilar el código que ellos tienen así como los de otros tutoriales y siempre me marca los mismo. Estoy usando el Visual C++ 2005. El código es el siguiente:

#include <windows.h>
/* Declaración del procedimiento de ventana */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HWND hwnd; /* Manipulador de ventana */
MSG mensaje; /* Mensajes recibidos por la aplicación */
WNDCLASSEX wincl; /* Estructura de datos para la clase de ventana */
/* Estructura de la ventana */
wincl.hInstance = hThisInstance;
wincl.lpfnWndProc = WindowProcedure; /* Esta función es invocada por Windows */
wincl.style = CS_DBLCLKS; /* Captura los doble-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Usar icono y puntero por defector */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* Sin menú */
wincl.cbClsExtra = 0; /* Sin información adicional para la */
wincl.cbWndExtra = 0; /* clase o la ventana */
/* Usar el color de fondo por defecto para la ventana */
wincl.hbrBackground = GetSysColorBrush(COLOR_BACKGROUND);
wincl.lpszClassName = "NUESTRA_CLASE"; // Aquí marca el error
/* Registrar la clase de ventana, si falla, salir del programa */
if(!RegisterClassEx(&wincl)) return 0;
/* La clase está registrada, crear la ventana */
hwnd = CreateWindowEx(
0, /* Posibilidades de variación */
"NUESTRA_CLASE", /* Nombre de la clase */ // Aqui también me marca error
"Ejemplo 001", /* Texto del título */
WS_OVERLAPPEDWINDOW, /* Tipo por defecto */
CW_USEDEFAULT, /* Windows decide la posición */
CW_USEDEFAULT, /* donde se coloca la ventana */
544, /* Ancho */
375, /* Alto en pixels */
HWND_DESKTOP, /* La ventana es hija del escritorio */
NULL, /* Sin menú */
hThisInstance, /* Manipulador de instancia */
NULL /* No hay datos de creación de ventana */
);
/* Mostrar la ventana */
ShowWindow(hwnd, SW_SHOWDEFAULT);
/* Bucle de mensajes, se ejecuta hasta que haya error o GetMessage devuelva FALSE */
while(TRUE == GetMessage(&mensaje, NULL, 0, 0))
{
/* Traducir mensajes de teclas virtuales a mensajes de caracteres */
TranslateMessage(&mensaje);
/* Enviar mensaje al procedimiento de ventana */
DispatchMessage(&mensaje);
}
/* Salir con valor de retorno */
return mensaje.wParam;
}

/* Esta función es invocada por la función DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT mensaje, WPARAM wParam, LPARAM lParam)
{
switch (mensaje) /* manipulador de mensaje */
{
case WM_DESTROY:
PostQuitMessage (0); /* Envía el mensaje WM_QUIT a la cola de mensajes */
break;
default: /* Mensajes que no queremos manejar */
return DefWindowProc (hwnd, mensaje, wParam, lParam);
}
return 0;
}

Y los errores que manda son los siguientes:
error C2440: '=' : cannot convert from 'const char [14]' to 'LPCWSTR' Línea 31
error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char [14]' to 'LPCWSTR' Línea 50

Les agradesco su ayuda de antemano.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Problema con WINAPI y VS2005

Publicado por fernando.gomez (1603 intervenciones) el 27/04/2007 00:00:45
Pos es que estás empleando char en lugar de wchar_t. Supongo que el tutorial ese no menciona la diferencia, ¿verdad? Bueno, un char ya sabes que es. Soporta todos los caracteres ASCII extendidos incluso. Pero ¿y qué pasa con los caracteres chinos, árabes, hebreos, etc?

Para solucionar esto, se creó un estándar llamado Unicode, que en lugar de un byte por caracter soporta dos bytes. Así, Windows soporta Unicode y para cada función del API de Windows existe su versión ASCII y Unicode. De hecho, CreateWindowEx y la mayoría de las funciones del API son en realidad macros definidas de la siguiente manera:

#ifdef _UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowExA
#endif

Entonces, las versiones ASCII toman como caracteres chars mientras que las Unicode toman wchar_ts. Visual C++ provee un mecanismo prácticamente transparente para solucionar esto. Ya vimos en primera instancia que todas las funciones del API tienen una versión para ASCII y la otra para Unicode, y se define una macro para que dependiendo de si está definido el símbolo _UNICODE o no, se tome una o la otra. Bueno, el mecanismo es más o menos el mismo. Se define el tipo de dato TCHAR:

#ifdef _UNICODE
#define TCHAR wchar_t
#else
#define TCHAR char
#endif

y la mayoría de las funciones estándares de C que trabajan con cadenas, de igual forma:

#ifdef _UNICODE
#define _tcscpy wcscpy
#define _tcscat wcscat
...
#else
#define _tcscpy strcpy
#define _tcscat strcat
...
#endif

También la macro de comillas:

#ifdef _UNICODE
#define _T(cadena) L##cadena
#else
#define _T(cadena) cadena
#endif

Recordemos que una cadena Unicode (para wchar_t), de forma estándar, se emplea el prefijo L:

wchar_t cadena_unicode[20] = L"Hola mundo";

Así, cuando trabajas en Windows es preferible emplear esta aproximación.

Y bueno, ¿por qué no compila tu código? Sencillo. En las versiones anteriores de Visual C++, el valor por defecto era no trabajar con Unicode. En Visual C++ 8, el valor por defecto es activar por default Unicode. Si deseas que tu código trabaje sin emplear las macros _T(...) y eso, simplemente ve a las opciones de proyecto y desactiva la opción de Unicode.

Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Problema con WINAPI y VS2005

Publicado por rdzulc (5 intervenciones) el 27/04/2007 04:37:15
Ya pude resolver mi problema.

Primero, para usar la WinApi en VS 2005 se debe crear un proyecto de tipo Win32 project en lugar de una Win32 console application.

Luego en el nombre de la clase se pone el prefijo 'L' antes de la cadena.
wincl.lpszClassName = L"NUESTRA_CLASE";

hwnd = CreateWindowEx(
0,
L"NUESTRA_CLASE",
L"Ejemplo 001",
etc)

Gracias a Fernando.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar