I'm new to Delphi and I've found some strange behaviors of Rad Studio XE3 code editor.
E.g., when i press the undo shortcut (Ctrl+Z), the editor does not undo just the last code editing, but also latest caret movements. I mean: when I open a unit and I browse through its code, it happens that I go clicking around, without editing the code. Well, if I press Ctrl+Z, the caret will move back to all points where I've been clicking before. I was expecting nothing to happen when I press Ctrl+Z, if no edit was performed!
There is a way to deactivate this feature?
I've CnWizards_1.0.0.638 installed.
Thanks.
You cannot disable that behavior completely, but you can reduce its effect. Turn on the group undo editor option. Then all consecutive cursor movements will be grouped into a single action. Other types of consecutive actions will be grouped together, too, but I don't recall that being an issue for me.
Moving the caret when performing undo of edit actions is very much by design. This is for sure not strange behaviour and all editors behave this way.
If the caret was not moved, and the window now scrolled, you would have absolutely no feedback that an undo event had occurred. For instance, the edit that you undo could perhaps be in code that is not currently visible. For sure in plain Delphi there is no way to change the behaviour and I'd be astounded if any plugin offered such functionality because it would render the undo functionality completely unusable.
Perhaps what you want to do is to undo some changes, and then return to where you were in the edit window before performing the undo operations. Well, the way to achieve that is to drop a bookmark, perform the undo, and then jump to the bookmark.
Related
I apologize in advance for this vague question but can anyone give me a pointer to this problem?
The Delete key does not work as normal in my application. e.g. The Delete key has no effect in an editbox (i.e. it will not delete highlighted text) but Shift Delete does work. This seems to be the case thoughout the application. I have disabled all keypreviews and OnKey events in case they were causing it but the problem persists.
Can anyone suggest where I might look for the problem?
Running Windows 10 Delphi 10.3.3
If this happens only in this particular application, it is likely that you have a TActionList or TActionManager with an action using Delete as its shortcut, or a simple menu item with such a shortcut.
For instance, you might have an Edit menu with a Clear item using Delete as its shortcut:
Then that action or menu item will respond to Delete, not allowing the focused control to do its own thing.
This kind of mistake is surprisingly common. For instance, in the Delphi IDE, you have an edit field above the editor, showing you the current class:
If you select this text and press Ctrl+C, you expect it to end up in the clipboard. But no! Instead, the selected text in the code editor (if any) is copied, even though the code editor didn't have keyboard focus.
I have an interesting observation and question, but first a comment. I have been using Delphi for 14 years and have taken a job developing an iOS mobile application using XE5. This is my first time using FMX and frankly I feel like I am stepping back in time many moons ago. In other words, if this is the future, then it feels like I have crippled. No problem though. Roll with the punches. Developing in this brave new world is not just a job. It is an adventure.
Now my question. Start a FMX mobile project using the "Header/Footer with Navigation" as your base. Then add an edit control (Edit1) to the first tab item. Then set the tab control align to none and move it to the right until you can clearly see the form itself. Then add an edit control (Edit2) to the form.
Now set the form's active control to Edit1 and run the app - no focus on Edit1. Now set the form's active control to Edit2 and run the app - focus is placed on Edit2. Interesting. Tab is a foreign word to tablets, right? Why have active control or even setfocus available? Is this an oversight by Embarcadero? Any thoughts?
Long story short I think they both have potential uses.
I use the SetFocus call to manually show the keyboard. Lets say the user navigates to a page where they're 100% sure to be putting in their username (or any text), I'll use ctrl.SetFocus to show the keyboard just to save them having to click (or is it press now?) on the edit.
I don't see ActiveControl being as useful, but it could definitely still be used. You could possibly use it to set up some sort of tabbing like structure for when the user presses Next on the keyboard (when the edit's ReturnKeyType is rkNext).
In Delphi XE, I use the rename variable refactoring (Ctrl+Shift+E) a lot of the time to make my code easier to understand by giving more meaningful variable names, for example:
That is all good but I have one slight issue regarding workspace when I use this. I like to keep the code messages etc pinned to the bottom, they only appear when I hover my mouse over them - this is my preference to allow more space for the editor.
Now, when I use the rename variable refactoring, the dialog has the checkbox: View references before refactoring as shown from the image above. I have this unchecked as I generally don't need to oversee what is been changed etc, if needs be I just undo it.
Here is my issue, with that unchecked I would of hoped for the refactoring to of performed silently, but no I still get the refactorings window showing up underneath:
It might not be considered a major issue but every time I have to manually close the refactorings window is just wasting time and is becoming a nuisance.
I noticed if you click on the refactorings tab in the editor there is an option to hide, but this is not permanent as it will come back the next time you refactor anyway.
Is there an option I may have missed somewhere to prevent the refactorings window from displaying in the code editor?
…to prevent the refactorings window from displaying in the code editor
How about moving it elsewhere? Undock it from the bottom of the editor window and dock it at a different place. (Unless you've hidden all the side panels.)
I encountered yet another problem with ribbon. When I have two forms (one of them is main) and I put ribbon on both of them, they behave strangely. When I open the second form by Form2.Show;, every time I click a ribbon menu button on the second form, it loses focus and the main form gets it.
This happens at pure blank project, so what could I possibly be doing wrong?
Here is a video, just in case: Watch YT
And to be clear, the Action1 button has only Caption:='a'; code.
The ribbon control assumes that there is only one per application, and misbehaves if it is not the only control. You could try to modify the Ribbon.pas code, but it is doing some hacks that probably rely on Ribbon.Parent being Application.MainForm only.
Question:
Can anyone point to an article or code samples anywhere on how to
provide BOTH editing AND range selection in a TStringGrid?
Yes, I KNOW there are third-party grids that do this, but it's
frustrating that the built-in grid lacks this basic capability.
Background:
It's pretty normal to expect to be able to both edit a cell in a grid,
and also to select a range of cells such as for a Copy operation.
As delivered, TStringGrid doesn't do that. It's either/or. In fact, the
docs tell us about the grid Options, "When goEditing is included in
Options, goRangeSelect has no effect".
However, it looks like it may be possible to do editing and rangeselects
in a TStringGrid anyway!!! Through careful use of the mousedown,
mouseup, selectcell and exit events, you can get dang close by switching
editing elements on and off at the right times. But I still don't have
it perfect, and that only covers mouse use, not keyboard changes.
I have not used the TStringGrid for this, so I can't provide a specific answer. But am I right in assuming you can manually (in code) start a cell being edited? That link implies it is possible even if the grid doesn't have goEditing included in its Options. (See below to work around this if this is not true.)
If so, I'd suggest the following approach:
Combined selection and edit behaviour
I find this is a good, Windows-standard-behaviour sort of approach:
Leave the grid in selection mode, so mouse and keyboard interaction selects cells
Trigger a cell being edited yourself, based on certain criteria (I think you are on the way to doing this from what you said in your last paragraph.) There are common ways to trigger editing, and the following criteria are what my programs follow when they do something similar with other controls:
Selection is normal. Ie, click to select, click and drag to multi-select, use the keyboard arrows and Shift or Control to select, etc.
A cell enters edit mode when either:
A cell is selected and the user presses Enter or F2 (F2 is the standard "Rename" or "Edit" shortcut, which works in a number of programs)
The user "slow-double-clicks" on a cell - ie, slow-double-clicks to select and edit, or clicks again, after a pause, on an already-selected cell. This mimics Explorer's behaviour, where if a file is selected and you later click on it, it enters the inline edit/rename mode. To implement this, record when a cell was last clicked (and selected.) If it is clicked again, and if the time is greater than GetDoubleClickTime then they have clicked twice, slowly, and enter edit mode. This allows you to distinguish between the first click to select, a double-click (to perform some kind of action), and a slow second click, to enter edit mode.
I also tend to check the mouse position, so that if an object is slow-double-clicked and it wasn't first selected (ie, this both selects the object and then enters edit mode) I verify the mouse hasn't moved very much. I use GetSystemMetrics to find the double-click distance, and check that the slow double click was within this box. (Because it's not a true doubleclick, I actually check the distance times 2. My action code is:
const int iMAX_MOVE_AMOUNT = ::GetSystemMetrics(SM_CYDOUBLECLK) * 2; (sorry, C++ not Delphi, but should be convertable easily enough!)
but I'm actually not certain if this is completely and utterly 100% to Windows guidelines. In practice users find it works as they expect, though.)
That should let you change between selecting and editing at the appropriate times with both the keyboard and the mouse.
Miscellaneous thoughts
You may find some of this is cleaner and easier to implement by subclassing TStringGrid and creating a new component. That will allow you to implement this in normal code and override the inbuilt behaviour (rather than event handlers) while keeping it invisible to the form code. It will also give you lower-level access to the mouse events or Windows messages than are exposed simply through events such as OnMouseDown. Finally, if there are problems with showing the editor when goEditing is included in Options, this will allow you to change that behaviour. You could also add your own events if you want your code to respond to certain things happening, such as creating an OnBeginEdit event, say.
Creating your own components is normally regarded as an advanced Delphi topic, but it's actually remarkably easy once you know how! This site has a few good topics that will introduce you to the subject in general, and if you go this route and encounter problems, Stack Overflow is of course a good place to ask questions :) The Embarcadero Delphi » VCL » Writing Components newsgroup / forum is also an excellent resource, in fact possibly even better than SO for this specific topic.
Hope that helps!
Yes it's old post, but the problem still exist on Delphi XE3.
To manage this feature I used next "trick" in SelectCell procedure :
if (ARow = StringGridParam.Row) then
begin
StringGridParam.Options:= StringGridParam.Options + [goEditing] - [goRowSelect];
end else begin
StringGridParam.Options:= StringGridParam.Options + [goRowSelect] - [goEditing];
end;