VCL-Styles embedded in dll? - delphi

How do I embed Delphi XE2 VCL-Styles in a dll? The Application - Appearance page is not visible in project settings for DLL-projects.
I tried defining them in a rc-file included with a $R directive which works but if there is a better way I'd like to know.
RC-file example:
GOLDENGRAPHITE VCLSTYLE "C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\Redist\styles\vcl\GoldenGraphite.vsf"
CARBON VCLSTYLE "C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\Redist\styles\vcl\Carbon.vsf"
In particular having to specify the full path to XE2-installation folder is something I want to avoid.

Another options which you can use
1) Using the Resource dialog.
2) Editing the dproj file of your dll
under this key <PropertyGroup Condition="'$(Base)'!=''">
Add one Entry VCL_Custom_Styles for the vcl styles
<VCL_Custom_Styles>"Amakrits|VCLSTYLE|$(PUBLIC)\Documents\RAD Studio\9.0\Styles\Amakrits.vsf";"Amethyst Kamri|VCLSTYLE|$(PUBLIC)\Documents\RAD Studio\9.0\Styles\AmethystKamri.vsf";"Aqua Graphite|VCLSTYLE|$(PUBLIC)\Documents\RAD Studio\9.0\Styles\AquaGraphite.vsf"</VCL_Custom_Styles>

It works for us also (thanks Rodrigo). Just a couple of details
Don't expect to find the VCLSTYLE on the list of the Resource Type Combo Box, you have to type it manually.
Don't miss to initialize the style in your DLL, we add the next code to the FormCreate event:
TStyleManager.SetStyle('Carbon');

To access correctly to the Style added as a resource check you are adding to the uses clause both units: Vcl.Themes, Vcl.Styles.

Related

Delphi {$INCLUDE filename} in uses part of dpr file

I have many Delphi 10 projects that are using the same units, let's call them "commons".
When I add anew unit to commons, I have to manually add it to each project. I have tried adding a {$INCLUDE commons.inc} line into the uses part of each .dpr file:
uses
Forms,
{$INCLUDE commons.inc}
projectUnit1,
...;
commons.inc has this content:
common1,
common2,
I can compile a project but cannot manage the units from commons.inc. By manage, I mean Ctrl-F12, remove from project, etc.
This is from Delphi's help:
There is one restriction to the use of include files: an include file can't be specified in the middle of a statement part. In fact, all statements between the begin and end of a statement part must exist in the same source file.
I suppose that is why my idea does not work?
Am I doing something wrong, or is there another solution?
This workaround might suit. The only downside I have found so far is that the included files do not appear in the Project Manager.
Add the folder(s) containing the files to be included to the search path of every project.
Create Include.pas, a normal .pas file, and include it in the normal way in every project.
Add the files to be included in multiple projects to the uses clause of Include.pas. $IFDEFS can be used if required.

How to use templates defined in other package without adding source file to the project?

I've created a package which contains several templates (TFrame descendants).
These templates has been added to the palette.
In other packages, I'm trying to use these templates but each time I add one of them, a message appear:
The following unit: %s, is needed in your project to create the
template. Do you wish to add it?
mrYes:
Source file is added to the project.
Furthermore, it causes the following error on compiling:
E2200 Package '%s' already contains unit '%s'
mrNo:
It's ok, but the question is asked each time I place one of my
templates. Me and my collegues will use these templates alot of times and I really would like to avoid that message.
Update 1:
Here are steps to observe the described behavior:
Create a package project named Package1.
Add a TFrame descendant named MyTest.
Add TMyTest to palette (Structure window, right click, add to
palette).
Set project output directories to .\out
Build the project.
Add \out to library path.
In the same projectgroup, create a package project named Package2.
Add Package1, to "requires" (in Package2.dpk).
Add a form.
Add a TMyTestTemplate to the form.
Update 2:
I'm looking for a solution which works with Delphi 2007 and Delphi XE7.
A bit more work but one that should fit your needs:
Create Package FooRuntime(Mark RuntimeOnly), add your TMyFrame
Create Package FooDesignTime(Mark DesigntimeOnly), requires FooRuntime, Registers your frame
Install FooDesignTime
Link your other project to FooRuntime
Without the packages the IDE seems to fail to recognize the units.

How to inform Free Pascal Compiler to set Locale ID for the compiled application

