Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: petrusic - Ottobre 23, 2021, 07:56:58 pm

Titolo: [Risolto] tasto Shift+Tab in Tedit mi funziona male
Inserito da: petrusic - Ottobre 23, 2021, 07:56:58 pm
la sintesi del titolo non è chiara. Spero di spiegarmi meglio ora:
Nella Form2 che ho in manipolazione per ora ho disegnato alcune Tedit.
Ve ne sono due dove ammetto caratteri tipici. Nella prima delle due ammetto solo caratteri numerici, nella seconda ammetto solo 1 carattere (U/E).
Ebbene, mi si presenta un comportamento del programma, per me, strano:
Se sposto il cursore a prima di un carattere immesso e premo il tasto Canc, ecco cosa succede:
1.a Tedit: il carattere puntato dal cursopre NON si cancella.
2.a Tedit: l'unico carattere, puntato dal cursopre, SI cancella.
Riporto qui appresso il codice che ho scritto per gli eventi OnKeyDown sia per la 1.a Tedit, sia per la 2.a:


1.a Tedit:
Codice: [Seleziona]
procedure TForm2.EImportoKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  swTastoSi: Boolean = False;
begin
  if (char(Key) = '.') then
  begin
   Key:= Ord(',');
  end
  else begin
    case Key of
      VK_BACK, [b]VK_CANCEL[/b], VK_CLEAR, VK_DELETE, VK_END, VK_HOME, VK_LEFT, VK_RETURN, VK_RIGHT, VK_TAB, VK_LCL_POINT, VK_LCL_COMMA:
        begin
          swTastoSi:= True;
        end;
      else begin
        case key of
          VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9:
            begin
              swTastoSi:= True;
            end
          else begin
            if (char(Key) >= '0') and (char(Key) <= '9') then
            begin
            swTastoSi:= True;
            end
            else begin
              if (ssShift in Shift) and (key = VK_TAB) then
              begin
                swTastoSi:= True;
              end;
            end
          end;
        end;
      end;
    end;
  end;
  case swTastoSi of
    False:
      begin
        Key:= 0;
      end;
    else begin
      case Key of
        VK_LCL_POINT:
          begin
            key:= Ord(',');
          end;
      end;
    end
  end;
end;                             


2.a Tedit:
Codice: [Seleziona]
procedure TForm2.EsimbEUKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
    VK_BACK, [b]VK_CANCEL[/b], VK_CLEAR, VK_DELETE, VK_HOME, VK_LEFT, VK_RETURN:
      begin
      end
      else begin
        if (char(Key) <> 'e') and (char(Key) <> 'E') and (char(Key) <> 'u') and (char(Key) <> 'U') then
        begin
          Key:= 0;
        end;
      end;
  end;
end;                         

In entrambe viene testata la pressione del tasto |Canc|

 ??? ::) :-\ :-[
Titolo: Re:tasto Shift+Tab in Tedit mi funziona male
Inserito da: DragoRosso - Ottobre 23, 2021, 09:25:16 pm
Ehmmm
 char(46) => '.'
 VK_DELETE = 46

 ;)
Titolo: Re:tasto Shift+Tab in Tedit mi funziona male
Inserito da: petrusic - Ottobre 23, 2021, 09:57:19 pm
Ehmmm
 char(46) => '.'
 VK_DELETE = 46

Scusa, ma non capisco. Vuoi dire che ho sbagliato a citare il codice VK?
Io credevo che fosse VK_CANCEL. Invece è VK_DELETE?
Non vi ho fatto caso. In ogni caso, sia VK_CANCEL che VK_DELETE, sono presenti nel test di tutte e due le procedure KeyDown, tuttavia, funziona solamente nella 2.a.

Mi pare che non cambi niente.

Titolo: Re:tasto Shift+Tab in Tedit mi funziona male
Inserito da: DragoRosso - Ottobre 23, 2021, 10:03:33 pm
Codice: [Seleziona]
procedure TForm2.EImportoKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  swTastoSi: Boolean = False;
begin
  if (char(Key) = '.') then  //ANCHE VK_DELETE
  begin
   Key:= Ord(',');
  end
  else begin
     ....................
  end;
  //Nel caso di VK_DELETE qui swTastosi = false e quindi azzeri il KEY
  case swTastoSi of
    False:
      begin
        Key:= 0;
      end;
    else begin
      case Key of
        VK_LCL_POINT:
          begin
            key:= Ord(',');
          end;
      end;
    end
  end;
