26. juli 2005 - 13:58Der er
13 kommentarer og 1 løsning
ASCII genvejskombinationer f.eks. CTRL+H
Jeg har opdaget, at tastekombinationen CTRL+H bliver i TEdit og TMemo opfattet som BACKSPACE. Og der er flere af den slags genveje - CTRL+M og CTRL+J svarer til henholdsvis "Carriage Return" og "Line Feed" - de bliver begge "oversat" til et linieskift i en TMemo.
Kan man ikke få ens program til at ignorere dem ?
Jeg har prøvet dem i Notepad - CTRL+M og CTRL+J virker som linieskift, men CTRL+H får en "Replace" dialogboks frem.
Jeg bruger formens OnKeyDown til at slå hints til og fra (v.h.a. CTRL+H kombinationen). Og jeg har to editbokse på formen. Hvis en af dem har fokus, når jeg trykker CTRL+H, bliver det opfattet som BACKSPACE.
Input til de to editbokse bliver håndteret i deres respektive OnKeyPress events. Jeg har prøvet at sætte et flag i formens OnKeyDown, når der bliver trykket CTRL+H, for at signalere, at det ikke er et BACKSPACE. Flaget bliver fanget i editboksens OnKeyPress og bliver behandlet korrekt - resten af koden bliver ikke udført. Men derefter forsvinder der alligevel et tegn fra editboksen.
Der er en Var parameter som man kan sætte til #0 jeg mener at huske den heder Key, det plejer at virke, f.eks. kan man fjerne bip-lyde på den måde, eller kan du måske smide en emtpy keybuffer msg. kan ikke lige huske hvad den hedder, men der findes en windows msg. der tømmer keyboardbufferen
Slå keyprewiev til på din form og check i OnKeyPress, hvilken tast, der er trykket på. Her kan du også fjerne uønskede taster. I nedenstående procedure fjernes alle tastetryk, der ikke er bogstaver, tal eller et mellemrum.
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char); begin if ord(key)<32 then key:=#0; end; Du kan så heller ikke lave linieskift i en memo. Hvis du ønsker det, skal du "åbne" for #13 og #10
procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); const VK_H = 72; begin if (Shift = [ssCtrl]) and (Key = VK_H) then ReplaceDialog1.Execute; end;
Jeg ville gerne have givet nogle point ud, men desværre fik ingen af svarene mig nærmere en løsning. Pointen var at jeg vil stadig tillade almindelige BACKSPACE, men CTRL+H har jeg givet en ny funktion, så den skulle ikke slette noget i mine editbokse. Det, jeg allerhelst ville have, var en universal løsning (f.eks. et compiler direktiv), som deaktiverede alle de obskure/gammeldags tastekombinationer.
Jeg har arbejdet lidt videre med min egen model. I formens OnKeyDown event checker jeg på CTRL+H kombinationen :
if (i_key in [72, 104]) and (ssCtrl in t_shift) then b_IgnoreKey := True;
I formens OnKeyPress event kontrollerer jeg, om flaget er blevet sat :
if b_IgnoreKey then begin c_key := #0; b_IgnoreKey := False; end;
Når jeg sætter Key til #0 i formens OnKeyPress event, bliver editboksens OnKeyPress slet ikke udført. Hvis jeg i stedet (som jeg fejlagtigt gjorde før) bare kaldte "Exit", når jeg stødte på mit flag, ville Key stadig være #8, og jeg ville stadig miste et tegn. Og det uanset, om "Exit" blev kaldt i formens eller i editboksens OnKeyPress event.
type TForm1 = class(TForm) Memo1: TMemo; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Memo2: TMemo; Memo3: TMemo; ComboBox1: TComboBox; procedure Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormCreate(Sender: TObject); private procedure ApplicationMessage(var Msg: TMsg; var Handled: Boolean); public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ApplicationMessage(var Msg: TMsg; var Handled: Boolean); const VK_H = 72; var ActiveControl: TWinControl; ShiftState: TShiftState; KeyState: TKeyboardState; begin case Msg.Message of WM_KEYDOWN:
case Msg.wParam of VK_H: begin GetKeyboardState(KeyState); ShiftState := KeyboardStateToShiftState(KeyState); ActiveControl := Screen.ActiveControl; if (ActiveControl is TCustomEdit) or (ActiveControl is TCustomComboBox) and (ShiftState = [ssCtrl]) then begin Msg.wParam := 0; Handled := True; //Handled true eller false ? Se note !! end; end; end; end; end;
(* NOTE : Skal Handled sættes true eller false ? Det kommer helt an på hvor du ønsker at håndtere di tastetryk ?
Hvis du ønsker at der skal komme et onKeydownEvent på din kontrol, når du trykker CTRL + H så skal handled sættes false. Dog skal du så være opmærksom på at den key der kommer ind er 0 (ZERO) og ikke 72 som ellers er Key koden for H
Hvis du ønsker at håndtere dit CTRL + H oppe i ApplicationMessage() så skal Handled sættes true. Men så kommer der ingen taste tryk til din kontrol (Hvis du trykker CTRL + H) *) procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin
end;
procedure TForm1.FormCreate(Sender: TObject); begin Application.OnMessage := ApplicationMessage;
Lige en lille kommentar - hvis man i Notepad bruger SHIFT+CTRL+H, så opfatter den det som BACKSPACE ... Derfor plejer jeg at bruge
if ssCtrl in ShiftState then
i stedet for
if ShiftState = [ssCtrl] then
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.