[Cramel] Consola.cml | 25 de Junio del 2017

Iniciado por BlackBlex, Marzo 01, 2017, 05:49:38 AM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Marzo 01, 2017, 05:49:38 AM Ultima modificación: Junio 26, 2017, 12:50:46 AM por BlackBlex
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
Código: Cramel
'/**
' * 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.
Código: Cramel
'/**
' * 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

Código: text
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




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.



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:
Código: text
'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

Código: text
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!

Marzo 01, 2017, 01:49:23 PM #3 Ultima modificación: Marzo 01, 2017, 01:51:31 PM por BlackBlex
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 @No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, 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!!!
"Algunos creen que soy un bot, puede que tengan razon"
"Como no se puede igualar a Dios, ya he decidido que hacer, ¡SUPERARLO!"
"La peor de las ignorancias es no saber corregirlas"

*Shadow Scouts Team*                                                No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Marzo 02, 2017, 02:18:12 PM #8 Ultima modificación: Marzo 02, 2017, 02:31:54 PM por BlackBlex
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.
RollthBuen hacker mejor No tienes permitido ver los links. Registrarse o Entrar a mi cuenta/No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

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?