Les traigo este código el cual te genera una consola, en la que puedes escribir y leer.
Información
- Compatible con Cramel: 2.0.0.362
- Librerías requeridas: MSVBVM60.cml
Tiene los siguientes métodos:
- establecerTitulo(titulo:Cadena) - Si queremos cambiar de titulo de la consola
- escribir(texto:Cadena) - Escribimos en la misma linea
- escribirLinea(texto:Cadena) - Escribimos agregando al final LF (Salto de linea)
- establecerColor(atributos:Entero) - Establecemos algunos colores para la fuente y fondo (CONSTANTES)
- leer(Referencia texto:Cadena) - Leemos el teclado sin agregar el enter
- pausarConsola() - Terminamos la ejecución de la consola
- limpiarConsola() - Limpia la consola
Para usarla solo es de Importar la librería Cramel, Consola y su archivo de constantes propia; después declaramos una variable del tipo Console y creamos el objecto
Y es todo por el momento.
Aquí el código:
Archivo
Consola.cml'/**
' * Consola
' *
' * @author Jovani Pérez Damián (@BlackBlex)
' *
' * ==============Information==============
' * Filename: Consola.cml
' * ---------------------------------------
'*/
Clase Consola,_
hEntrada,_
hSalida,_
hError,_
textoEscritura,_
contador:Entero,_
caracter,_
letra,_
texto:Cadena,_
modo:WORD,_
tecla:Byte
Constructor:Inicializar
Destructor:Finalizar
Proc Inicializar
AllocConsole()
hEntrada = GetStdHandle(STD_INPUT_HANDLE)
hSalida = GetStdHandle(STD_OUTPUT_HANDLE)
hError = GetStdHandle(STD_ERROR_HANDLE)
Si hEntrada = INVALID_HANDLE Entonces
Mensaje("Error al obtener STDIN")
FinSi
Si hSalida = INVALID_HANDLE Entonces
Mensaje("Error al obtener STDOUT")
FinSi
Si hError = INVALID_HANDLE Entonces
Mensaje("Error al obtener STDERR")
FinSi
FinProc
Proc Finalizar
CloseHandle(hEntrada)
CloseHandle(hSalida)
CloseHandle(hError)
FreeConsole()
FinProc
Sección Privada
Proc getChar():Byte
caracter = Espacio(1)
GetConsoleMode(hEntrada, modo)
SetConsoleMode(hEntrada, modo and (-1*ENABLE_ECHO_INPUT) and (-1*ENABLE_PROCESSED_INPUT))
ReadConsole(hEntrada, StrPtr(caracter), 1, 1, 0)
SetConsoleMode(hEntrada, modo)
Resultado = ASCII(caracter)
FinProc
Sección Pública
Proc escribir(Referencia txt:Cadena)
WriteConsole(hSalida, StrPtr(txt), CadLong(txt), textoEscritura, nulo)
FinProc
Proc escribirLinea(Referencia txt:Cadena)
escribir(txt + LF)
FinProc
Proc establecerColor(atributos:Entero)
SetConsoleTextAttribute(hSalida, atributos)
FinProc
Proc establecerTitulo(Referencia titulo:Cadena)
SetConsoleTitle(titulo)
FinProc
Proc leer():Cadena
contador = 0
texto = ""
Repetir
tecla = getChar()
letra = Carácter(tecla)
Si (tecla = 8) Entonces
Si (contador > 0) Entonces
escribir("\x08 \x08")
texto = Izquierda(texto, CadLong(texto)-1)
contador = contador - 1
FinSi
SiNo
Si (tecla <> 13) Entonces
escribir(letra)
texto = texto + letra
contador = contador + 1
FinSi
FinSi
HastaQue (tecla = 13) or (contador = MAX_PATH)
escribirLinea("")
Resultado = texto
FinProc
Proc pausarConsola
escribirLinea("Presione una tecla para continuar . . . ")
tecla = getChar()
FinProc
Proc limpiarConsola
Var Temp:Entero
Temp = CreateConsoleScreenBuffer(GENERIC_READ Or GENERIC_WRITE,FILE_SHARE_READ Or FILE_SHARE_WRITE,Nulo,1,0)
Si (Temp = 0) Entonces Salir
SetConsoleActiveScreenBuffer(Temp)
CloseHandle(hSalida)
hSalida = Temp
FinProc
FinClase
Archivo
Constantes.cml <- Se recomienda que tengan un archivo propio de constantes (y que sea global), donde puedan poner todas las constantes que no contenta Cramel por defecto.
'/**
' * Constantes para la consola
' *
' * @author Jovani Pérez Damián (@BlackBlex)
' *
' * ==============Information==============
' * Filename: Constantes.cml
' * ---------------------------------------
'*/
' Consola '
Const STD_OUTPUT_HANDLE = -11
Const STD_INPUT_HANDLE = -10
Const STD_ERROR_HANDLE = -12
' Colores '
Const FOREGROUND_BLUE = &1
Const FOREGROUND_GREEN = &2
Const FOREGROUND_RED = &4
Const FOREGROUND_INTENSITY = &8
Const FOREGROUND_SEARCH = (&10)
Const BACKGROUND_BLUE = &10
Const BACKGROUND_GREEN = &20
Const BACKGROUND_RED = &40
Const BACKGROUND_INTENSITY = &80
Const BACKGROUND_SEARCH = &20
' Console mode flag'
Const ENABLE_ECHO_INPUT = &4
Const ENABLE_PROCESSED_INPUT = &1
Const ENABLE_LINE_INPUT = &2
Const ENABLE_MOUSE_INPUT = &10
Const ENABLE_WINDOW_INPUT = &8
Const ENABLE_PROCESSED_OUTPUT = &1
Const ENABLE_WRAP_AT_EOL_OUTPUT = &2
Const ENABLE_INSERT_MODE = &20
Const ENABLE_QUICK_EDIT_MODE = &40
Const ENABLE_EXTENDED_FLAGS = &80
Const ENABLE_AUTO_POSITION = &100
Y aquí un ejemplo usando Consola.cml
Importar "Cramel.cml"
Importar "MSVBVM60\MSVBVM60.cml"
Importar "Constantes.cml"
Importar "Consola.cml"
Var texto:Cadena
Var cmd:Consola
Crear cmd
cmd.establecerTitulo("cmd [Cramel]")
cmd.escribirLinea("Hola, como estas?")
texto = cmd.leer()
Si texto = "bien" Entonces
cmd.escribirLinea("Me alegra")
SiNo
cmd.escribirLinea("Suena mal, que paso?")
FinSi
cmd.escribirLinea("Como te llamas??")
texto = cmd.leer()
cmd.limpiarConsola()
cmd.escribirLinea("Hola " + texto)
cmd.pausarConsola()
Destruir cmd
(http://i.imgur.com/N31qkJY.png)
4 de marzo del 2017
- Gracias a @Yuki - Por la explicación del Prototipo.
- Aplicada la observación de @79137913
- Actualizada para la versión 1.5.0.83 - No funciona en anteriores
25 de junio del 2017
- Gracias a @Yuki - Por su función de limpiarConsola. :#
- Se paso a crear una clase para la Consola
- Corregido error al borrar texto.
- Actualizada para la versión 2.0.362 - No funciona en anteriores
Cualquier sugerencia, o error, comenten.
No tienes permitido ver los links.
Registrarse o Entrar a mi cuenta
Les traigo este código el cual te genera una consola, en la que puedes escribir y leer.
(http://i.imgur.com/N31qkJY.png)
Tiene los siguientes métodos:
- iniciar() - Siempre que ocupemos la consola debemos iniciarla
- establecerTitulo() - Si queremos cambiar de titulo de la consola
- escribir() - Escribimos en la misma linea
- escribirLinea() - Escribimos agregando al final LF (Salto de linea)
- establecerColor() - Establecemos algunos colores para la fuente y fondo (CONSTANTES)
- leer() - Leemos el teclado sin agregar el enter
- pausar() - Terminamos la ejecución de la consola
Tiene los siguientes campos:
- txt:Cadena - Antes de escribir en la consola, debemos de llenar este campo con lo que queremos escribir
- txtresultado:Cadena - Aquí se almacena la cadena leida
Y es todo por el momento.
Aquí el código:
'APIS para el funcionamiento de la consola'
API GetStdHandle(nStdHandle:Entero):Entero, "Kernel32"
API AllocConsole():Booleano, "Kernel32"
API WriteConsoleA(hConsoleOutput:Entero, Referencia lpBuffer:Cadena, nNumberOfCharsToWrite:Entero, Referencia lpNumberOfCharsWritten:WORD, Referencia lpReserved:Entero):Entero, "Kernel32"
API ReadConsoleA(hConsoleInput:Entero, Referencia lpBuffer:Cadena, nNumberOfCharsToRead:Entero, Referencia lpNumberOfCharsRead:WORD, Referencia lpReserved:Entero):Entero, "Kernel32"
API FreeConsole():Booleano, "Kernel32"
API SetConsoleTitleA(lpConsoleTitle:Cadena):Entero, "Kernel32"
API SetConsoleTextAttribute(hConsoleOutput, wAttributes:Entero):Entero, "Kernel32"
API GetConsoleMode(hConsoleHandle:Entero, Referencia lpMode:WORD):Booleano, "Kernel32"
API SetConsoleMode(hConsoleHandle, dwMode:WORD):Booleano, "Kernel32"
' Consola '
const STD_OUTPUT_HANDLE = -11
const STD_INPUT_HANDLE = -10
const STD_ERROR_HANDLE = -12
' Colores '
Const FOREGROUND_BLUE = &1
Const FOREGROUND_GREEN = &2
Const FOREGROUND_RED = &4
Const FOREGROUND_INTENSITY = &8
Const FOREGROUND_SEARCH = (&10)
Const BACKGROUND_BLUE = &10
Const BACKGROUND_GREEN = &20
Const BACKGROUND_RED = &40
Const BACKGROUND_INTENSITY = &80
Const BACKGROUND_SEARCH = &20
' Console mode flag'
Const ENABLE_ECHO_INPUT = &4
Const ENABLE_PROCESSED_INPUT = &1
'Callback'
Prototipo procsimple():Entero
Prototipo settitle(titulo:Cadena):Entero
Prototipo setattibute(atributos:Entero):Entero
' Nuestro gestor de consola '
Estruct ConsolaEstructura,_
hEntrada,_
hSalida:Entero,_
txt,_
txtresultado:Cadena,_
establecerTitulo:settitle,_
escribir:procsimple,_
escribirLinea:procsimple,_
establecerColor:setattibute,_
leer:procsimple,_
iniciar:procsimple,_
pausar:procsimple
' Variables de control '
Var Error:Booleano
Var Consola:ConsolaEstructura
Var consoleVar:WORD
' Iniciamos algunos metodos de nuestra consola '
Error = Falso
Consola.hEntrada = INVALID_HANDLE
Consola.hSalida = INVALID_HANDLE
Consola.iniciar@ = initConsole@
Consola.establecerTitulo@ = setCTitle@
Consola.escribir@ = writeConsole@
Consola.escribirLinea@ = writeConsoleLine@
Consola.leer@ = readConsole@
Consola.establecerColor@ = establecerAtb@
Consola.pausar@ = pauseConsole@
Proc initConsole():Entero
AllocConsole()
Consola.hEntrada = GetStdHandle(STD_INPUT_HANDLE)
Consola.hSalida = GetStdHandle(STD_OUTPUT_HANDLE)
Consola.txt = ""
Consola.txtresultado = ""
FinProc
Proc establecerAtb(atributos:Entero):Entero
Si check() Entonces
Resultado = SetConsoleTextAttribute(Consola.hSalida, atributos)
FinSi
FinProc
Proc setCTitle(titulo:Cadena):Entero
Si check() Entonces
Resultado = SetConsoleTitleA(titulo)
FinSi
FinProc
Proc writeConsole():Entero
Si check() Entonces
Var result:Entero
result = WriteConsoleA(Consola.hSalida, Consola.txt, CadLong(Consola.txt), consoleVar, 0)
Resultado result
FinSi
FinProc
Proc writeConsoleLine():Entero
Si check() Entonces
Consola.txt = Consola.txt + LF
Resultado writeConsole()
FinSi
FinProc
Proc readConsole():Entero NoResultado
readConsoleLimited(MAX_PATH)
FinProc
Proc readConsoleLimited(limite:Entero):Entero NoResultado
Si check() Entonces
Var i:Entero
Var tecla:Byte
Var letra:Cadena
i = 0
Consola.txtresultado = ""
Repetir
tecla = getChar()
letra = Caracter(tecla)
Si (i > 0) And (tecla = 8) Entonces
Consola.txt = "\x08 \x08"
Consola.escribir()
Consola.txtresultado = Izquierda(Consola.txtresultado, CadLong(Consola.txtresultado)-1)
SiNo
Si tecla <> 13 Entonces
Consola.txt = letra
Consola.escribir()
Consola.txtresultado = Consola.txtresultado + letra
i = i + 1
FinSi
FinSi
HastaQue (tecla = 13) or (i = limite)
Consola.txt = ""
Consola.escribirLinea()
FinSi
FinProc
Proc pauseConsole()
Si check() Entonces
Var tecla:Byte
Consola.txt = "Presione una tecla para continuar . . . "
Consola.escribirLinea()
tecla = getChar()
closeConsole()
FinSi
FinProc
Proc getChar():Byte
Var char:Cadena
Var mode:WORD
GetConsoleMode(Consola.hEntrada, mode)
SetConsoleMode(Consola.hEntrada, mode and (-1*ENABLE_ECHO_INPUT) and (-1*ENABLE_PROCESSED_INPUT))
ReadConsoleA(Consola.hEntrada, char, 1, consoleVar, 0)
SetConsoleMode(Consola.hEntrada, mode)
Resultado = ASCII(char)
FinProc
Proc closeConsole():Entero
Si check() Entonces
CloseHandle(Consola.hEntrada)
CloseHandle(Consola.hSalida)
FreeConsole()
FinSi
FinProc
Proc check():Booleano
Si (Consola.hEntrada = INVALID_HANDLE) or (Consola.hSalida = INVALID_HANDLE) Entonces
Si Error = Falso Entonces
Mensaje("Primero debes iniciar la consola antes de usarla")
FinSi
Error = Verdad
Resultado = Falso
SiNo
Resultado = Verdad
FinSi
FinProc
Y aquí un ejemplo usando Consola.cml
Importar "Cramel.cml"
Importar "Consola.cml"
Consola.iniciar()
Consola.establecerTitulo("Consola [Cramel]")
Consola.txt = "Hola, como estas?"
Consola.escribirLinea()
Consola.leer()
Si Consola.txtresultado = "bien" Entonces
Consola.txt = "Me alegra"
SiNo
Consola.txt = "Suena mal, que paso?"
FinSi
Consola.escribirLinea()
Consola.txt = "Como te llamas??"
Consola.escribirLinea()
Consola.leer()
Consola.txt = "Hola " + Consola.txtresultado
Consola.escribirLinea()
Var d,suma:Entero
d = 0
Repetir
suma = suma + d
Consola.txt = EntCad(suma)
Consola.escribirLinea()
d = d+1
HastaQue d = 10
Consola.pausar()
Cualquier sugerencia, o error, comenten.
Excelente!!
En cuanto este frente a un PC lo pruebo y te paso detalles!!
-RIOJAS
Muy interesante tu código y me parece increíble que le hayas agarrado la mano tan rápido, hasta estas usando prototipos :o
Te recomiendo inicializar los prototipos dentro de un procedimiento, al declarar una dll no se puede tener código no encapsulado (fuera de un procedimiento), por lo que tu código no se podría utilizar y seria una lastima.
También me gustó como emulaste la POO ;D ;D
Muy buen aporte!
No tienes permitido ver los links.
Registrarse o Entrar a mi cuenta
Muy interesante tu código y me parece increíble que le hayas agarrado la mano tan rápido, hasta estas usando prototipos :o
Te recomiendo inicializar los prototipos dentro de un procedimiento, al declarar una dll no se puede tener código no encapsulado (fuera de un procedimiento), por lo que tu código no se podría utilizar y seria una lastima.
También me gustó como emulaste la POO ;D ;D
Muy buen aporte!
Gracias por la explicación de los prototipos, por eso andaba confundido, porque no los hacia funcionar, una vez la explicación le agarre de volada.
Lo de exportarlo como dll, no lo había pensado; simplemente se me hizo más practico dejarlo como .cml e importarlo al usar.
Lo de inicializar los protopitos los tenia antes en la función initConsole, el problema llegaba cuando el usuario no ejecutaba dicho metodo, y salia "Error al acceder a la memoria" aunque es valido; quería que antes saliera un mensaje de lo que paso; y la única forma que vi fue haciendo la inicialización fuera. ;D
Lo cambiaré para que pueda ser exportado como dll, aunque viendo un poco más afondo, no sabría como mantener lo de "Consola." + metodos, puesto que en la dll, creo que solo se podrían usar los metodos y nada mas
Podes crear un "InitConsola" que retorne la estructura de prototipos, va a funcionar, el usuario solo tendria que declarar una variable del mismo tipo que la estructura y asignarla con el procedimiento.
Gracias por el aporte!! Me voy a poner a entender el código para agarrarle la mano
Muy bueno @BlackBlex (https://underc0de.org/foro/index.php?action=profile;u=26511), queria hacer algo similar, para agregar a el Editor de Cramel.
Saludos.
HOLA!!!
Veo que en el intento de emular POO perdes la capacidad para pasar parametros, no seria mejor, hacer una funcion que sea Consola_Escribir(txt) y otro que sea Consola_EscribirLinea(txt) para no tener que llenar las variables por fuera.
Me parece una mala practica la utilizacion de variables publicas para alimentar procedimientos.
GRACIAS POR LEER!!!
No tienes permitido ver los links.
Registrarse o Entrar a mi cuenta
HOLA!!!
Veo que en el intento de emular POO perdes la capacidad para pasar parametros, no seria mejor, hacer una funcion que sea Consola_Escribir(txt) y otro que sea Consola_EscribirLinea(txt) para no tener que llenar las variables por fuera.
Me parece una mala practica la utilizacion de variables publicas para alimentar procedimientos.
GRACIAS POR LEER!!!
Lo hice así sólo para hacer algo simple y sencillo.
Si se le puede pasar parámetros, ahora que tenga un tiempo rehago el archivo.
Estoy conciente de que es mala práctica lo de tener que poner el texto en una variable y luego imprimir, por finés de prácticas fue echo así.
Enviado desde mi MotoG3 mediante Tapatalk
Buenas, no me funciona en la última versión de cramel, me da error con la función Caracter().
Es fallo mío o por la versión del compilador.
Saludos.
No tienes permitido ver los links.
Registrarse o Entrar a mi cuenta
Buenas, no me funciona en la última versión de cramel, me da error con la función Caracter().
Es fallo mío o por la versión del compilador.
Saludos.
Checa que guardes el archivo con una codificación que no rompa los acentos y caracteres especiales, ya que es ahí donde se me ocurre que este el error; ya que la función Carácter es de Cramel.
Yo suelo guardar los .cml con codificación Windows 1252 (CP-1252), ya que igual he tenido problemas gordos con este asunto >.<
Cualquier cosa avisa, para que haga pruebas.
Enviado desde mi MotoG3 mediante Tapatalk
No tienes permitido ver los links.
Registrarse o Entrar a mi cuenta
Buenas, no me funciona en la última versión de cramel, me da error con la función Caracter().
Es fallo mío o por la versión del compilador.
Saludos.
Tengo la manía de cambiar el nombre de las funciones, intentaste con "Carácter"? ¿con la tilde?