end;                             
Titolo: Re:tasto Shift+Tab in Tedit mi funziona male
Inserito da: petrusic - Ottobre 23, 2021, 10:46:28 pm
Si, l'ho trovato anch'io.
il problema nasce per effetto del codice
Codice: [Seleziona]
  if (char(Key) = '.') then
  begin
   Key:= Ord(',');
  end
Infatti, come hai rilevato tu, detto passo di programma precede il test sui codici VK e riconoscendo key= 46 come '.' (punto), viene modificato in ','(virgola). Il successivo case
Codice: [Seleziona]
case Key of
      VK_BACK, VK_CANCEL, VK_CLEAR, VK_DELETE, VK_END, VK_HOME, VK_LEFT, VK_RETURN, VK_RIGHT, VK_TAB, VK_LCL_POINT, VK_LCL_COMMA:   
non trova più key= 46. Trova invece key= 44 (',' - virgola), quindi il test non può funzionare.

Mi resta il compito di riconoscere il punto che,
- premuto nella tastiera alfanumerica, assume key= 190
- premuto nel tastierino numerico, assume key= 110

Per cui penso che dovrò modificare il passo iniziale così:
Codice: [Seleziona]
 if (Key = 190) or (Key = 110) then
  begin
   Key:= Ord(',');
   WriteLn('codice_carattere modificato= "' + IntToStr(Key) + '/' + char(Key) + '"');
  end                                         
. . .
case char(key) of
    ',':
      begin
        swTastoSi:= True;
      end;
  end;                       

Ho provato, ma non funziona nemmeno.
uffaaaaaaaaaaaa
Titolo: Re:tasto Shift+Tab in Tedit mi funziona male
Inserito da: DragoRosso - Ottobre 23, 2021, 10:51:56 pm
Scusa per le risposte succinte ma ero impegnato.

Per spiegarti meglio la cosa, a parte la modifica del tuo codice, dovresti conoscere la sequenza degli eventi alla pressione di un qualsiasi tasto:

1) Event OnKeyDown (o OnKeyUp) per ogni tasto;
2) Event OnKeyPress solo per i tasti che generano un carattere;

In OnKeyDown occorre filtrare tutti i tasti che non generano un carattere (CANC, BACKSPACE, ETC ...) , in OnKey Press invece si processano i caratteri ('0', '1', ',' , 'p', '+', etc ...) compresi CTRL-C, RITORNO A CAPO, ....

Anche se poni a zero il KEY in OnKeyDown, comunque viene generato OnKeyPress se il tasto premuto è un carattere ('p' ad esempio).

Questo è tipico di Windows, che genera due eventi (WM_KEYDOWM) e (WM_CHAR) nel caso il tasto sia un carattere.

Si possono così filtrare tutti i caratteri, che altrimenti in OnKeyDown  potrebbero non essere processati correttamente.

EDIT: BACKSPACE è un carattere  8)
Ciao
Titolo: Re:tasto Shift+Tab in Tedit mi funziona male
Inserito da: petrusic - Ottobre 23, 2021, 10:59:41 pm
Anche se poni a zero il KEY in OnKeyDown, comunque viene generato OnKeyPress se il tasto premuto è un carattere ('p' ad esempio).
Questo è tipico di Windows, che genera due eventi (WM_KEYDOWM) e (WM_CHAR) nel caso il tasto sia un carattere.

Ho capito. Proverò a modificare il codice seguendo i tuoi consigli. Comunque il mio SO. è Linux.
Titolo: Re:tasto Shift+Tab in Tedit mi funziona male
Inserito da: DragoRosso - Ottobre 23, 2021, 11:07:14 pm
Codice: [Seleziona]
procedure TForm5.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (key <> VK_DELETE) and (key <> VK_LEFT) then
   key := 0;
end;

procedure TForm5.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if key = 'p' then
    key := #0;
end;

Prova questo codice, vedrai che puoi premere solo i tasti CANC e FRECCIA A SINISTRA come tasti "speciali".... ma nonostante tu metta il key a zero i tasti carattere PASSANO  ;D

Non passa il invece il carattere 'p' ....
Ciao
Titolo: Re:tasto Shift+Tab in Tedit mi funziona male
Inserito da: petrusic - Ottobre 24, 2021, 05:27:37 pm
Si, ho risolto. Grazie per l'aiuto.
Distribuendo e distinguendo i controlli sui tasti speciali da quelli sui tasti carattere negli eventi OnKeyDown e OnKeyPress, ho raggiunto lo scopo. Ho faticato un pò col tasto '.'(punto) del tastierino numerico, ma alla fine si è arreso.  :D
Riporto, per completezza, il codice definitivo:
Codice: [Seleziona]

