visual studio microsoft español descargar community c menu winapi windows-messages

microsoft - visual studio community



¿Qué pasa con mi conjunto de caracteres(Win32 API) (2)

Con toda la extrañeza de los pequeños cuadrados, tu código está equivocado. No es compatible con Unicode. Debería prefijar todas las cadenas con L (como en L "cadena") y cambiar las configuraciones de compilación a Unicode (esto hace que las funciones de Windows acepten la codificación UTF-16). Esta es la codificación nativa de Windows, que es como el texto debe ser hecho en Windows.

Un enfoque alternativo sería usar API amplias y convertir a UTF-16 al llamar a las API. Se describe en http://utf8everywhere.org .

Actualmente estoy aprendiendo Win32 usando este tutorial , y tengo dificultades con mis personajes mostrados.

Tomemos por ejemplo esta pieza de código que agrega un menú a mi ventana después de la creación:

case WM_CREATE: { HMENU hMenu, hSubMenu; HICON hIcon, hIconSm; hMenu = CreateMenu(); hSubMenu = CreatePopupMenu(); AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "Exit"); AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "File"); hSubMenu = CreatePopupMenu(); AppendMenu(hSubMenu, MF_STRING, ID_STUFF_GO, "&GO"); AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Stuff"); SetMenu(hwnd, hMenu); hIcon = LoadImage(NULL, "Stuff.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE); if (hIcon) SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); else MessageBox(hwnd, "Could not load large icon!", "Load Error", MB_OK | MB_ICONERROR); hIconSm = LoadImage(NULL, "Stuff.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE); if(hIconSm) SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm); else MessageBox(hwnd, "Could not load small icon!", "Load Error", MB_OK | MB_ICONERROR); } break;

Eso está dentro de un bloque de switch dentro de mi función WndProc que maneja los mensajes de Windows recibidos desde el bucle de mensajes.

Cada cadena que se va a mostrar:

"Exit" "File" "&GO" "&Stuff"

Es ilegible en tiempo de ejecución ya que se muestran como pequeños cuadrados, al igual que la página de códigos no era la correcta o algo así. Cuando ejecuto el tutorial, todas las cadenas se muestran correctamente. Tiendo a apegarme exactamente a lo que dice el tutorial para ayudarme a hacer las cosas bien, y su pedagogía es buena. ¡De todas formas!...

Estoy usando:

  1. Sistema de equipo de Microsoft Visual Studio 2008;
  2. Microsoft Windows Server 2003 usando RDP;
  3. El sistema operativo local es Windows Vista Ultimate.

Alguien tiene una pista al respecto?


Tiene un problema con Unicode frente a la codificación de caracteres ANSI de Windows. Históricamente, Windows utilizó un ASCII extendido que denominaron erróneamente ANSI. Esto trajo consigo la necesidad de páginas de códigos porque incluso un personaje de 8 bits no proporciona suficientes puntos de código para representar todos los sistemas de escritura europeos, y mucho menos el resto del mundo. Cuando se desarrolló Win32, se decidieron por Unicode como el juego de caracteres preferido. (En realidad, se decidieron por la codificación UTF-16LE del conjunto de caracteres Unicode, pero ese detalle no es del todo relevante en este momento). Sin embargo, había demasiado código existente para considerar que requería que la migración de Win16 a Win32 también necesitaría cambiar la codificación de caracteres de todas las cadenas.

Su solución fue inteligente (algunos han argumentado que era demasiado inteligente). Cada punto de entrada de Win32 API que toma una cadena viene en dos formas. El primer sabor toma cadenas ANSI y maneja la conversión a UTF-16LE internamente. El segundo sabor (y ahora preferido) toma las cadenas UTF-16LE directamente. También conspiraron con el equipo de Visual C para definir wchar_t como un tipo de 16 bits, y para asegurar que L"" literales de cadena usan la asignación de texto ASCII a UTF-16LE.

Para facilitar la migración desde el código Win16 existente, la función MessageBox y cualquier otra API Win32 que tome cadenas se asignan en tiempo de compilación por una macro a MessageBoxA o MessageBoxW dependiendo de si el símbolo del preprocesador UNICODE está definido o no.

Este mapeo no puede corregir los literales de cadena, por lo que también introdujeron una macro para designar literales de cadena que sean angostos o anchos dependiendo de UNICODE , y un typedef coincidente para que las variables puedan ser declaradas para contener punteros a ellos.

Entonces, para la mejor portabilidad hacia y desde Win16, debería #include <tchar.h> , use TCHAR en lugar de char o wchar_t , wchar_t todos los literales de cadenas que contengan texto en la macro _T() y llame a las API de Win32 con los nombres sin sufijo como MessageBox .

Esta no es una solución perfecta, sin embargo. En el momento en que su código necesita manipular o calcular una cadena que se mostrará a un usuario, descubrirá que es difícil escribir código que sea perfectamente portátil en el régimen de TCHAR . Hay reemplazos para todas las funciones de cadena estándar que manipulan los TCHAR , pero es difícil verificar con pruebas automáticas que los haya utilizado correctamente de modo que el código compile y funcione correctamente con y sin UNICODE definido.

Si hoy escribo un nuevo código Win32, mi consejo sería definir UNICODE en el proyecto, agregar una verificación de que está realmente definido en un archivo de encabezado común, y usar L"" strings y los sabores W de todas las llamadas envolventes explícitamente.

Finalmente, todo este ensayo lo solicita su código que muestra el glifo de personaje faltante (el carácter de cuadro cuadrado vacío es el glifo que se muestra cuando a una fuente le falta un carácter en particular). Esto ocurre porque los literales de cadena ASCII están siendo interpretados por el código Win32 como si fueran UTF-16LE, por lo que la cadena "Exit" se tomaría como dos caracteres Unicode, U+7845 y U+7469 , que son ambos Ideogramas Han unificados. A menos que tengas las fuentes Han instaladas, es muy poco probable que ambas estén presentes en cualquier fuente de tu sistema, por lo que obtienes el glifo de personaje que falta.

Esto sucede porque está mezclando la macro del contenedor con un literal de cadena ASCII. Tienes:

AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "Exit");

pero deberías tener uno de los siguientes:

AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, _T("Exit")); AppendMenuA(hSubMenu, MF_STRING, ID_FILE_EXIT, "Exit"); AppendMenuW(hSubMenu, MF_STRING, ID_FILE_EXIT, L"Exit");

donde prefiero recomendar el último ejemplo.