In Delphi there is an option VersionInfo->Language->Locale ID when viewing project properties.
I was wandering how to set such property for a program being compiled under Free Pascal.
Any solution is welcome: command line argument or preprocessor directive such as {$key value}; equivalent to Delphi.
If you can build your projects using *.lpi files then I would try to add the following into your project's Project.lpi file. In the following snippet is shown how to set the project's locale ID (for Windows platform) to 0405 (Czech).
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
...
<VersionInfo>
<UseVersionInfo Value="True"/>
<Language Value="0405"/>
<StringTable ProductVersion=""/>
</VersionInfo>
...
</ProjectOptions>
...
</CONFIG>
Or if you are using Lazarus IDE then you might use to Delphi very similar settings tab which you can open from Project / Project Options ... and as in Delphi go to Version Info where is the Language selection combo box available if you include the version info into the project.
Not 100% sure this will work, feel free to vote me down if this doesn't work.
Lazarus will inherit the locale settings it starts with.
You can set the locale info prior to starting Lazarus in Linux/OS X using the command line:
export LC_CTYPE="pt_BR"
export LANG="pt_BR"
export LANGUAGE="pt_BR"
./lazarus
Your compiled application should inherit these settings.
The answer is inspired by this workaround to an error has since been fixed.
I recommend you have a look at the fpc forum as well and ask the question there.
Don't forget it include details like the platform (Linux/Windows/OS X) and the exact version of FPC and Lazarus you are using as well as the actual Locale that you want.
Better answer
From: http://forum.lazarus.freepascal.org/index.php/topic,5924.0.html
Finally, I managed to find a simple and effective way to make my application localizeable. It uses just one unit and no code.
1. Add unit "defaulttranslator" to your uses list.
2. Enable "i18n" in "Project Options" and set "PO output directory" to "locale" or "languages". You can put translation files right into application folder, but that would just make a mess. Don't forget to create an appropriate folder.
3. Add components to the form. If you already have all components on your form, you'll have to move it a little bit, so it's modified.
4. Save your project.
5. Now there should be .po files in your "locale" or "languages" folder. For different languages files should be copied and renamed like so "project1.XX.po", where XX is language code (e.g. "en", "de", etc.).
6. Translate .po files with translation software, and generate .mo files. I suggest to use POEdit.
7. Run your application, and the translation to be used will be chosen by your regional locale settings. If you need to test other language - just start your application with following command line parameters - "-l XX" or "-lang XX", where XX is a language code.
This method is not very versatile, but it translates resource strings and LCL component properties.

Delphi DFM not found

