Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 25-05-2017
Juampi Juampi is offline
Miembro
NULL
 
Registrado: may 2017
Posts: 14
Poder: 0
Juampi Va por buen camino
Necesito ayuda - Pascal - Lazarus

Buenas noches ( al menos por mis pagos es de noche ).

Antes que nada decir que no sé si es la sección correcta, y pido disculpas por adelantado de no serlo. Soy nuevo en el foro, el usuario lo cree hace unos días y les quería contar que en cuestión de programación soy novato elevado a la N, pero al mismo tiempo me gusta, no bajé Lazarus por obligación, y entiendo que eso es una gran ventaja, je.

Bueno, al tema, mi pregunta es bastante puntual, pienso que en principio sería bastante fácil de contestar, al menos por aquellos con conocimientos intermedios - avanzados.

Me puse como meta, y ya me dirán uds si es una meta sensata, muy ambiciosa o muy discreta, hacer una calculadora lo más parecida a la de Windows 10. Es decir:
  • El mismo formato.
  • Poder ingresar los números tanto mediante click como mediante teclado.
  • Que al ingresarlos mediante teclado los botones tengan una animación del número que es presionado.
  • No perder el foco en la caja de texto por más que haya clickeado un botón con el puntero. Es decir, que la caja de texto siempre esté "lista" de recibir los números que se teclean.
  • Poder ir "anidando" operaciones y que al final me de el resultado de todo lo que hice. Ejemplo 10 + 7 + 5 - 8 * 2 / 3 + 5... =
  • Etc, básicamente, "plagiar" la calculadora de Windows como práctica.

Entonces, la pregunta es, ¿qué conocimientos NECESITO para poder llevar a cabo ese programa?, y remarco el "necesito" porque por ahí con determinados conceptos lograrlo sería más sencillo, o quedaría "mejor programado", de una forma más eficiente, etc, pero lo de perfeccionar el código lo dejo para más adelante, yo ahora quiero saber qué es imprescindible para poder hacer esa calculadora, aunque me lleve más tiempo y código.

Me gusta mucho pensar y pensar y romperme la cabeza viendo como resolver un problema pero quiero saber si tengo los conceptos necesarios o voy a estar rompiéndome el marote sin llegar a nada ya que directamente no conozco las herramientas que necesito.

Desde ya muchas gracias y perdón si la hice muy larga. Espero haya quedado claro el planteo.

Saludos
Responder Con Cita
  #2  
Antiguo 25-05-2017
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Hola y bienvenido a clubdelphi
Para empezar a responderte habría que saber cuáles son tus conocimientos de programación, porque lo que necesitas es manejarte un poco con el lenguaje, tener unas ideas de matemáticas, un poco de deducción lógica y ganas, muchas ganas de ponerte con ello

Por los foros y por nuestro ftp encontrarás montones de tutoriales, ayudas, ejemplos, programas (incuso calculadoras), libros, enlaces... montones de gigas de información para poder aprender.
También te recomiendo, antes de seguir, que leas nuestras normas básicas.
De nuevo, bienvenido
Responder Con Cita
  #3  
Antiguo 26-05-2017
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Bienvenido al ClubDelphi

Yo creo que lo mejor es ir poco a poco y que vayas realizando de una tarea a la vez. Por ejemplo, podrias ir tomando una a una las de la lista que hiciste, e ir resolviendolas. Si te trabas en algun momento, no dudes en consultar. Tampoco me parece mal que hagas una especie de "diario" si quieres en el mismo foro de como lo vas resolviendo. De esa manera el resto puede ir viendo el codigo y comentando

Vas a necesitar, mas que nada, conocer el framework de componentes con el que vas a trabajar. En Delphi tenes dos, uno se llama Vcl y esta basado en la API de Windows, por lo tanto, solamente corre en Win32 y Win64. Por otra parte, tenes Firemonkey (FMX) el cual es multiplataforma, y puede correr en Win32, Win64, iOS, OSX y Android. Por mucho esfuerzo que hayan hecho, algunas cosas son "similares" entre los dos framework, pero la verdad es que hay grandes diferencias.

Una vez que te decidas por un framework, es cuestion de ir conociendo los componentes y los controles, saber que puedes hacer con ellos basicamente. Firemonkey es mas nuevo, por lo que esta en las versiones mas recientes de Delphi (creo que desde Delphi XE2, pero aca solo corria en Windows y OSX, y le han ido agregando plataformas en las sucesivas versiones) mientras que la Vcl esta desde el dia 1. Sobre la Vcl vas a encontrar muchisima informacion en los foros, en la web, y sobre todo, mas gente que conoce el framework. Ademas, es indiscutiblemente muchisimo mas maduro que FMX, al que todavia le falta pulir algunas cosas
Responder Con Cita
  #4  
