Jump to content

Teclas de seta(readkey)


Go to solution Solved by nunopicado,

Recommended Posts

Posted (edited)

Olá, conheço o P@P a algum tempo, porém não tinha criado minha conta, sempre quis responder algumas pessoas mas também tenho minhas dúvidas, a minha dúvida é a seguinte, estou criando um Software cujo o nome é Lipïïnn Program ©, nele tem uma procedure chamada, janela1, e nesta janela1 certamente abre uma janela (feita em códigos ASCII claro) e nesta janela tem dois readkeys no caso deveria ter só um, mas se eu colocar só um ele confunde tecla com letra, como faço pra resolver isso? Obrigado desde já!

procedure janela1;
var
 ATUAL : INTEGER;
 Construtor_de_janela : integer;
 tecla : char;
begin
 gotoxy(20,5);

 for Construtor_de_janela := 1 to 30 do begin
     gotoxy(Construtor_de_janela + 20,5);
     write(#219);
 end;
 for Construtor_de_janela := 1 to 10 do begin
     gotoxy(50,Construtor_de_janela + 5);
     write(#219);
 end;
 for Construtor_de_janela := 1 to 30 do begin
     gotoxy(Construtor_de_janela + 20,15);
     write(#219);
 end;
 for Construtor_de_janela := 1 to 11 do begin
     gotoxy(20,Construtor_de_janela + 4);
     write(#219);
 end;
 window(21,6, 49,14);
 textbackground(blue);      //29 colunas, 9 linhas
 clrscr;
 gotoxy(2,2);
 write('Janela de pausa');
 gotoxy(2,3);
 write('Escolha uma opcao');
 gotoxy(2,4);
 write('com as teclas de seta');
 gotoxy(2,5);
 WRITE('Nao aperte outra tecla ');
 gotoxy(2,6);
 WRITE('A nao ser as de seta e ENTER (bug) ');
 cursoroff;
 window(38,13, 46,13);
 textbackground(blue);
 write('Desligar');
 gotoxy(3,9);
 window(25,13, 34,13);
 textbackground(white);
 textcolor(red);
 write('Continuar');
 tecla := readkey;
 tecla := readkey;
 repeat
  case tecla of
  #75 : begin       //Seta esquerda //#75 // #37
       window(25,13, 34,13);
       textbackground(white);
       textcolor(red);
       write('Continuar');
       window(38,13, 46,13);
       textbackground(blue);
       write('Desligar');
       tecla := readkey;
       tecla := readkey;
       atual := 1;
       cursoroff;
       end;
       {else
        gotoxy(2,6);
        window(21,6, 49,14);
        write('Incorrect Information');
        delay(500);
        janela1;}
   end;
   {if (tecla = #77) then begin}
   case tecla of
   #77 : begin                 //Seta direita //#77 // #39
      window(25,13, 34,13);
      textbackground(blue);
      textcolor(red);
      write('Continuar');
      window(38,13, 46,13);
      textbackground(white);
      write('Desligar');
      tecla := readkey;
      tecla := readkey;
      atual := 2;
      cursoroff;
    end;
   {else
      window(21,6, 49,14);
      gotoxy(2,6);
      delay(500);
      write('Incorrect Information');
      janela1;}
   end;

 until(tecla = #13);
 case tecla of
 #13 : begin
     if (atual = 1) then begin
         clrscr;
         window(1,1, 80,1);
         textbackground(lightcyan);
         highvideo;
         clrscr;
         window(1,1, 80,25);
         gotoxy(2,2);
         textcolor(lightblue);
         textbackground(black);
         cursoron;
         piboaritiboyet3;
     end;
     if atual = 2 then begin
        clrscr;
        halt;
       end;
     end;
 end;

end;
Edited by nunopicado
Adicionada linguagem de Highlight

Brenio Hallison A.M. Filho

 

Posted

As teclas de setas, bem como algumas outras teclas especiais, têm um prefixo, o que as força a precisar de 2 readkeys para as poderes usar.

No caso do teu código, se só lá tiveres um readkey, a variável 'tecla' irá guardar apenas o prefixo, no caso dessas teclas especiais.

Esse prefixo é o caracter #0 (nulo).

Assim, para usares a seta esquerda, tens de ler o readkey 2 vezes, uma para o prefixo e outra para o código da tecla, que é um código ASCII também, e geralmente equivale a uma letra.

O que deves fazer, em vez de leres simplesmente o readkey 2 vezes (pois isso trava o teu programa caso o utilizador toque numa tecla normal, e não numa especial, inclusivamente o próprio enter #13, que é uma tecla normal) é:

1. Ler o readkey

2. Testar se o valor é #0.

Se for, voltas então a ler pela segunda vez o readkey, e avanças para o case.

Se não for, terás de decidir o que o teu programa faz quando uma tecla errada é pressionada (por exemplo, ignorar a entrada e voltar ao inicio do repeat).

Resumindo: Só lês o readkey pela segunda vez se da primeira o seu valor for #0.

Alguma dúvida, apita. 😉

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Posted (edited)

Bom, neste caso eu teria que colocar assim no meu código?

if tecla = #0 then begin

repita; //procedure para verificar se as teclas de seta foram pressionadas

else

erro1; //essa procedure que coloquei ao lado diz que a tecla digitada foi incorreta e volta a procedure atual

end;

Edited by BHAMF

Brenio Hallison A.M. Filho

 

  • Solution
Posted (edited)

Olhando para o teu código:

1. O readkey tem de estar dentro do repeat, para que o user possa ir carregando nas setas até terminar carregando em enter (é essa a ideia, certo?)

2. A primeira coisa dentro do repeat é o tecla := readkey.

depois teclas como if, como puseste, e no then do if, metes a segunda leitura do readkey e o case que controla as teclas.

3. Estás a usar mal o case. não tens de meter case para cada opção. Simplesmente vais colocando as opções, e metes o end do case apenas no final de todas as opções.

4. Depois de leres um prefixo do código de teclas especiais, não precisas voltar a ler para a variável. Podes, se quiseres, usar o readkey directamente no case.

Isto é opcional, não há problema nenhum em ler para a variável se preferires.

5. Depois do until, não precisas de meter ali aquele case. Primeiro porque quando o programa aí chega, é por que o user carregou no enter, pelo que não precisas testar nem com case, nem com nada. Segundo porque não precisas nunca usar um case se só há uma opção a testar (ver ponto 3).

Assim, ficaria algo deste género:

  textcolor(red);
  write('Continuar');  
  repeat
  tecla := readkey;
  if tecla = #0 then  
	 case readkey of  // quando chega aqui é porque já leu o prefixo, pelo que podes testar directamente o restante código
		#75 : begin	   //Seta esquerda //#75 // #37
				 window(25,13, 34,13);
				 textbackground(white);
				 textcolor(red);
				 write('Continuar');
				 window(38,13, 46,13);
				 textbackground(blue);
				 write('Desligar');
				 atual := 1;
				 cursoroff;
			  end;
		#77 : begin				 //Seta direita //#77 // #39
				 window(25,13, 34,13);
				 textbackground(blue);
				 textcolor(red);
				 write('Continuar');
				 window(38,13, 46,13);
				 textbackground(white);
				 write('Desligar');
				 atual := 2;
				 cursoroff;
			  end;
	 end;
  until (tecla = #13);

  case atual of   // a variável 'atual' tem aparentemente 2 opções, pelo que podes usar o case para esta verificação
  1: begin
		clrscr;
		window(1,1, 80,1);
		textbackground(lightcyan);
		highvideo;
		clrscr;
		window(1,1, 80,25);
		gotoxy(2,2);
		textcolor(lightblue);
		textbackground(black);
		cursoron;
		piboaritiboyet3;
	 end;
  2: begin
		clrscr;
		halt;
	 end;
  end;
end;

Nota que não testei o teu código, pelo que não sei se as minhas alterações fazem exactamente o que precisas. Mas dá para teres uma ideia de como deves proceder para lá chegar!

Outra coisa:

Começa a indentar correctamente o teu código. Quando não o fazes, estás a dificultar a vida a ti próprio e a quem te precisar avaliar/ajudar.

Um código correctamente indentado é metade da ajuda que vás precisar para qualquer problema! 😉

Edited by nunopicado
  • Vote 1

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Posted

Obrigado nunopicado, meu Programa, graças a ti, chegará a versão 1.5.2 😄 se quiseres o código fonte inteiro só pedir por aqui, se não podes fechar este tópico. Obrigado por tudo 🙂 ))))

Brenio Hallison A.M. Filho

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.