PDA

Ver la versión completa : Visual Basic, AllocConsole y otros rollos



Nost
09-08-2007, 12:36
Tengo un problema, estoy intentando hacer un módulo para que cualquier programa de visual basic pueda usar de forma fácil (con unas pocas llamadas) la consola de windows. Algo así como:

CrearConsola()
EscribirEnConsola(StringAEscribir as String)
BorrarConsola()
CerrarConsola()

El problema está en EscribirEnConsola.

Estoy usando la api de windows (como es natural), y al parecer para escribir en la consola se usa WriteConsole, creo que hay que mandar un caracter cada vez, y en OEM.

La función está así:

1º Descomponer la StringAEscribir en un array. (HECHO)
2º Pasar los caracteres a códigos ANSI, por ejemplo, pasar "A" a "65" (como integer :)) (SIN HACER)
3º Pasar el código ANSI a código OEM (ejemplo: "65" > "??" (no sé como es en OEM)) (SIN HACER)
4º Pasarle el código OEM a WriteConsole (HECHO)

Pues eso, ayudadme... creo que hay que usar WideCharToMultiByte, y aunque tengo el win32.hlp (ayuda de la api) y el visor de la api (para las declaraciones y las constantes) me está siendo muy difícil. Gracias.

hystd
09-08-2007, 22:07
Hola buenas! Antes de nada decirte que me parece interesante esta aplicación que estás realizando ;).

Bueno para el punto 2, puedes usar la API: VkKeyScan (ch: char) que dado un caracter devuelve su valor en ASCII, por ejemplo:

VkKeyScan('a') => devuelve 65.

Esta contenida en User32.dll, de nombre VkKeyScan

puedes usarla con un bucle y pasar caracter a caracter la cadena: VkKeyScan(cadena[i]); en fin eso ya sabrás tu como hacerlo ;)

Por cierto, decirte que en delphi existen unas funciones (vease chr() y ord()) que te realizan esta labor... xD (No estoy de acuerdo con tu firma jejeje)

Bueno, y para el punto 3, no entiendo muy bien tu propósito, ¿que quieres hacer la inversa de esa función? Mira acerca de la función OEMKeyScan. Especifícalo mejor, jejjee.

Un saludo.

Nost
10-08-2007, 19:23
Bueno, ya esta casi acabado... la funcion no tiene ningun fallo visible, ademas pasa todos los caracteres acentuados, enyes, interrogantes, exclamaciones y otros simbolos a su equivalente oem.

Imaginate, lo facil que es, desde tu aplicacion:
CrearConsola()
EscribirEnConsola("Hola. Esto es una prueba. Como molaaaaaaaaa")

Funciona de puta madre. Pero, una cosa... ¿hay alguna funcion de api, para poder borrar la consola? Es que de momento estoy obligado a hacer:
FreeConsole
AllocConsole
para hacerlo, lo cual funciona perfectamente, pero no es muy bonito puesto que crea otra ventana, aparte de que dicha ventana toma el foco inmediatamente.

Nost
10-08-2007, 19:29
Por cierto, si no entiendes lo del OEM:
escribe en un archivo .bat:


@echo áéíóúÁÉÍÓÚ
@pause

Queda asi:
http://es.geocities.com/clancfs1/cosasparaforos/consola.JPG
Un pelin antiestetico, ¿verdad? Por eso, he solucionado todos esos pequeños fallos, todas las letras no-inglesas usadas en español. Evidentemente, es facil adaptar el codigo para incluir otro tipo de caracter.

hystd
12-08-2007, 14:00
Hola buenas! Me alegro que lo hayas solucionado. En cuanto a lo de convertir caracteres a OEM tienes el procedimiento CharToOEM(a, b: PChar), donde a y b son dos punteros a caracteres. En "a" pasas la dirección del caracter a convertir y en "b" se guarda el resultado de la conversión (parámetro de entrada-salida).

Para borrar la consola no existe una función o procedimiento específico de la API, aunque podrías implementarlo a partir del Handle de la Consola. Cuando creas una nueva a partir del constructor CrearConsola() guarda la dirección de memoria de ésta y a partir de ahí puedes implementar un procedimiento específico para ello. También puedes hacer uso de GetStdHandle que te devuelve el Handle de la consola (haciendo uso de las constantes STD_INPUT_HANDLE y STD_OUTPUT_HANDLE, cuyos valores son resultados de hacer un casting a un DWORD)

Tambíen se me ocurre una manera un poco mas sencilla y es mandar la instrucción "cls" del DOS, que te realiza esta labor :)

O bien, tienes la opción de usar FillConsoleOutputCharacter, que pasándole el handle de la consola y el carácter espacio " ", puedes rellenarla de espacios en blanco dando la sensación de "haberla borrado". :D

Espero haberte servido de ayuda :p

Un saludo

Nost
17-08-2007, 14:18
Sí, más o menos... Si todo marcha como he previsto, esta tarde crearé un hilo en offtopic con mi dll y un manual de uso...

Ah, y perdonar lo de que ponga la dll :), en cuanto limpie el código un poco de guarradas que tengo en él, subiré el módulo de clases...

Nost
17-08-2007, 14:21
por cierto, ¿ha caído geocities?...

Bueno, en otro orden de cosas, mi rutina de conversión ANSI>OEM es un poco home-made, no llama a dll's ni nada.