Antiguo 26-05-2017
Juampi Juampi is offline
Miembro
NULL
 
Registrado: may 2017
Posts: 14
Poder: 0
Juampi Va por buen camino
Gracias

Primero que nada gracias por las respuestas y la bienvenida.

@Casimiro Notevi

Imaginé que podría ser una posible consulta de uds, qué conocimientos tengo, de primera no los puse por dos motivos, uno, para que no quedara más largo de lo que ya estaba quedando mi mensaje (no soy bueno sintetizando, tiendo a escribir mucho), y dos, mi pregunta buscaba una respuesta del estilo de:

"Necesitas conocer tipos de variables (diferenciar integer de string, por ejemplo), estructuras de control y manejo de arrays, teniendo claros esos conceptos es suficiente"

...o por ejemplo...

"Necesitas conocer tipos de variables, estructuras de control, arrays, matríces, punteros, listas, árboles, cola, pila, manejo de eventos, bla, bla, bla"

Esas respuestas que puse como ejemplo se podrían dar independientemente de cuáles sean mis conocimientos, ¿se entiende a lo que voy?. Pero es lógico tu planteo, ya mismo te cuento que tengo los conocimientos del primer ejemplo de respuestas, jeje. Sé lo que es una variable, conozco los tipos básicos (integer, real, char, string, boolean), sé utilizar las estructuras de control (quizás incursione en malas prácticas al usarlas pero les doy un uso que resuelve mis problemas, je), sé manejar un array acotado y tengo idea de los eventos. Hasta ahí llega mi sabiduría, como les dije, novato elevado a la N.

Pff, leí las normas, el punto 4 me crucifica, de tres palabras de ejemplo para NO utilizar, usé dos. Lo que no estoy viendo es si es posible corregir el título, si se puede no encontré cómo.

@[AgustinOrtu]

Si, es lo que estoy haciendo, de hecho lo único que empecé a programar es el botón +, y ahora mismo estoy viendo cómo resolver la cuestión de que cada vez que presione el botón + me guarde el número ingresado en el array (array que por el momento lo tengo acotado a diez lugares ya que no sé cómo manejar "arrays dinámicos", por ahora mi calculadora solo te permite operar con hasta diez números distintos ) y que el próximo ingresado lo guarde en la siguiente posición, y así sucesivamente hasta que se presione el botón =. Ahí recién se opera con todos los números almacenados.

Suena simple pero no me estoy dando cuenta como hacerlo. A esto agregar que no sé tampoco como hacer para que luego de clickear el botón + automáticamente retome el foco en la caja de texto y lo próximo que escriba sobreescriba el anterior número.

En principio no veo de qué modo iterar, un for no puedo porque no sé cuántos números va a utilizar el usuario, puede hacer 4 + 4 como puede hacer 4 + 5 + 4 + 7 + 7 + 9. Y si hago un repeat no me doy cuenta como controlarlo para que se ejecute entre click y click del botón + hasta que se presione el =, la primera vez que empecé a escribir el código se me "rompía" el array porque el repeat ejecutaba todo el código en el momento que apretaba el más y la condición de término nunca llegaba, después me di cuenta la burrada que había hecho y ahora estoy viendo como encararlo.

Gracias nuevamente, sigo un poco más y les comento mis avances.
Responder Con Cita
  #5  
Antiguo 26-05-2017
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Si vas a usar un arreglo, vas a tener que en algun lado mantener un indice, osea el lugar "actual", por decirlo de alguna manera, para saber cual fue la ultima posicion en la que guardaste el ultimo numero.

El arreglo dinamico es muy similar al estatico, la unica diferencia es que debes inicializarlo, y obviamente el compilador no puede ayudarte si "te vas de rango", mientras que el estatico no te va a permitir (a menos, no por defecto) utilizar posiciones fuera del rango permitido.

Asi usas un arreglo dinamico:

Código Delphi [-]
procedure ArregloDinamico;
var
  tamanoArreglo, unNumero: Integer; 
  numeros: array of Integer;
begin
  tamanoArreglo := 10; // no es ncesario que sea una variable, podes pasar el 10 como constante
  System.SetLength(numeros, tamanoArreglo); // inicializo un arreglo de 10 elementos
  numeros[0] := 1;
  numeros[2] := 34;
  numeros[9] := 5;
  numeros[10] := 5; // aca te fuiste de rango!

  unNumero := numeros[2];
end;
Responder Con Cita
  #6  
Antiguo 26-05-2017
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por Juampi Ver Mensaje
Pff, leí las normas, el punto 4 me crucifica, de tres palabras de ejemplo para NO utilizar, usé dos. Lo que no estoy viendo es si es posible corregir el título, si se puede no encontré cómo.
No te preocupes, no lo sabías.