I am having one xyz.pas file reference in my project. But that file is not with me. I am having the xyz.dcu and xyz.obj file of that xyz.pas file.
When I tried to compile the project I have got the Error "xyz.dcu not found". So i have included the path of xyz.dcu in Search path. Now I am getting error "xyz.dfm not found".
Please suggest me the solution. Is it possible to compile the project with only .dcu and .obj files?
Thanks in advance.
Regards,
Naren
I hope you haven't lost your work.
Simplified, Delphi works like this:
PAS+DFM => DCU
DCU+RES => EXE
More about Delphi files at the end of this answer.
You can compile the project if you only have the DCU file. First, remove the PAS file from your folder else Delphi will try to recompile it (and in order to recompile it, it needs the DFM file).
I don't think the Obj file will be of any use to you.
The DFM file is very very important for your project but yet not critical important. If you are in deep need, you can still go on without it as it can be reconstructed manually based on information you have in the PAS file and based on the way the application's GUI looks (if you have ever seen it running).
Here is the trick (involves some work):
Just create a new form and then look at the top of your original PAS file for the declaration of the form. It may look like this:
TYPE
TYourForm = class(TForm)
xLabel: TLabel;
yButton: TButton;
etc
etc
end;
Then put all those controls back to your new form and name them exactly as they are named in the PAS file (xLabel, yButton, etc). Arrange them to resemble the original GUI. When done, replace the new created PAS file with your original PAS file. IMPORTANT: the name of the DFM and PAS file should match. Compile and you are done! The rebuilt GUI may not look EXACTLY as the original one, but it should do it.
Hint:
There are tools that can extract the DFM file from DCU/EXE.
Here are some of them: www.delphi2.software.informer.com/download-delphi-extract-dfm
This will help you a lot!
.PAS - Delphi Source File
PAS should be stored in Source Control
In Delphi, PAS files are always the source code to either a unit or a form. Unit source files contain most of the code in an application. The unit contains the source code for any event handlers attached to the events of the form or the components it contains. We may edit .pas files using Delphi's code editor. Do not delete .pas files.
.DCU - Delphi Compiled Unit
A compiled unit (.pas) file. By default the compiled version of each unit is stored in a separate binary-format file with the same name as the unit file, but with the extension .DCU (Delphi compiled unit). For example unit1.dcu contains the code and data declared in the unit1.pas file. When you rebuild a project, individual units are not recompiled unless their source (.PAS) files have changed since the last compilation, or their .DCU files cannot be found. Safely delete .dcu file because Delphi recreates it when you compile the application.
.DFM - Delphi Form
DFM should be stored in Source Control
These files are always paired with .pas files. Dfm file contains the details (properties) of the objects contained in a form. It can be view as text by right clicking on the form and selecting view as text from the pop-up menu. Delphi copies information in .dfm files into the finished .exe code file. Caution should be used in altering this file as changes to it could prevent the IDE from being able to load the form. Form files can be saved in either binary or text format. The Environment Options dialog lets you indicate which format you want to use for newly created forms. Do not delete .dfm files.
source: delphi.about.com/od/beginners/a/aa032800a.htm
If you are still in the possesion of the executable, then you can extract your complete and original DFM file from the application resources by any arbitrary resource manager. For example: XN Resource Editor. In the RC DATA category, there will be an item called TXYZ.
Delphi 20xx/XE
Note that Delphi saves old versions of your files in a hidden subdir of your project dir called __history.
In that dir are saved versions of your .pas, .dfm and other project files.
These files are created every time you save a change to disk.
Do a search on your harddisk for all files, (including hidden ones) named *.~*~ this should bring up any backup source files you may have.
They will miss the last change(s) you made, but at least you will not have to do everything all over again.
Delphi 7 and before
Delphi 7 saves these files in the same dir as your project files with a .~ extension.
DFM-Files hold the "visual" aspects (controls, components, properties, visuals, data...) of a (say) form. If the PAS-File (or the compiled DCU-File) needs the DFM, you have to have it, or you get this error. There is no other way than to have the DFM, i think.
Correction (as written below, sorry!): you can compile with only the DCU-file if you remove the PAS-file and provide ONLY the DCU-File. In this case the DCU-File must be compiled with the same compiler-version to be linked into the App, because the compiler can not recompile the DCU.
This is pretty late, but here's what I came with.
My directory stucture is like this
/ Project
/ Source
/ Unit1.pas
/ Packages
/Delphi2010Berlin
/ MyPackage1.dpk
/ MyPackage2.dpk
/ Library
/ Delphi2010Berlin
/ Win32
/ Debug
/ Release
In the /Project folder, i created a .bat file named 'dfmcopy.bat'
All it contains is
#echo off
for /r %1 %%x in (*.dfm) do #copy "%%x" %2 /Y >NUL
Then, in my post build event for my .bpl
./../../dfmcopy.bat $(PROJECTPATH)\..\..\Source $(PROJECTPATH)\..\..\Library\$(Platform)\$(Config)
This will recursively copy all .dfm that are contained in the /Source folder into the /Library/{DelphiVersion}/{Platform}/{Config} folder
One caveat is that if you have multiple projects that have this post build event, dfms might be copied over and over for each project. Don't know if that can pose any issue now.
I use apache ant to build delphi project.
I fix the "dfm not found error" by deleting all dcu files and seperating compiler output files from source files.
The problem is probabily caused by wrong path of dcus files.
<project name ="app1" default = "run">
<property name="delphipath" value="your delphi path"/>
<property name="source" value="C:/ws4d/TStateMachine-master/Tests"/>
<property name="dunit" value="C:/ws4d/dunit-svn"/>
<property name="DCUOUT" value="C:/ws4d/TStateMachine-master/Tests/BIN"/>
<target name="run">
<!-- Compile with Delphi 6 -->
<apply executable="${delphipath}/bin/dcc32.exe" failonerror="true" output="build-dxe10.log" >
<!-- rebuild quiet -->
<arg value="-B"/>
<arg value="-Q"/>
<!-- file paths -->
<arg value="-I${source};{dunit}/src"/>
<arg value="-U${source};{dunit}/src;{delphipath}/lib/win32/release"/>
<arg value="-R${source};{dunit}/src;{delphipath}/lib/win32/release"/>
<arg value="-O${DCUOUT};"/>
<arg value="-N${DCUOUT}"/>
<arg value="-E${DCUOUT}"/>
<!-- all *.dpr files in current directory -->
<fileset dir=".">
<patternset><include name="*.dpr"/></patternset>
</fileset>
</apply>
</target>
</project>

Delphi Path Variables

In the Delphi IDE, the path to the Delphi installation is specified as $(DELPHI). I am wondering if there is a way to create my own path indicators, such as $(MY_LIBRARY) or something similar. I thought $(DELPHI) was specified as an environment variable, but apparently not. Any ideas? (I'm using Delphi 7)
In Delphi 2010:
select Tools -> Options
select "Environment Variables"
specify either System, either User variable
For Delphi 5 you can add them from windows Environment variables
right click on My computer > properties > advanced > Environment variables
In Delphi 2010:
I know many of the XML tags in the Project.dproj can be used like this. (For exemple, $(DCC_DcuOutput), $(DCC_ExeOutput)...).
Maybe it is possible to add your own XML tags in the file and use them afterward. Though I'm not sure if they'll be preserved by the IDE.
Also of note is when your using the command line compiler, the file RSVARS.BAT located in the BIN directory of the current Delphi installation is what creates some of the environment variables for child processes. (for example BDS and BDSCOMMONDIR).
In Windows 7 (and Vista is similar) click the 'start' button, right-click 'computer', 'properties' and then 'advanced system settings'. Click 'Environment variables' and you're now able to create new ones as global (system), or just for the current user (you). For example 'MyVar'.
Now in a delphi path, refer to MyVar as $(MyVar).
MyVar will now be visible in batch files too as %MyVar%.
There is an alternative workaround -- use SUBST to assign a virtual drive letter to the root of the folder you would be using $(MyFiles) if you could and then just use that.
For Example if you have files in deep directory, you'd go to the command prompt and type:
SUBST M: "C:\users\Me\Delphi Files\My Components"
and then you could refer to it by M:

Resources