procedure TForm2.EImportoKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  swTastoSi: Boolean = False;
begin
  case Key of
    VK_BACK, VK_CANCEL, VK_CLEAR, VK_DELETE, VK_END, VK_HOME, VK_LEFT, VK_RETURN, VK_RIGHT, VK_TAB, VK_LCL_POINT, VK_LCL_COMMA:
      begin
        swTastoSi:= True;
      end
      else begin
        case key of
          VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, 110:    // 110 è il codice numerico del tasto "."(punto) del tastierino numerico
            begin
              swTastoSi:= True;
            end;
        end;
      end;
  end;
  case swTastoSi of
    False:
      begin
        Key:= 0;
      end;
  end;
end;

procedure TForm2.EImportoKeyPress(Sender: TObject; var Key: char);
var
  decimali, lun, p: Integer;
begin
  p:= Pos(',', EImporto.Text);
  if (Key = Char(46)) then
  begin
    case p of
      0:
        begin;
          Key:= ',';
        end
      else begin
        key:= Char(0);
      end;
    end;
  end
  else begin
    lun:= Length(EImporto.Text);
    if (p > 0) and (p < lun) then
    begin
      decimali:= lun - p;
      if (decimali >= 2) then
      begin
        key:= Char(0);
      end;
    end;
  end;
end;
Nel KeyPress ho gestito la virgola con la limitazione de caratteri decimali a due soltanto.
Titolo: Re:[Risolto] tasto Shift+Tab in Tedit mi funziona male
Inserito da: DragoRosso - Ottobre 24, 2021, 09:04:08 pm
Lo scan code del punto sul tastierino numerico dovrebbe essere codificato come VK_DECIMAL, ossia come scrivi tu 110.

Però testare quei tasti, ossia VK_Numpadx e VK_DECIMAL non serve in quel posto, perchè comunque "passano" che tu metta il key a zero o meno. Sono tasti che generano caratteri  e quindi non puoi filtrali in quell'evento.

Prova togliere il blocco dove li usi e vedrai che il risultato non cambia, almeno così dovrebbe essere. Visto che utilizzi Linux una conferma o una smentita farebbe comodo.

Ciao.
Titolo: Re:[Risolto] tasto Shift+Tab in Tedit mi funziona male
Inserito da: petrusic - Ottobre 25, 2021, 05:34:02 pm
testare quei tasti, ossia VK_Numpadx e VK_DECIMAL non serve in quel posto, perchè comunque "passano" che tu metta il key a zero o meno. Sono tasti che generano caratteri  e quindi non puoi filtrali in quell'evento.

Prova togliere il blocco dove li usi e vedrai che il risultato non cambia, almeno così dovrebbe essere. Visto che utilizzi Linux una conferma o una smentita farebbe comodo.

Purtroppo, nel mio caso, non è così, perchè il blocco
Codice: [Seleziona]
 case key of
          VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, 110:    // 110 è il codice numerico del tasto "."(punto) del tastierino numerico
            begin
              swTastoSi:= True;
            end;
        end;       
è subordinato all'esito del blocco
Codice: [Seleziona]
case Key of
    VK_BACK, VK_CANCEL, VK_CLEAR, VK_DELETE, VK_END, VK_HOME, VK_LEFT, VK_RETURN, VK_RIGHT, VK_TAB, VK_LCL_POINT, VK_LCL_COMMA:
      begin
        swTastoSi:= True;
      end
      else begin
        case key of
          VK_NUMPAD0, VK_NU. . .
il quale esclude tutti i codici tasto diversi  da " VK_BACK, VK_CAN. . .". quindi il successivo test su swTastoSi trova False e forza key=0 che non fa attivare la procedure KeyPress. Infatti, per effetto del codice scritto in KeyDown,   arrivano in KeyPress solo caratteri relativi alla pressione di soli tasti numerici, del tasto '.'(punto) e del tasto ',' virgola, come ho riscontrato in 4 giorni di prove e modifiche varie.  Credimi.

Anzi, in seguito a quest'ultima tua riflessione, ho riprovato ed ho riscontrato che i numeri immessi dalla tastiera alfanumerica non vengono riconosciuti, perciò dovrò riconoscerne i codici in KeyDown per fare passare pure quelli.