Realmente no se puede contestar lo que necesitas saber porque puedes hacer la calculadora de muchas formas distintas, esto es como el MacGuiver, según con lo que cuentes te las apañas
Que quieres hacerlo con arrays, lo haces con arrays, que quieres hacerlo solo con variables, pues solo con variables, etc.
Claro, siempre hay métodos mejores, pero eso lo hace la experiencia y haber visto códigos de otros.
Responder Con Cita
  #7  
Antiguo 26-05-2017
Avatar de olbeup
olbeup olbeup is offline
Miembro
 
Registrado: jul 2005
Ubicación: Santiago de la Ribera (España)
Posts: 685
Poder: 19
olbeup Va camino a la fama
Hola Juampi,

Con esto puedes avanzar un poco.

Esto al principio
Código Delphi [-]
const
  WVK_BACKDELETE  = #8;
  WVK_SUM         = #43;
  WVK_REST        = #45;
  WVK_EQUAL       = #61;
  WVK_NULL        = #0;
  WVK_EMPTY       = '';

type
  TCalculatorReg = record
    NumberStr: String;
    KeyPred: Char;
    KeyNext: Char;
    SubTotal: Integer;
  end;
Y esto en los eventos correspondientes.
Código Delphi [-]
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if not (Key in ['0'..'9', WVK_SUM, WVK_REST, WVK_EQUAL, WVK_BACKDELETE]) then
    Key := WVK_NULL;
end;

procedure TForm1.Button1Click(Sender: TObject);

  function IsNumeric(S: Char): Boolean;
  begin
    Result := (S in ['0'..'9']);
  end;

  function IsSum(S: Char): Boolean;
  begin
    Result := (S = '+');
  end;

  function IsRest(S: Char): Boolean;
  begin
    Result := (S = '-');
  end;

var
  Calc: TCalculatorReg;
  nI: Integer;
  S: String;
  Key: Char;
