How to activate 'Variable completion' feature in Delphi? - delphi

There is a 'Variable completion' feature in Delphi XE?
I ask because I know there are lots of hidden or semi-hidden features (like the possibility to change the execution point when you are in debugging mode) in Delphi.
Example: http://wiki.freepascal.org/Lazarus_For_Delphi_Users#Example_for_Local_Variable_Completion
That I want to achieve:
When I need a new variable in the middle of a procedure, I don't want to go back at the top of the procedure to declare it and then go back in the middle of the procedure. So, it is not that I am lazy in copy/pasting the variable name but that I am disturbed in the middle of the 'creative process'.
I think this tiny feature will be a gigantic improvement to Delphi and to our efficiency.

There is something similar in the Refactoring menu. You have to select the variable to declare first and then hit Ctrl-Shift-V. In the following dialog you can accept the type suggestion or change it to your needs.
More information can be found here: http://docwiki.embarcadero.com/RADStudio/XE/en/Declare_Variable_and_Declare_Field_Overview_(Delphi)

There's a template available that will add the variable declaration somewhat automatically, but it does have some issues. Type var in your code and press Ctrl+J:
begin
var(Ctrl+J)
end;
This produces the following in the Code Editor:
Enter a name for the variable, Tab, enter a type for the variable, Tab adds the variable declaration at the top of the current procedure or method. For instance, adding an integer variable named Idx produces
with the text cursor immediately below the g in begin (with my IDE settings of 2-space indentation).
The drawback is that it doesn't automatically type the variable name on the line where the text cursor is located, meaning you have to type the name again (or at least start typing and use Code Completion to finish) in order to use it.

Related

Delphi TEdit in iOS - turn off auto-caps on a per TEdit basis

Currently, the iOS TEdit when it brings up the Keyboard, will have the keyboard in Caps for first letter.
I would like to turn off Keyboard auto going into Caps for first letter for specific TEdit.
Some TEdits I would want to retain first letter as capitalized, eg Names.
I can't use the TEdit.CharCase feature as it forces all input in TEdit to lowercase.
What I want is that user can Type in Mixed Case if they choose to but the Keyboard has to be in lowercase when TEdit first comes into focus.
How do I do this in Delphi 10.4.1?
You can control the default behavior of virtual keyboard by changing the KeyboardType property.
The KeyboardType property controls both the visual look of the virtual keyboard so that it is the most suitable for expected input (text, URL, phone number, etc.) as well as whether some advanced features like Spelling, Word Completion, or even Auto Correct which can automatically correct spelling errors or make sure that words at the beginning of sentence start with Capital letter.
I believe in your case you would like to use Alphabet KeyboardType instead of the Default.
One possible way to solve this is to:
Create a unit with a Boolean reference (or add to an existing unit) that is exposed publicly, e.g:
unit iOSPatch;
interface
var
DisableAutoCapitalization: Boolean;
implementation
end.
Create a copy of source\fmx\FMX.Platform.iOS.pas and put it in the project compile path (such as the project folder)
Modify the copy of FMX.Platform.iOS by adding the unit name from the first step to the implementation uses clause, e.g.:
implementation
uses
iOSPatch,
System.Classes, System.SysUtils, System.Types, System.UITypes, System.TypInfo, System.Messaging, System.RTLConsts,
// ... rest of uses clause snipped
Modify the TFMXViewBase.autocapitalizationType method to look like this:
function TFMXViewBase.autocapitalizationType: UITextAutocapitalizationType;
begin
if DisableAutoCapitalization or FPassword or not (FKeyboardType in [TVirtualKeyboardType.Default, TVirtualKeyboardType.Alphabet, TVirtualKeyboardType.NamePhonePad]) then
Result := UITextAutocapitalizationTypeNone
else
Result := UITextAutocapitalizationTypeSentences;
end;
Use the OnEnter event of every edit to set DisableAutoCapitalization to True/False depending on your needs
Alternatively, if you want it to apply to all edits regardless, you could modify TFMXViewBase.autocapitalizationType to set Result to UITextAutocapitalizationTypeNone and ignore the first step.
Unfortunately I can't test this right now as something has gone haywire with deployment on my machine
EDIT
I've managed to solve my deployment issue, and tested the code above, which works. Slight side-effect: the Shift button on the VK appears as "pressed" briefly

How to find component in design time easily

I am adding some functionality to form not created by me. It has loads and loads of buttons and I would like to test if everything works by clicking on the button which executes the code I added. I know the name of this button, but I don't know it's position on the form.
For now I scroll through all components of the form looking for this button. If I miss it in the first lookup, I have to start over. It's tiresome and takes a lot of time.
Is there easy way? Something like "Find component" menu item, which would bring me directly to that button (or label, or anything really).
There is no built-in, comfortable way of locating components on a form (even in Delphi Tokyo). But you can search and select component in the Object Inspector Instance List combo box:
Or perform inremental search in the Structure View's tree:
Or install some 3rd party IDE tool. For example CnWizards toolset has the Locate Components in Designer tool (which is what you're looking for, I guess):
While no help at design-time, if what you want is testing your code you likely do that at run-time:
TComponent has the function FindComponent that returns a TComponent owned by the calling component with matching Name.
As you know the name, to write test code you could use it like this:
var
AButton: TButton;
begin
AButton := Form.FindComponent(Button_Name) as TButton;
AButton.Click;
end;

How to go to definition of method or procedure in Delphi 7?

How to go to definition of method or procedure in Delphi 7? If ctrl key + mouse-click, it goes to the method declaration. I want it to go to the actual method instead, similar to "go to definition" in Visual Studio.
Update:
I want to jump to where proc2's code is defined.
procedure proc1
begin
proc2
end
It's a two-step process:
Ctrl+click the identifier you want to navigate to. That will take you to the declaration (as you've already observed).
Once the cursor is on the declaration, press Ctrl+Shift+↓ to navigate to the corresponding definition.
You can press that key combination again to go back to the declaration. (The up and down arrow keys are equivalent in this keyboard shortcut; it doesn't actually matter whether you want to navigate up or down within the file.)

How can i work RegisterClass() to units

Base from the anwser How to eliminate variables... i get and accepted it works great when i have all this components and make the actions like a button1.click from the main form...
But i use to make the actions from units... so
When i click a button i great a procedure DoMaths(Sender: TObject);
procedure Tform1.DoMaths(Sender: TObject);
begin
if TButton1(Sender).hint := 'Make the standard Package' then
do_Maths_standard_package;
end;
the do_Maths_standard_package is in unit ComplexMaths.
is the procedure do_Maths_standard_package form unit ComplexMaths it calls some components form Form1... like Form1.label1 etc...
So when i call the RegisterClass(TLabel) and erase the Tlabel from the type it gives an error that it cant find the Label1...
Please can someone help me so not to do the hole program from the start...
Thank you..
You might be able to reference your components like this:
TLabel(Form1.FindComponent('Label1')).Caption := '...';
TCheckBox(Form1.FindComponent('CheckBox12')).Checked := False;
But it's really a pain...
I think you have two options.
1) you can assign each component a unique numeric ID.
And save it into .Tag property.
Just like u use to generate and bind IDs in .HelpContext properties.
Then to get the control by number you would enumerate Form.Controls and get the one with proper Tag value.
The problem would be to have two separate ID lists, in PAS files and DFM files, in sync. Mistyping would be hard to notice. Especially since you have no constants in DFM but only "magic numbers".
2) Set .Name property and use iMan Biglari's recipe - FindComponent by name.
The question is if you can have .Name but not variable. Since no one answers - just try and see.
To my experience - with Delphi 5, hopefully D7 is mostly the same - you can just delete the variable.
If you made wrong declaration of variable, then Delphi editor would notice and ask to correct it.
If you have variable without DFM object, Delphi would notice it and ask to remove it.
But if there is DFM object without corresponding variable, then Delphi editor is oblivious. Maybe it thinks that the object is inherited or whatever.
But if you did not declare it at all it does not mind.
However, since you deleted Names, it looks like it is not possible to you for some reason.
In both cases you would have to cache value if some procedure makes a lot of accesses to some control. And maybe even across the procedures. In effect yu would manually restore those variables at least for most used controls.

Setting Up Event Handler in Delphi 2007 and Getting "Parameter Lists Differ" Error

I'm trying to write a class in Delphi 2007 that uses a ActiveX library. The class will catch an event that the ActiveX library has to expose its own event that adds some information to the ActiveX library's event.
The bottom line is that when I assign my own procedure to the ActiveX library's event that I want to use, I get an error:
E2009 Incompatible types: 'Parameter lists differ'
I'm certain the parameter lists are the same (same number of parameters and same types) so I'm thinking I'm going about it the wrong way.
Any suggestions or can someone post some sample code of what I'm trying to do?
The first thing to check is that the thing you're trying to assign to the event property is a method. It needs to be a procedure or function that belongs to a class; it can't be a standalone subroutine.
Next, note that merely confirming that the names of the types match isn't enough. Delphi allows redefining an identifier, so the type name you see in one unit isn't necessarily referring to the same thing when you see the same identifier in another unit. The meaning can even change in the middle of a unit. For example:
unit Example;
interface
uses Windows;
var
foo: TBitmap;
implementation
uses Graphics;
var
bar: TBitmap;
end.
The foo variable has type Windows.TBitmap, a record type, whereas bar has type Graphics.TBitmap, a class type.
You can let the IDE help you diagnose this: Ctrl+click on the identifier names and let the IDE take you to their declarations. Do they take you to the same places? If not, then you can qualify the type names with the unit names. For example, we could change the bar declaration above to this:
var
bar: Windows.TBitmap;
Now it will have the same type as foo. Check for the same sort of thing in your event-handler declaration.
I used gabr's advice with the Ctrl+click and discovered that one of the parameters was a constant which I did not realize. I changed the second variable to a const and it worked fine. Thanks.

Resources