I am working on a component in Delphi 7 and Delphi 2006, where I am using a unit which I need to add to the .dpr file of the project on which the component is dropped automatically.
Like the way Eureka Log automatically adds the unit 'ExceptionLog' to the project file:
Can anyone tell me how to programmatically add a unit to the project file when I drop my component on any form in the project?
You most likely have to use the Open Tools API for that.
Also it might require to write a TSelectionEditor for your component to trigger the adding of the unit (I would try the RequiresUnit method).
While there is an easy way to just add a unit to the active project (code below) this just works for the active project which might not be the project the form belongs to you are adding the component to. Also it adds the unit at the end of the uses clause.
uses
ToolsAPI;
var
currentProject: IOTAProject;
begin
currentProject := GetActiveProject();
currentProject.AddFile('MyUnit.pas', True);
You can check the GExperts source code because it contains a class (TUsesManager) that can parse units and modify the uses clause.
Odd.
I used to set my default dpr to contain next to nothing as a result my toolbox was very empty. So if it was in my toolbox it was in the dpr - what are you having problems with - normally if its in the toolbox, its already in the dpr.
go Project > Eurekalog Options and disable Eurekalog.
Related
I want to import an unit to save ini files with this unit from Github, but, as soon as i import it, code insight stops working - instead of opening itself doesn't even open anymore. It isn't a change in the IDE options, as it works in every unit/project in which i don't use it. So, the line
Uses: [...], FMX.IniFile;
Seems to deactivate Code Insight. I use Rad Studio 10.3. Is this a known issue or does a solution already exists?
Thanks
Edit: In order to use the file correctly, i need to import the files for android and Apple as well, which are in the same directory as the main FMX.IniFile.Pas, these might cause the problem as well
Sorry, I just tried what you describe in your q and code completion continues to work fine.
Here's exactly what I did:
Created a new multi-platform application.
Saved the default new Form1 unit the IDE creates and the project.
Created a new unit and cut and pasted the source of FMX.IniFile into it.
Saved the new unit in the project's folder under the name FMX.IniFile.Pas
Added FMX.IniFile to Form1's unit's Uses clause.
Added a TButton to Form1 and did a Save All
Created a `Button1Click' event on Form1.
Switched from the form editor to the code editor and, in the Button1Click handler skeleton and started to type
Self.c
and the IDE immediately offered the various properties of Form1 beginning with c as code-completion possibilities.
I'm using Delphi 10.2.3 on Windows 10 Pro 64-bit.
When i create a new service, then this service will have a main datamodule (DM), and when i add this service to an already existing app, then delphi automatically add to the dpr (in the uses clauses) of this app the unit of the datamodule:
uses ...
...
myService_mainunit;
why ? it's also make after not possible to compile under IOS ...
The IDE has absolutely no idea what your intentions are. It has no clue that you only want to use this for Android, regardless of if it's Android-specific code or not. You have to write the code which tells it this, such as using conditionals.
When you created a new Android Service, the IDE set up a pre-made template for you. This template just happens to use a Data Module to do its work. But when you add the Data Module to a project, the IDE simply does not know why you want to add it. It's just doing its job, it does this for any and every unit you add to your project, regardless of what that unit's purpose is. In fact, there is no such thing as adding a unit to your project and not being in the DPR uses.
"it's also make after not possible to compile under IOS"
Again, this is easily resolved by wrapping platform conditionals around it. Of course, the IDE "takes control" of the DPR file, so perhaps not that easily, as the IDE could malform your code. It is however very possible by not including this Data Module in your project, but place it in a location where your project can find it.
In my Firemonkey multi device project the IDE keeps adding the unit "FireDAC.VCLUI.Wait" to my uses in a data module of my project.
This unit keeps me from building the project, because it can't resolve the name in Android or iOS. The strange thing is that it previously didn't do this and I haven't added/changed anything to this data module.
I know some component add units to the uses but as I said it's a firemonkey project not a VCL project so it shouldn't add this.
How can I keep the IDE from adding this unit?
Place a IFDGUIxWaitCursor component on your data module and set its Provider property to 'FMX' (FireMonkey).
Remove that unit from the uses section, so the IDE will now set the one corresponding to Firemonkey instead of VCL.
Note: If the Provider property changes its value, then developers need
to delete the implementation units for the old Provider value from the
uses sections. For example, switching from 'Forms' to 'FMX' requires
to delete the TFDGUIxFormsXxx units.
You can set the "Provider" property to "Console", if you compile it for Linux.
I have some forms inherited from a TMyForm (TMyForm is a 3rdparty component with source code form).
When I open in the IDE my forms inherited from TMyForm I have:
Error creating form: Ancestor for
'TMyForm ' not found.
The workaround is to open the TMyForm unit in the IDE and then try top open my inherited forms.
But how can I avoid that Delphi gives this error and is able to open my forms even if TMyForm is not opened in the IDE?
You need to have the parent form opened in the IDE or added to the project, there's no workaround, unfortunately. Over here: Register custom form so I can inherit from it from multiple projects, without copying the form to the Object Repository folder I attempted lots and lots of things, without success.
My Workaround. There are several ways:
Add to project full path to all of the parent form. Uncomfortable, because of absolute path
Add package with parent forms to the project list. In this case, no problems there. But every time it is necessary to open a components
in the delphi environment.
Use a temporary solution from embarcadero.
There is automatically opens all the child forms:
Ticket, was created about 10 years ago: http://qc.embarcadero.com/wc/qcmain.aspx?d=8376
Here you can download the version for Delphi XE2: https://bitbucket.org/hemn/autoopenunit
I recommend it!
I've been searching all over for a solution to this and it seems I've finally found one.
I'm using a package with several base forms and frames.
I've added these to the repository, yet still the error came up.
Some of the forms and frames didn't show a 'dfm' in the Project Manager, it seems key to this, is to edit the .dpr file and add the name in curly brackets:
fIBSConnectionForm in 'GUI\BaseGUI\fIBSConnectionFrom.pas',
into
fIBSConnectionForm in 'GUI\BaseGUI\fIBSConnectionFrom.pas' {frmIBSConnectionForm},
and for frames, make sure to use {f...: TFrame}
After doing this and restarting Delphi, I could open descendant forms again!
I have a class in a unit. Usually, when I changed the algorithm of its methods, I have to recompile it and deliver the patch as a whole.
I think to create the instance of the class using DLL. After searching in delphi.about.com, I found that instead of using DLL, I can use BPL. It is a DLL for Delphi. The problem is almost all examples I found is only telling how to export a function.
I want to dynamically load the BPL, and whenever I replace the BPL, I can get the latest algorithm of the class, not only the functions I export.
Article I have read:
- http://delphi.about.com/od/objectpascalide/a/bpl_vs_dll.htm
- Plugins system for Delphi application - bpl vs dll?
- http://delphi.about.com/library/weekly/aa012301a.htm
Any URL or SAMPLE how to create a BPL from scratch to encapsulate a component or a class is greatly appreciated.
Dear Guru,
Suppose I have code like this:
unit unitA;
interface
type
B = class(TObject)
public
procedure HelloB;
end;
A = class(TObject)
public
function GetB: B;
function HelloA: String;
procedure Help;
end;
implementation
uses
Dialogs;
{ B }
procedure B.HelloB;
begin
ShowMessage('B');
end;
{ A }
function A.GetB: B;
begin
Result := B.Create;
end;
function A.HelloA: String;
begin
Result := 'Hello, this is A';
end;
procedure A.Help;
begin
//do something
end;
end.
I want to export all public methods of A. How to make it a DLL?
How to use it from another unit where to import it?
let's say:
var a: A;
a := A.Create;
a.GetB;
showMessage(a.HelloA);
A is not declared in the unit (it is in the DLL).
Please advise.
Hurray. I got it last night. All I have to do is make the object implement an interface which is used in the caller unit to catch the instance of object returned by the DLL.
Thank you all.
Mason nailed it already, but let me elaborate on why BPLs aren't what you are looking for.
BPLs are a means for the Delphi IDE to load components that share the same memory manager and RTL. (Type identity works almost transparently using BPLs)
However, the dependencies you are getting tied up in are almost always unacceptable. Except for the IDE, which cannot handle different versions of RTL and VCL anyway.
When you pass only interface references between your application and its DLLs, then you don't have to share RTL, VCL or shared packages at all.
It also means that you could write some DLLs in another language (C++, C#, FPC, another Delphi version), and still use objects. Which can be tempting when you don't want to port your main app but still want to use existing libraries that are not available for Delphi, or your version of Delphi.
The problem with putting a class in an external file is that your main application needs to know some way to refer to it. It will either have to descend from a base class that exposes all the methods you need as virtual methods, or implement an interface that contains all the functionality you need from it.
If you already know what the interface of the object should look like, and all you're changing is implementation details such as internal algorithms, probably the easiest thing would be to make your class implement an interface and put it in a DLL that exports a function that returns an instance of this interface. That way you don't need to worry about breaking your app up into packages, which can be a real hassle.
I see nothing in your problem description suggesting you would need to explicitly export anything from the package or that you would need to load it dynamically at run time. Instead, it's enough that your functions reside in a run-time package that can be replaced separately from the main program.
Start a new package project and move your class's unit into that project along with any other units it depends on. Compile the project. If the compiler warns about "implicitly including" any other units, add those to the package, too.
Now, remove any of the package units from the EXE project. There should be no units that are members of both projects. Next, turn on the "build with run-time packages" checkbox in your EXE's project options. Add your package to the semicolon-separated list of package names. The RTL and VCL packages will probably also be on that list.
Compile both projects, and you're done.
If you make changes to your class implementation, you can recompile the package only and send a new version to customers. The program will automatically get the new changes when you replace the original file with the new one. The package is listed in the program's import table, so the OS will automatically load the BPL file when it loads the EXE. The EXE doesn't need to run any special code to load the package.
Delphi can create DLL to export functions or BPL to export component.
You can create component, compile it (use the same compiler settings as in your main app), and Delphi will create .bpl. Then import this component to Delphi and compile your app with this compomponent as a package.
My experience with components created with Delphi 4 proved that one, big application is more reliable than application with separate .bpls. It was multithreaded server and it worked fine if compiled standalone, while crashed after short time if compiled with packages. I hope newer versions of Delphi improved in this area.
Be aware of memory management (in app do not free memeory allocated in package and vice versa) and compiler settings.
If you like about.com then this link will be useful: Introduction to Packages; BPLs are special DLLs!
BPLs have their usage. For example if you have to make a very huge application like an Erp, you need to try to use BPLs seriously.
In the other hand, BPLs aren't responsible of crashing applications. Bad usage of BPLs does it.
you can try the MAF Components, they handle plugins and much more for you without extra code. Comes with tutorials and a demo application with source.
http://www.maf-components.com