Forum > Linux
doubled keypresses register when there is a TMemo on a form
robert rozee:
i've encountered an odd behavior with a Lazarus/FPC application that may be worthy of further investigation. and to answer the obvious question - yes - i have found a (sortof) workaround.
the application is rather large, something that i've been developing and maintaining for a number of years. a few days ago i made a change to the main form's OnKeyPress handler that involved, when a certain set of conditions were met, changing the value of the variable Key (of type char) that is passed in. changing the value of Key was done for convenience, as there were a few dozen following lines of code that i didn't wish to edit; i could have equally well just used a locally defined variable called NewKey instead.
to my surprise, i now found that on those occasions when the value of Key was changed, the OnKeyPress handler would be called TWICE in quick succession. this made absolutely no sense, and i could not for the life of me figure out the cause!
a bit of research online brought up a smattering of postings on the web (going back some number of years) about similar things happening, but with no clear/definitive explanation or solution. however, several of the postings mentioned a possible connection with the form also having a TMemo on it. my application does have a TMemo on the main form, but normally this component sits hidden (Memo1.Visible=false, Memo1.Enabled=false). only occasionally is the component enabled, displaying some content that the user can select and copy to clipboard before being hidden again.
after much experimentation, i found that the double-keypress events (there were also matching double-keydown events) could seemingly be prevented by adding the following few lines of code into my application's startup code:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.ApplicationPropertiesActivate(Sender: TObject);const startup:boolean=true;begin if startup then // startup things that can/should not be performed until the main form is 'live' begin startup:=false; Memo1.Visible:=true; /////////////////////////////////////////////////////////////// Memo1.Enabled:=true; // WITHOUT these lines (in particular the SetFocus) we get // Memo1.SetFocus; // doubling up of Form1 KeyPress events. Have no idea WHY it // Memo1.Visible:=false; // happens, but the SetFocus prevents it! // Memo1.Enabled:=false end ///////////////////////////////////////////////////////////////end
note that, by design, on the main form of my application there are NO components that would normally have focus. also, while the above seems to work, i am not convinced that i have got to the bottom of the problem. the feeling i have is that it is a focus-related issue, but then when i tinker more with the code i'll sometimes find a fix that works, then when i rearrange the code it doesn't... then i'll go back to the original fix and it too doesn't work! needless to say, in my OnKeyPress handler i now do not change the value of Key - that seems to be the one way of (100% ???) avoiding the problem.
has anyone else encountered this sort of behavior? i'd be interested in hearing any theories that others may have. i must admit, few GUI applications would normally have no focused component, but then it is not unheard of. my OnKeyDown, OnKeyPress and OnKeyUp events are all triggered from the main form, while my mouse events are all triggered from a TPanel that covers the entire area of the main form (the panel then contains a TImage that the user interacts with).
cheers,
rob :-)
Thaddy:
Of course it makes sense. changing key triggers onkeypress again, since it is a change.
robert rozee:
--- Quote from: Thaddy on January 03, 2025, 03:09:39 pm ---Of course it makes sense. changing key triggers onkeypress again, since it is a change.
--- End quote ---
except:
* the second time round it passes in the original value for Key, not the updated one,
* if the TMemo is removed from the form the the OnKeyPress handler is not called a second time,
* if i start out with a blank form and drop a TMemo onto it, i can not duplicate the double-up behavior.if it were intended behavior, then it would surely be consistent?
addendum: further experimenting, and all i find is weird behavior! i think it is fair to say that if you do NOT have something like a TMemo on your form in a state that can 'receive' keypresses, then you should NOT go altering the value of Key passed into the OnKeyPress handler. also, using the feature to swap upper and lowercase characters over is not workable.
cheers,
rob :-)
robert rozee:
Thaddy, i think i have managed to put together a simple demonstration of at least part of what i am seeing.
i've created two identical applications, with but one key difference:
* the first application is just a blank form, with an OnKeyPress event handler.
* the second application has added to it a TMemo objectattached are .zip archives containing the source code for two applications.
the OnKeyPress event handlers are identical, and as follows:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.FormKeyPress(Sender: TObject; var Key: char);const mark:Int64=0;begin writeln(GetTickCount64-Mark:16, ord(Key):8, #9, '<', Key, '>'); Key:='@'; mark:=GetTickCount64end;
also attached is a screenshot showing the two applications running, after pressing the 7-key sequence "abcdefg" while the main form has focus.
the first application, that excludes the TMemo, produces the output:
856988796 97 <a>
232 98 <b>
248 99 <c>
832 100 <d>
936 101 <e>
288 102 <f>
192 103 <g>
the second application, that includes the TMemo, produces the output:
856995892 97 <a>
0 97 <a>
940 98 <b>
0 98 <b>
1656 99 <c>
0 99 <c>
392 100 <d>
0 100 <d>
271 101 <e>
1 101 <e>
284 102 <f>
0 102 <f>
252 103 <g>
0 103 <g>
* why is there a difference between the two sets of output?
* why is the value of Key that is passed in to the extra OnKeyPress events never '@' for the application that includes the TMemo?
* why is there no doubling-up of OnKeyPress events for the application that excludes the TMemo?
what i have not been able to create, so far, is a simple demonstration of a form containing a TMemo and that has no doubling-up of OnKeyPress events. i do have a complex demonstration - in excess of 5000 lines of code.
cheers,
rob :-)
Hartmut:
@robert rozee: which versions of FPC and Lazarus and Linux are you using?
Navigation
[0] Message Index
[#] Next page