begin
  FillChar(Calc, SizeOf(Calc), #0);
  Key := WVK_NULL;
  S := Edit1.Text;

  for nI := 1 to Length(S) do
  begin
    if IsNumeric(S[nI]) then
      Calc.NumberStr := Calc.NumberStr + S[nI]
    else
      if IsSum(S[nI]) then
        Key := WVK_SUM
      else
        if IsRest(S[nI]) then
          Key := WVK_REST
        else
          Key := WVK_EQUAL;

    if (Key <> WVK_EMPTY) and (Calc.KeyPred <> WVK_EMPTY) and (Calc.KeyNext = WVK_EMPTY) then
      Calc.KeyNext := Key;

    if (Key <> WVK_EMPTY) and (Calc.KeyPred = WVK_EMPTY) and (Calc.KeyNext = WVK_EMPTY) then
      Calc.KeyPred := Key;

    Key := WVK_NULL;

    if (Calc.KeyPred <> WVK_EMPTY) and (Calc.KeyNext = WVK_EMPTY) then
      if (Calc.SubTotal = 0) then
      begin
        Calc.SubTotal := StrToInt(Calc.NumberStr);
        Calc.NumberStr := WVK_EMPTY;
      end;

    if (Calc.KeyPred <> WVK_EMPTY) and (Calc.KeyNext <> WVK_EMPTY) then
    begin
      if (Calc.KeyPred = WVK_SUM) then
        Calc.SubTotal := Calc.SubTotal + StrToInt(Calc.NumberStr);
      if (Calc.KeyPred = WVK_REST) then
        Calc.SubTotal := Calc.SubTotal - StrToInt(Calc.NumberStr);
      Calc.NumberStr := WVK_EMPTY;
      Calc.KeyPred := Calc.KeyNext;
      Calc.KeyNext := WVK_NULL;
    end;
  end;

  Label2.Caption := IntToStr(Calc.SubTotal);
end;

Un Saludo.

p.d.: Sólo funciona con enteros y al final tienes que poner un = para que lo sume todo, ya lo modificas como quieras.
__________________
Al hacer una consulta SQL, haz que los demás te entiendan y disfruten de ella, será tú reflejo de tú saber.
Responder Con Cita
  #8  
Antiguo 27-05-2017
Juampi Juampi is offline
Miembro
NULL
 
Registrado: may 2017
Posts: 14
Poder: 0
Juampi Va por buen camino
Baby steps lo mio xD

@[AgustinOrtu]

Estuve hablando con un amigo y al parecer el array dinámico no era lo que yo creía que era, y tampoco me permitiría tener "infinitos" números, que para eso pensara en punteros. Voy a tener que leer un poco sobre eso, tanto sobre arrays dinámicos como sobre punteros.

@Casimiro Notevi

¿Es posible hacer la calculadora de Windows solo con variables?, de ser así, sé menos programación de lo que creía que sabía. ¿Cómo manejas solamente con variables que el usuario ingrese todos los números que se le plazca?.

Repito la consigna por las dudas, mi idea no es hacer una calculadora cualquiera, es hacerla como la de Windows, que el usuario me puede ingresar n + n como me puede ingresar n + n + n - n -n + n / n * n + n... + n. Sinceramente no sé cómo guardar todos esos valores utilizando solo variables, no digo que no sea posible, sencillamente no me doy cuenta.

@olbeup

Hay varias líneas de ese código que no sé leer, no las termino de entender, pero veré si lo copio y ejecutándolo y probando logro entenderlo al completo.

Saludos y gracias, les aviso cuando logre algo como la gente, jeje.
Responder Con Cita
  #9  
Antiguo 27-05-2017
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Con un arreglo dinamico podes tener tantos numeros como memoria tengas disponible (ok no es del todo precisa esa afirmacion, es un poco exagerado, pero podemos verlo de esa manera)

Si te fijas en como estan implementadas las estructuras que contienen datos (el ejemplo mas facil son las listas) veras que usan un arreglo dinamico, el cual van haciendo crecer a medida que hace falta meter mas elementos. Para eso estas clases van llevando la cuenta de cuantos elementos hay, cual es el tamaño actual del arreglo, realizan el "ensanchamiento" cuando es necesario, etc.

Obviamente esto tiene un coste, porque los arreglos tratan de posiciones contiguas de memoria: si yo primero digo que hay un arreglo con 10 posiciones, se reserva en memoria 10 posiciones contiguas; si ahora quiero tener 15, necesito 15 posiciones. Si en donde estaba parado tengo para sumar las 5 posiciones, genial; pero si no, tengo que buscar una porcion de memroia en donde me entre un arreglo de 15 y despues moverlo.
Todo esto se maneja de memoria automatica incluso si queres operar a un nivel "tan bajo" como es el de los arreglos dinamicos. Uno simplemente lo redimensiona, con el mismo codigo que mostre arriba, llamando a System.SetLength(variableArreglo, tamanoDeseado) y Delphi/Lazarus se encarga del resto.

Si queres poder usar el arreglo dinamico, quiza requiera un poco mas de trabajo, aunque como aprendizaje esta buenisimo. Si queres usar algo ya hecho, en tu caso lo mas ideal seria una lista. No es estoy muy al dia con el tema de las clases en Lazarus, pero si realmente trata de ser lo mas Delphi-compatible posible, supongo que habra una clase TList en la unidad Classes.pas. Ejemplos y documentacion de esta clase hay por doquier. El problema que tiene esta clase es que el tipo de los elementos que guarda son punteros, porque permite guardar cualquier cosa. Va a implicar que aprendas a usar casting, lo cual a esta altura me parece demasiado

Tambien podes considerar utilizar la version generica, TList<T>. Esta soluciona el problema del tipo que comentaba en el parrafo anterior. En pocas palabras, es lo mismo que la TList, pero esta permite solamente tener elementos del tipo que le indica el programador, esto lo hace mas seguro y comodo de usar ya que te olvidas del tema de punteros. Pero de nuevo, creo que te voy a marear demasiado con tanta informacion
Responder Con Cita
  #10  
Antiguo 28-05-2017
Avatar de axesys
axesys axesys is offline
Miembro
 
Registrado: ene 2007
Ubicación: Los Mochis Sinaloa
Posts: 208
Poder: 18
axesys Va por buen camino
Te recomiendo que investigues sobre tplex y tpyacc, son metacompiladores que te pueden tokenizar y calcular las expresiones de una cadena.

http://freecode.com/projects/dyacclex
Responder Con Cita
  #11  
Antiguo 29-05-2017
Juampi Juampi is offline
Miembro
NULL
 
Registrado: may 2017
Posts: 14
Poder: 0
Juampi Va por buen camino
Retomo el proyecto

@[AgustinOrtu]

Gracias por la aclaración, y dado lo que me dijiste ya guardé para leer más adelante "TCollection" en wiki.freepascal.org. Decidí inicialmente intentar hacer funcionar la calculadora con un máximo de números y una vez consiga ese objetivo parcial, después dar el paso a todos los números que el usuario quiera. Pienso que como comienzo e ir fijándome metas es razonable.

@axesys

Gracias, lo haré ni bien avance un poco más con el proyecto, que por ahora no he salido del botón +, je. En mi defensa aclarar que desde que abrí este hilo no debo haber pasado la media hora con el programa, no he tenido tiempo y acá estoy un Domingo, el único día "100% libre" que tengo, tratando de adelantar algo.

@todos

Les cuento lo que me tiene trancado ahora mismo, que estoy seguro que es una bobada importante pero no me estoy dando cuenta. Este es el código de mi botón +:

Cita:
{--- S U M A (+) ---}

procedure TForm1.btnSumaClick(Sender: TObject);

var i : integer;

begin
display.setFocus; {---"display" es el nombre que le puse a la caja de texto donde ingreso los números, le pongo el setFocus para que enseguida quede pronto para recibir más números---}
op[i] := '+'; {---ignoren esto por ahora---}
nros[i] := StrToInt(display.text); {---nros es el array donde guardo los números que va ingresando el usuario---}
log[i] := display.text; {---esto también lo pueden ignorar por el momento, tiene que ver con mi idea de dejar un log encima de la caja de texto con las operaciones que fueron ingresadas---}
lbLog.caption := log[i]; {---lbLog se llama el label donde voy a mostrar el log---}
i := i + 1 {---acumulo en i---};
end;
Les explico:
  • ¿Estamos de acuerdo que el bloque de código que les muestro se va a ejecutar tantas veces como veces apriete el botón +, no?
  • Si dejo la variable i sin inicializar el programa me da error, aparece un mensaje que si mal no recuerdo dice 'External: SIGSEGV', que por lo poco que googleé es un 'Access Violation' y entiendo que se debe a que aleatoriamente la variable i tomó un valor que queda por fuera del rango del array. ¿Esto es así?.
  • Si inicializo la variable antes del begin me da error al compilar, o sea, no funciona el programa ya de arranque, así que entiendo que eso no se hace, que no funciona de esa manera.
  • Y después del begin ni siquiera lo probé porque entiendo que cada vez que presione el botón le voy a asignar ese valor (cero en este caso, mi array va del 0 al 9) y nunca lo podría usar como acumulador que es lo que busco justamente.

Es muy probable que la solución a esto sea extremadamente sencilla, y si bien termino de escribir esto y me voy a seguir pensando como se haría, quería que supieran en qué estaba trancado y mi decisión de por el momento acotar el array a "x" cantidad de lugares y después profundizar en arrays dinámicos, TList, etc.

Gracias una vez más.
Responder Con Cita
  #12  
Antiguo 29-05-2017
Juampi Juampi is offline
Miembro
NULL
 
Registrado: may 2017
Posts: 14
Poder: 0
Juampi Va por buen camino
Quise editar y no pude

No dije nada, no dije nada, ya se me iluminó la lamparita con lo que me tenía trancado, jeje. Quise editar el mensaje anterior pero ya habían pasado 25 minutos.

Saludos
Responder Con Cita
  #13  
Antiguo 22-07-2017
Juampi Juampi is offline
Miembro
NULL
 
Registrado: may 2017
Posts: 14
Poder: 0
Juampi Va por buen camino
I'm back!

Buenas, no me conectaba desde el 29/5, hacía rato no me daba una vuelta por aquí. Por distintos motivos la calculadora la dejé en stand by pero esta semana la retomé y les quería pedir una mano porque estoy trancado.

Lo que me pasa es lo siguiente, hago múltiples operaciones y me dan todas ok hasta que hago la siguiente combinación:

5 + 5 - 1 x 2 / 2.

Que de forma correcta (igual que la calculadora de Windows que es la que quiero emular, jeje) me da 9.

5 + 5 = 10
10 - 1 = 9
9 x 2 = 18
18 / 2 = 9

Pero la siguiente operación que hago después de esa secuencia me da mal. Ejemplo hago 5 x 5 y me da 24, 5 + 5 me da 9, 6 x 6 me da 35, 9 x 9 me da 80. Si, como podrán ver, me da uno menos del resultado correcto. Viendo eso sería sencillo identificar el problema pero no me doy cuenta que puede estar mal. Si teóricamente después de apretar el botón = vuelvo todo a cero, sería como cerrar y volver a ejecutar la calculadora (aunque evidentemente no lo es).

Es más, por las dudas también aprieto el botón C que lo que hace es "poner todo en cero", y nada, hasta que no cierre la calculadora seguirá dando un número menos.

Probando hice otra operación, en este caso 5 + 10 - 2 x 2 / 2 = 13 (correcto). Todo lo que hago luego de eso me da DOS números menos que lo correcto. Ejemplo 5 x 5 me da 23.

Les dejo lo que yo entiendo que necesitarían ver de este código para que puedan decirme donde la estoy macaneando y un link al .exe de la calculadora (no se rían, está en fase ultra beta, jaja).

Les dejo la declaración de variables, el form on create, el botón igual, el botón +, el botón C y un número, en este caso el 1.

Cita:
private
{ private declarations }
public
{ public declarations }
var res, ultNro: integer;
nros: array [0..9] of integer;
op: array [0..9] of string;
nro: string;
sobreescribo, borroLog : boolean;

end;

____________________________________________________________________________________________________ ________________________________________________________

{ TForm1 }

{--- FORM ON CREATE ---}

procedure TForm1.FormCreate(Sender: TObject);
begin
ultNro := 0;
sobreescribo := false;
borroLog := false;
end;

____________________________________________________________________________________________________ ________________________________________________________

{--- BOTÓN IGUAL (=) ---}

procedure TForm1.btnIgualClick(Sender: TObject);

var i: integer;

begin

i := 0;

if display.text = '' then
begin
display.text := '0'
end;

nros[ultNro] := StrToInt(display.text);

if lbLog.caption = '' then
begin
display.text := IntToStr(nros[ultNro]);
display.setFocus;
end;

for i := 0 to ultNro do
begin

{S U M A (+)}
if op[i] = '+' then
begin
if i = 0 then
begin
res := nros[i] + nros[i + 1];
end

else
begin
res := res + nros[i + 1];
end
end

{R E S T A (-)}

else if op[i] = '-' then
begin
if i = 0 then
begin
res := nros[i] - nros[i + 1];
end

else
begin
res := res - nros[i + 1];
end
end

{M U L T I P L I C A C I Ó N (X)}

else if op[i] = 'X' then
begin
if i = 0 then
begin
res := nros[i] * nros[i + 1];
end

else
begin
res := res * nros[i + 1];
end
end

{D I V I S I Ó N (/)}

else if op[i] = '/' then
begin
if i = 0 then
begin
res := nros[i] DIV nros[i + 1];
end

else if nros[i] = 0 then
begin
display.text := 'No se puede dividir entre 0';
display.setFocus();
btnPercentage.enabled := false;
button16.enabled := false;
button17.enabled := false;
button1.enabled := false;
button2.enabled := false;
btnComa.enabled := false;
btnSuma.enabled := false;
btnResta.enabled := false;
btnMultiplicacion.enabled := false;
btnDivision.enabled := false;
ultNro := 0;
end

else

begin
res := res DIV nros[i + 1];
end
end

else
begin
res := res;
end
end;

lbLog.caption := '';
display.text := IntToStr(res);
sobreescribo := true;
borroLog := true;
ultNro := 0;

end;

____________________________________________________________________________________________________ ________________________________________________________

{--- BOTÓN SUMA (+) ---}

procedure TForm1.btnSumaClick(Sender: TObject);

begin

if display.text = '' then
begin
display.text := '0'
end;

display.setFocus;

nros[ultNro] := StrToInt(display.text);
op[ultNro] := '+';

if lbLog.caption = '' then
begin
lbLog.caption := IntToStr(nros[ultNro]) + op[ultNro];
end

else
begin
lbLog.caption := lbLog.caption + IntToStr(nros[ultNro]) + op[ultNro];
end;

ultNro := ultNro + 1;
sobreescribo := true;

end;

____________________________________________________________________________________________________ ________________________________________________________

{--- BOTÓN BORRAR TODO (C) ---}

procedure TForm1.btnCClick(Sender: TObject);
begin
btnPercentage.enabled := true;
button16.enabled := true;
button17.enabled := true;
button1.enabled := true;
button2.enabled := true;
btnComa.enabled := true;
btnSuma.enabled := true;
btnResta.enabled := true;
btnMultiplicacion.enabled := true;
btnDivision.enabled := true;
display.text := '0';
display.setFocus;
lbLog.caption := '';
ultNro := 0;
sobreescribo := false;
end;

____________________________________________________________________________________________________ ________________________________________________________

{--- BOTÓN UNO (1) ---}

procedure TForm1.btn1Click(Sender: TObject);
begin

if borroLog then
begin
lbLog.caption := '';
end;

if (sobreescribo) or (display.text = '0') or (display.text = '') then
begin
display.text := '1';
end

else
begin
nro := display.text;
display.text := '1';
display.text := nro + display.text;
end;

sobreescribo := false;
borroLog := false;

end;
Aquí el link para descargar el .exe

drive.google.com/open?id=0B2s4ogym-XembWY5Vl8tV2tBcEE

Si les sirve más el proyecto completo les dejo el link para descargar el rar.

Aclaraciones:

*Por el momento funciona solo haciendo click con el mouse, ya aprenderé como hacer para que los botones del teclado accionen (con animación incluida es mi idea, no sé si es posible) los botones de la calculadora.

*Los únicos botones que andan son los números, los signos de +, -, X, /, el de borrar todo (C), el = y el de borrar de a uno (<).

Desde ya muchas gracias.
Responder Con Cita
  #14  
Antiguo 22-07-2017
Juampi Juampi is offline
Miembro
NULL
 
Registrado: may 2017
Posts: 14
Poder: 0
Juampi Va por buen camino
Never mind (?)

Creo haberme dado cuenta del problema, olvídense, cualquier cosa los vuelvo a molestar.

Gracias
Responder Con Cita
  #15  
Antiguo 23-07-2017
Juampi Juampi is offline
Miembro
NULL
 
Registrado: may 2017
Posts: 14
Poder: 0
Juampi Va por buen camino
KeyDown

Bueno, esta vez si me tranqué de verdad...

La calculadora ya funciona de forma correcta en lo que tiene que ver con hacer operaciones, pero ahora quiero poder ingresar los números por teclado también, y entiendo que tengo que manejar el evento KeyDown, pero no hay caso, no lo puedo hacer funcionar.

Vi algunos ejemplos en internet e intenté replicarlos pero no hubo caso. Lo que tengo es lo siguiente:

Cita:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

begin
if key = 49 then
begin
btn1.Click;
end;
end;
Es el evento KeyDown del Form1 (¿tendría que hacerlo en el TEdit en vez del Form?, yo elegí el form porque es lo que siempre tiene el foco, pero lo cierto es que no tengo claro el manejo de eventos), y la idea es que dispare el evento click del botón correspondiente. En ese código lo que quise hacer es que la tecla 1 ejecute el evento click del botón 1 de la calculadora.

Variantes probé varias, probé if key = #49, if (key = #49), if key in [49], if key in [#49] y varias más que ahora no recuerdo, algunas dieron error y otras compilaron bien pero ninguna funcionó. Claramente estoy haciendo algo mal.

Gracias por su ayuda.

P.D.: Por si a alguien le interesa, acá el link del ejecutable actual de la calculadora drive.google.com/open?id=0B2s4ogym-XemRUNPbzhtaWcxbEE
Responder Con Cita
  #16  
Antiguo 23-07-2017
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Proba seteando la propiedad KeyPreview del Form a True
Responder Con Cita
  #17  
Antiguo 23-07-2017
Juampi Juampi is offline
Miembro
NULL
 
Registrado: may 2017
Posts: 14
Poder: 0
Juampi Va por buen camino
Gracias

Pero la p... que fácil que era.

Me funciona con el botón de arriba a la izquierda, abajo del F1, y no con el numérico que está a la derecha, pero supongo que es una cuestión de cambiarle el número, en lugar de 49 tendré que usar otro.

Muchas gracias, me destrancaste, jeje.

EDITO:

¿Cuáles son los números ascii de las teclas numéricas de la derecha?, ¿o cómo puedo capturar para saber qué código son usando el evento?. Recién puse un ShowMessage() y se disparó al apretar el 1 del teclado numérico, pero, ¿cómo almaceno eso para saber qué código tengo que poner en el IF?.

Gracias.
Responder Con Cita
  #18  
Antiguo 23-07-2017
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Podes usar las constantes VK_NUMPADX, donde X es un numero entre 0-9. Estas estan definidas en la unidad Winapi.Windows

Te recomiendo que uses estas constantes en lugar de, como suele llamarseles, "valores magicos", porque el 13 es el enter, y el 27 el escape, pero es mas practico leer VK_ESCAPE, VK_RETURN, etc
Responder Con Cita
  #19  
Antiguo 23-07-2017
Juampi Juampi is offline
Miembro
NULL
 
Registrado: may 2017
Posts: 14
Poder: 0
Juampi Va por buen camino
Error: Identifier not found "VK_MULTIPLY"

Gracias, no encontré la unidad Winapi.windows (asumo que es un archivo) ni windows.pas como leí un comentario tuyo en otro hilo que también podría aparecer, pero si encontré el archivo LCLType.pp.

En dicho archivo me figura lo siguiente:

VK_NUMPAD0 = 96; // $60
VK_NUMPAD1 = 97;
VK_NUMPAD2 = 98;
VK_NUMPAD3 = 99;
VK_NUMPAD4 = 100;
VK_NUMPAD5 = 101;
VK_NUMPAD6 = 102;
VK_NUMPAD7 = 103;
VK_NUMPAD8 = 104;
VK_NUMPAD9 = 105;
VK_MULTIPLY = 106; // VK_MULTIPLY up to VK_DIVIDE are usually in the numeric keypad in PC keyboards
VK_ADD = 107;
VK_SEPARATOR = 108;
VK_SUBTRACT = 109;
VK_DECIMAL = 110;
VK_DIVIDE = 111;

Y por lo que probé en el evento KeyDown funciona con el valor numérico, no con el texto. Si pongo VK_MULTIPLY (por ejemplo) al compilar me aparece el error del asunto (Error: Identifier not found "VK_MULTIPLY"), pero usando el valor numérico (106 en el caso de MULTIPLY) si funciona.

Por otro lado con el evento KeyPress no me funciona de ninguna de las dos maneras, ni con valor numérico ni con el texto. Si pongo números el error pasa a ser:

Error: Incompatible types: got "Char" expected "Int64"

Pero bueno, uso el evento KeyDown únicamente y listo, yo había hecho una especie de división entre botones que utilicen keydown y botones que utilicen keypress porque si tu abres la calculadora de Windows y dejas un número apretado se irá escribiendo varias veces, pero al mismo tiempo un signo de operación no tiene que repetirse, se aprieta una vez sola hasta que haya otro número ingresado, por eso quise hacer de la siguiente manera:

Cita:
{___________________________________________________________________________________________________ _________________________________________________________

--- EVENTO KEYDOWN ---
____________________________________________________________________________________________________ _________________________________________________________}

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

begin

{BOTÓN 0}

if key = 96 then
begin
btn0.Click;
end;

{BOTÓN 1}

if key = 97 then
begin
btn1.Click;
end;

{BOTÓN 2}

if key = 98 then
begin
btn2.Click;
end;

{BOTÓN 3}

if key = 99 then
begin
btn3.Click;
end;

{BOTÓN 4}

if key = 100 then
begin
btn4.Click;
end;

{BOTÓN 5}

if key = 101 then
begin
btn5.Click;
end;

{BOTÓN 6}

if key = 102 then
begin
btn6.Click;
end;

{BOTÓN 7}

if key = 103 then
begin
btn7.Click;
end;

{BOTÓN 8}

if key = 104 then
begin
btn8.Click;
end;

{BOTÓN 9}

if key = 105 then
begin
btn9.Click;
end;

{BOTÓN <}

if key = 08 then
begin
btnBS.Click;
end;

end;

{___________________________________________________________________________________________________ _________________________________________________________

--- EVENTO KEYPRESS ---
____________________________________________________________________________________________________ _________________________________________________________}

procedure TForm1.FormKeyPress(Sender: TObject; var Key: char);
begin

{VK_MULTIPLY}

if key = 106 then
begin
btnMultiplicacion.Click;
end;

{VK_ADD}

if key = 107 then
begin
btnSuma.Click;
end;

{VK_SUBTRACT}

if key = 109 then
begin
btnResta.Click;
end;

{VK_DECIMAL}

if key = 110 then
begin
btnComa.Click;
end;

{VK_DIVIDE}

if key = 111 then
begin
btnDivision.Click;
end;

end;
Como puedes ver ahí tengo bajo el evento keydown los números y el botón de borrar (<) y bajo el evento keypress los signos de operación (+, -, X, /, punto, etc). Pero bueno, si abres la calculadora de Windows y dejas presionado una tecla de operación el botón responde al evento keypress, simplemente no escribe nada, pero responde. Así que utilizo keydown para todos y controlo por código que no se escriba si ya está escrito y esperando otro número y no otra operación. De hecho con el evento keypress si bien cambia el comportamiento del botón también tendría que controlar que no se ingresase más de una vez, así que por ese lado no cambia.

Volviendo al tema de usar el identificador VK o el número, ¿sabes de qué manera podría usar el texto en vez del número?, porque coincido contigo que visualmente es mejor a la hora de leer. Por el momento como puedes ver más arriba le agregué un comentario.

Una vez más, gracias por tu ayuda.
Responder Con Cita
  #20  
Antiguo 23-07-2017
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
No me percate de que estabamos hablando de Lazarus

Acabo de hacer esta sencilla prueba y me funciona bien:

Código Delphi [-]
uses
  LCLType;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if Key = VK_NUMPAD0 then
     ShowMessage('VK_NUMPAD0');

  if Key = VK_MULTIPLY then
     ShowMessage('VK_MULTIPLY');
end;

Obvio que es necesario tener KeyPreview a True
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Opinión sobre la estabilidad actual de Lazarus/Free Pascal Toni Lazarus, FreePascal, Kylix, etc. 34 06-02-2016 02:04:45
Soy desarrollador de Delphi ¿Que necesito saber para usar Lazarus? Godzuki Linux 7 24-02-2012 00:54:34
Lazarus, Nemesis Pascal rmendoza83 Varios 1 08-01-2009 18:41:08
Indy soporta Free Pascal/Lazarus Delfino Noticias 6 15-01-2006 11:55:55
Free Pascal y Lazarus Magician^ Noticias 7 31-03-2004 20:12:04


La franja horaria es GMT +2. Ahora son las 00:38:06.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi