https://wiki.freepascal.org/api.php?action=feedcontributions&user=Wstomv&feedformat=atomFree Pascal wiki - User contributions [en]2024-03-28T15:51:38ZUser contributionsMediaWiki 1.35.6https://wiki.freepascal.org/index.php?title=Lazarus_Documentation&diff=32130Lazarus Documentation2008-11-22T15:54:22Z<p>Wstomv: /* The Lazarus Developer Guides */ Fixed typo</p>
<hr />
<div>{{Lazarus Documentation}}<br />
<br />
==Lazarus and Pascal Tutorials==<br />
*[[Overview of Free Pascal and Lazarus]] - A brief discussion of kinds of things you can develop with these general-purpose tools.<br />
*[[Lazarus Tutorial]] - A tutorial for beginners and a detailed description of the Lazarus IDE.<br />
*[[Lazarus IDE Tools]] - An intermediate level tutorial about code completion and other IDE tools.<br />
*[[Lazarus Database Tutorial]] - An introduction to using Lazarus with databases.<br />
*[[Developing with Graphics]] - Some basic examples on graphic programming.<br />
*[[Pascal Tutorial]] - [http://www.taoyue.com/ Tao Yue's] [http://www.taoyue.com/tutorials/pascal/ Pascal Tutorial] (reposted with permission).<br />
*[[Object Oriented Programming with FreePascal and Lazarus]] - going beyond standard Pascal<br />
*[[Console Mode Pascal]] - using the Lazarus IDE for writing Pascal programs for text-mode operation.<br />
*[[Executing External Programs]] - A short tutorial showing how to run external programs from inside your program.<br />
*[[TXMLPropStorage]] - Using TXMLPropStorage to save user preferences.<br />
*[[Hardware Access]] - How to access hardware devices, such as ISA cards, PCI cards, parallel and serial ports and USB devices.<br />
*[[Networking]] - Tutorials about TCP/IP protocol, creating secure network programs, WebServices, etc.<br />
*[[XML Tutorial]] - Writing and reading XML files<br />
*[[Multithreaded Application Tutorial]] - How to write multithreaded applications using Free Pascal and Lazarus<br />
*[[Streaming components]] - How to write components to streams and read/create components from streams<br />
*[[OpenGL Tutorial]] - How to use GLUT in Lazarus<br />
*[[Creating bindings for C libraries]] - How to convert C header files (.h) to pascal units<br />
*[[Lazarus/FPC Libraries]] - How to create dynamic libraries (.so, .dll, .dylib) and how to use them<br />
*[[Translations / i18n / localizations for programs]] - How to provide localized versions of your programs and packages<br />
*[[Daemons and Services]] - How to write windows services and/or linux daemons.<br />
*[[Office Automation]] - How to interact with office software and create spreadsheets, text documents, presentations, etc.<br />
*[[Lazarus Inline Assembler]] - a getting started guide.<br />
*[[VirtualTreeview Example for Lazarus]] - Using VirtualTreeview on Lazarus.<br />
*[http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_Pascal Programando en Pascal] - Spanish tutorial focused on FPC/Lazarus, hosted in Wikibooks.<br />
<br />
==The Lazarus User Guides==<br />
*[[Lazarus Faq]] - General information about Lazarus and specifics for Linux and Windows users.<br />
*[[Lazarus DB Faq]] - FAQ on database issues in Lazarus.<br />
*[[Databases in Lazarus]] - An overview of using databases in Lazarus<br />
*[[Code Examples]] - Example working code for Lazarus.<br />
*[[Feature_Ideas|Wishlist/Wanted Features]] - Features that you would like to see in Lazarus<br />
*[[How do I create a bug report]] - You think you found a bug in Lazarus, how can you report it?<br />
<br />
===Installation=== <br />
*[[Installing Lazarus]] - An installation guide<br />
*[[Getting Lazarus]] - Instructions on how to download a released or SVN version of Lazarus<br />
*[[Multiple Lazarus]] - How to install several lazarus versions on one machine<br />
<br />
===IDE===<br />
*[[IDE tricks]] - Tips, tricks and hidden features<br />
*[[Lazarus IDE]] - The IDE windows<br />
*[[Lazarus IDE Shortcuts]] - The key mapping and shortcuts.<br />
*[[Lazarus Packages]] - A guide for creating a package under Lazarus<br />
*[[Install Packages]] - A small guide to install packages<br />
*[[Extending the IDE]] - How to add functionality to the Lazarus IDE<br />
*[[Adding Kylix Help]] - How to use the Borland Help files within the IDE editor.<br />
*[[Using Lazarus for other computer languages]] - How to use the IDE for C, Java, etc.<br />
*[[IDE Development]] - Various pages about current development of the IDE.<br />
<br />
===LCL===<br />
*[[doc:lcl/|LCL documentation]] - On line help for LCL (work in progress).<br />
*[[The LCL in various platforms]] - A brief discussion about LCL features which behave differently in different platforms.<br />
*[[Autosize / Layout]] - How to design forms that work on all platforms.<br />
*[[Main Loop Hooks]] - How to handle multiple event sources<br />
*[[Asynchronous Calls]] - How to queue methods for later execution<br />
*[[File size and smartlinking]] - How to smartlink applications and create smaller executables.<br />
*[[Accessing the Interfaces directly]] - Example how to access the LCL widgetsets<br />
*[[Add Help to Your Application]] - How to create a Online Help for your application<br />
*[[Anchor Sides]] - Description of Anchor Sides Feature<br />
*[[LCL Tips]] - Tips and tricks<br />
*[[LCL Defines]] - Choosing the right options to recompile LCL<br />
<br />
===Developing===<br />
*[[The Power of Proper Planning and Practices]] - common-sense programming best practices for the Free Pascal and Lazarus developer<br />
*[[Multiplatform Programming Guide]] - How to develop cross-platform applications and how to port from one platform to another<br />
*[[Using Pascal Libraries with .NET and Mono]] - yes, you can use your Free Pascal code with .NET and Mono<br />
*[[Deploying Your Application]] - How to create an installer for your application<br />
*[[Cross compiling]] - Creating executables of one platform, on another.<br />
*[[Remote Debugging]] - How to debug your Lazarus application from another machine.<br />
*[[Application Icon]] - Setting the application icon<br />
<br />
===Platform specific Tips===<br />
*[[OS X Programming Tips]] - Lazarus installation, useful tools, Unix commands, and more...<br />
*[[WinCE Programming Tips]] - Using the telephone API, sending SMSes, and more...<br />
<br />
===Tools===<br />
*[[Lazarus Documentation Editor]] - Using "lazde" to create documentation<br />
*[[LazDoc]] - An integrated editor for documentation files<br />
*[[FPDoc Updater]] - A GUI tool for updating FPDoc files<br />
*[[lazbuild]] - Compiling projects and packages without the IDE<br />
*[[LazSVNPkg]] - Lazarus SVN IDE Plugin<br />
<br />
===Coming from Delphi===<br />
*[[Lazarus Components]] - Comparison between Lazarus and Turbo Delphi components<br />
*[[Lazarus For Delphi Users]] - For Delphi users who are getting started with Lazarus<br />
*[[Code Conversion Guide]] - How to convert existing code and components from Delphi and Kylix<br />
<br />
==The Lazarus Developer Guides==<br />
*[[Lazarus Development Process]] - Roadmaps, ideas, current development<br />
*[[How To Help Developing Lazarus]] - A guide to help newbies start improving Lazarus<br />
*[[Version Numbering]] - Explanation of the different version numbers of Lazarus <br />
*[[Creating A Patch| Creating a Patch]] - A guide to making a patch with changes made to Lazarus<br />
*[[Creating a Backtrace with GDB]] - A guide to making a backtrace to help you debug a program<br />
*[[Nomenclature]] - Guide to choose a name for a new method or property<br />
*[[DesignGuidelines|Design Guide Lines]] - A guide about how to proceed when changing Lazarus Source Code.<br />
*[[GUI design]] - Notes on guidelines when designing the lazarus GUI<br />
*[[Roadmap]] - An idea of the current status of the various parts of Lazarus<br />
*[[Road To 1.0]] - What needs to be done for Lazarus 1.0 and To Do lists<br />
*[[Moderating the bug tracker]] - Guidelines for lazarus developers and moderators for using the [http://www.freepascal.org/mantis/ bug tracker].<br />
*[[Codetools]] - How the codetools are integrated into the IDE<br />
*[[Creating IDE Help]] - How to extend the IDE documentation<br />
*[[Unit not found - How to find units]] - How to setup the IDE and source files<br />
*[[Bounties]] - Need a particular new feature soon? Set a price here. <br />
<br />
===LCL - Lazarus component library===<br />
*[[LCL Messages]] - Guide related to LCL Messages<br />
*[[LCL Internals]] - Some info about the inner workings of the LCL<br />
*[[LCL Key Handling]] - Help! A key press, what now?<br />
*[[LCL Internals - Resizing, Moving]] - How the LCL communicates with the LCL interface to resize, move controls<br />
*[[LCL Unicode Support]] - Road to Unicode enabled Lazarus<br />
*[[LCL Documentation Roadmap]] - Which units have to be documented<br />
*[[LCL Bindings]] - Bindings to use LCL on other languages<br />
<br />
===Interfaces===<br />
*[[Lazarus known issues (things that will never be fixed)]] - A list of interface compatibility issues<br />
*[[Win32/64 Interface]] - The winapi interface for Windows 95/98/Me/2K/XP/Vista, but not CE<br />
*[[GTK1 Interface]] - The gtk1.2 for Unixes, Mac OS X, Windows<br />
*[[GTK2 Interface]] - The gtk2 for Unixes, Mac OS X, Windows<br />
*[[Carbon Interface]] - The Carbon Interface for Mac OS X<br />
*[[Qt Interface]] - The Qt 4 Interface for Unixes, Mac OS X and linux-based PDAs<br />
*[[Windows CE Interface]] - For Pocket PC and Smartphones<br />
*[[fpGUI Interface]] - A widgetset completely written in Object Pascal<br />
*[[Cocoa Interface]] - The Cocoa Interface for Mac OS X<br />
<br />
===Translations===<br />
* [[Getting translation strings right]] A few notes for programmers on how to create and use translateable strings in your application. Quickly discusses general things about creating strings, offers a few hints on implementation issues and points out some things to consider when using English as base language in particular.<br />
* '''Localization Notes:'''<br />
:* [[German localization notes|German]] - Notes and guidelines for translating the Lazarus IDE to German, including a small dictionary to look up often used translations.<br />
:* [[Portuguese-Brazilian Localization Notes|Portuguese-Brazilian]] - Small dictionary containing common translations of terms used in the Lazarus IDE for the Portuguese-Brazilian translation.<br />
:* [[Russian localization notes|Russian]] - Notes and guidelines for translating the Lazarus IDE to Russian.<br />
<!-- *[[TO-DO]] Remaining Tasks --><br />
* [[Help:Add language bar | Add language bar]] explains how you can add a list of translations to the top of a wiki page.<br />
<br />
==Additional Components Documentation==<br />
*[[Pascal Script]] and [[Pascal Script Examples]] - How to use the pascal script components in Lazarus<br />
*[[OpenGL]] - How to use OpenGL in Lazarus<br />
*[[KOL-CE]] - Free Pascal/Lazarus port of KOL&MCK library. How to create very compact applications for Win32/WinCE in Lazarus.<br />
<br />
==Free Pascal Compiler Documentation==<br />
In addition to [http://lazarus-ccr.sourceforge.net/fpcdoc/ this site], the latest version of the documentation can also be found online and in a variety of downloadable formats on the main [http://www.freepascal.org/docs.html Free Pascal Compiler site].<br />
There is now also a WiKi site for FreePascal [http://www.freepascal.org/wiki/index.php/Main_Page] very similar in style to this one, to allow developers to submit documentation in addition to the official FPC documents below.<br />
<br />
*[http://lazarus-ccr.sourceforge.net/fpcdoc/user/user.html User's guide]<br />
*[http://lazarus-ccr.sourceforge.net/fpcdoc/prog/prog.html Programmer's guide]<br />
*[http://lazarus-ccr.sourceforge.net/fpcdoc/ref/ref.html Reference guide for the system unit, and supported Pascal constructs]<br />
*[http://lazarus-ccr.sourceforge.net/fpcdoc/rtl/index.html Run-Time Library reference manual]<br />
*[http://lazarus-ccr.sourceforge.net/fpcdoc/fcl/index.html Free Component Library reference manual]<br />
*[http://lazarus-ccr.sourceforge.net/fpcdoc/fpdoc/fpdoc.html Free Pascal documentation tool manual]<br />
*[[Build messages]]<br />
<br />
==Lazarus related blogs and websites==<br />
'''Blogs'''<br />
*[[Adventures of a Newbie]] - A blog of a newbie getting started with some tutorial information in a running log.<br />
*[http://lazarusroad.blogspot.com/ On the road with Lazarus/Freepascal] - A blog dedicated to register my experiences while programming with Lazarus and Freepascal (by Luiz Américo)<br />
*[http://port2laz.blogspot.com/ Porting to Lazarus] - This blog describes the porting of a medium-sized application (~100 kloc) from D7 with CLX to Lazarus (by Alexsander da Rosa)<br />
*[http://living-lazarus.blogspot.com/ Living Lazarus] - One mans exploration into the possibilities of an open source RAD (by [[User:Wibblytim|Wibblytim]]).<br />
*[http://beeography.wordpress.com/tag/object-pascal/ Bee.ography] just (another) Bee’s buzz!<br />
*[http://donaldshimoda.blogspot.com/ Parallel Pascal Worlds] Donald Shimoda.<br />
<br />
'''Websites'''<br />
*[[swainbrain pascal wiki]] - unique free pascal tutorials and info [http://mercury.it.swin.edu.au/swinbrain/index.php/Pascal#Pascal_Development_Tools swainbrain]</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Lazarus_FAQ&diff=32043Lazarus FAQ2008-11-18T22:05:31Z<p>Wstomv: /* What is the meaning of the various file extensions used by Lazarus? */ added that *.lfm has textual format</p>
<hr />
<div>{{Lazarus Faq}}<br />
<br />
This FAQ has been copied from the FAQ at www.lazarus.freepascal.org, as this wiki document is easier to maintain and extend.<br />
<br />
== General ==<br />
<br />
=== Where can I find more FAQs? ===<br />
<br />
See the [http://www.lazarus.freepascal.org official website]. There is another FAQ as well.<br />
<br />
===Why are the generated binaries so big?===<br />
The binaries are big because they include a lot of debug information necessary for using gdb (GNU Debugger).<br />
<br />
The compiler has an option to remove the debug information from the executable (-Xs), but due to a bug in the compiler (version 2.0.2 and earlier), this doesn't work correctly. It has been fixed in the development version of the compiler.<br />
<br />
You can use a program called "strip" to remove the debug symbols from the executable file. It is located under lazarus dir lazarus\pp\bin\i386-win32\.<br />
<br />
Just type "strip --strip-all <your executable file with path>" on the command line.<br />
<br />
If you want to make your program even smaller, you should try [http://upx.sourceforge.net/ UPX] too. UPX is a very good exe compressor. It includes no memory overhead due to in-place decompression. It also has a very fast decompression (~10 MB/sec on an Pentium 133).<br />
<br />
To use upx just type "upx <your executable file with path>" on the command line.<br />
<br />
after using both strip and upx a simple GUI Lazarus program gets:<br />
* ~ 700kb on Linux<br />
* ~ 420kb on Windows<br />
<br />
A more detailed answer with the drawbacks of using UPX is given on [[Size Matters]].<br />
<br />
It's also important to note that the hello world lazarus software already includes a huge amount of features. It includes:<br />
<br />
* XML handling library<br />
* Image handling library for png, xpm, bmp and ico files<br />
* Almost all widgets from the Lazarus Component Library<br />
* All of the Free Pascal Runtime Library<br />
<br />
So it's very big, but it already includes almost everything a real world non-trivial app will need.<br />
<br />
Lazarus executable size starts big, but grows very slowly, because of the Free Pascal compiler and the way lazarus forms operate. A c++ project (just an example, but applies to other languages / tools too) starts very small on the hello world, but quickly grows exponentially when you need features to write a non-trivial application.<br />
<br />
[[Image:Lazarus_vs_cpp.png]]<br />
<br />
=== Why is the linking so slow on Windows? ===<br />
<br />
This problem is over from FPC 2.2 and Lazarus 0.9.24. Please update your Lazarus. For older versions read text below.<br />
<br />
Generally speaking, compilation on Windows takes more time then other platforms because the GNU Linker utilized by Free Pascal is slow on this platform. This problem only affects Windows, and is only bad on relatively old computers (less then 1Ghz) and computers with little RAM (128MB or less).<br />
<br />
Also, if you smartlink LCL the linking will be much slower. A study about this is located here: [[File size and smartlinking]]<br />
<br />
A internal linker was developed, and is ready, but will only be available when Free Pascal 2.2 is released (of course it's also available via subversion). It decreases the linking time dramatically.<br />
<br />
'''Note''': In 2.1.1 Windows uses an internal linker for win32/64/ce which speeds the process up a bit. A Lazarus recompile then eats about 280MB.<br />
<br />
=== Do I need ppc386.cfg or fpc.cfg? ===<br />
<br />
You only need fpc.cfg. This way the compiler knows where to find the libraries.<br />
<br />
=== How do I compile lazarus? ===<br />
<br />
Do something like this:<br />
$ cd lazarus<br />
$ make clean all<br />
<br />
=== How do I build other projects based upon the LCL ===<br />
<br />
If you can't use the IDE to build your applications, use lazbuild. This is a command line version of the IDE to build lazarus projects and packages.<br />
If you want to build LCL applications without the IDE and without the lazbuild, add the following lines to the end of your ''fpc.cfg''<br />
<br />
# searchpath for other toolkits (Linux)<br />
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/{YourToolKit}<br />
<br />
# searchpath for other toolkits (Windows)<br />
-Fu/{YourLazarusDirectory}/components/units/{YourToolKit}<br />
<br />
:Where {YourToolKit} may be ''gtk2'', ''gnome'', ''qt'' or ''win32'' and run:<br />
::ppc386 your.project.pp<br />
<br />
'''Hint:''' Don't forget to install the development packages for your toolkit otherwise you might a receive something like: [[Linker message: cannot find -l]].<br />
<br />
=== What version of FPC is required? ===<br />
<br />
2.0.4 for MacOSX and 2.2.2 for all other systems. Warning: The 2.2.0 has a bug under MacOSX with case sensitive filenames.<br />
You can also use the svn version of fpc 2.2.3 and 2.3.x.<br />
<br />
=== I can't compile Lazarus ===<br />
<br />
# Check if the compiler has the correct version<br />
# Check if the (fpc)libraries are from the same version.<br />
# Check if you have a fpc.cfg and no old ppc386.cfg<br />
# Check also the OS-dependent FAQs<br />
<br />
=== When I try to compile a project, I have an error ===<br />
==== "Cannot find Unit interfaces". How can I solve this?====<br />
It means the compiler can not find the file 'interfaces.ppu' '''or''' it means it found one, but it is wrong or outdated.<br />
<br />
This unit can be found in {LazarusDir}\lcl\units\{TargetCPU}-{TargetOS}\{LCLWidgetSet}\interfaces.ppu. For example: /home/username/lazarus/lcl/units/i386-linux/gtk/interfaces.ppu.<br />
<br />
Make sure, it is only there. If you have multiple versions of interfaces.ppu, then you probably have a wrong configuration (for instance you added a lcl directory to a search path). Remove all interfaces.ppu, but the one in the directory above.<br />
<br />
If you selected a different widgetset than you used to build lazarus, you need to build the LCL for this widgetset. <br />
<br />
If it is there, but you get this error, you are using a different compiler / rtl for compiling your project than you used for compiling your Lazarus IDE. You can do one of the following<br />
* Rebuild the LCL (or Lazarus completely) with the compiler selected in the Environmnent Options. You can do this with Tools -> Build Lazarus. Before doing this, check the current settings in Tools -> Configure Build Lazarus.<br />
* Change the compiler in the Environment Options to the one you used to compile Lazarus. Look carefully also in the Environment Options to see if you are using the correct paths for the Lazarus Directory and the FPC sources directory. Check that there is only one version of the compiler configuration file fpc.cfg - it should reside in /etc/ for Linux/Unix systems or in the same directory as the fpc compiler for Windows systems. Try to run "fpc -vt bogus" to check which fpc.cfg is being used in your system. Rogue copies often creep in if you have updated your compiler to a new version; they may be found in your home directory or in the same directory as the one in which you built your new compiler. DELETE THESE!!<br />
* You may also try to change the widgetset currently selected for the project. For example, the sample project "objectinspector" that comes with Lazarus is set to gtk by default. Compiling this project will surely give you "Can't find unit interfaces" in Windows platform. Changing widgetset to default(Win32) in Project | Compiler Options... | LCL Widget Type (various) should fix this issue.<br />
<br />
=== When I try to compile delphi projects under lazarus, I have an error ===<br />
==== at the line :{$R *.DFM} How can I solve this problem ? ====<br />
<br />
Lazarus (or better Linux) doesn't know about resources, so you can't use them in the way Delphi/Win32 does. However Lazarus uses a method pretty compatible with this. You can still use your Delphi layouts (.dfm files) if you use the following steps:<br />
<br />
*You need a textual version of the .dfm files. D5 and higher are doing this as default. If you have older files: ALT-F12 to see the layout as text and paste/copy. When you have a text .dfm file, just copy it to a .lfm file.<br />
*Create a file with lazres (in lazarus/tools) lazres yourform.lrs yourform.lfm<br />
*Add the following initialization section to<br />
<br />
initialization<br />
{$I yourform.lrs}<br />
<br />
Please keep in mind that not all properties in the dfm are supported yet by<br />
lazarus, so you might get a crash.<br />
<br />
==== 'Identifier not found LazarusResources'. ====<br />
<br />
When creating a form Lazarus automaticaly add some extra units to the uses section of your form unit. During the conversion of a delphi unit to a Lazarus unit this does not happen. So you need to add LResources to the Uses section of your form unit.<br />
<br />
=== When accessing events of objects e.g. the onclick event of a button I get the following error. ERROR unit not found: stdCtrls ===<br />
<br />
Make sure, in the Project -> Project Inspector, that your project depends on the package 'LCL' and that you have installed the FPC sources.<br />
<br />
Lazarus is the IDE and the visual components library LCL.<br />
All other stuff, like IO, Database, FCL and RTL are provided by FPC.<br />
The IDE needs the paths to all sources.<br />
<br />
The FPC source path can be set via:<br />
Environment -> Environment Options -> Files -> FPC source directory<br />
<br />
===How to embed a small file in the executable, without the need of a separate file? How to embed a resource?===<br />
<br />
For example:<br />
/your/lazarus/path/tools/lazres sound.lrs sound1.wav sound2.wav ...<br />
will create sound.lrs from sound1.wav and sound2.wav.<br />
<br />
Then include it *behind* the form lrs file:<br />
<br />
...<br />
initialization<br />
{$i unit1.lrs} // this is main resource file (first)<br />
{$i sound.lrs} // user defined resource file<br />
<br />
end.<br />
In your program you can then use:<br />
Sound1AsString:=LazarusResources.Find('sound1').Value;<br />
<br />
=== How can I see debug output? ===<br />
<br />
The LCL has in the LCLProc unit two procedures to write debug output. They are named: <br />
* '''DebugLn:''' which works about the same as WriteLn, but accepts only strings.<br />
* '''DbgOut:''' which works about the same as Write, but accepts only strings.<br />
<br />
In normal circumstances the output is written to stdout. If stdout is closed, (for example when the application is {$AppType Gui} or compiled with -WG on Windows), no output is written.<br />
<br />
Debug output can also be written to file. The initialization code of the LCLProc unit checks Lazarus.exe's command line parameters for '--debug-log=<file>'. On finding this parameter any subsequent debug output is sent to <file>.<br />
<br />
If no '--debug-log' command line parameter has been given, it next checks if an operating system environment variable xxx_debuglog exists, where xxx is the program file name without extension. For Lazarus this would be lazarus_debuglog. If such an environment variable exists, it uses the file specified in the lazarus_debuglog environment variable as file to receive debug output. Example: if you do:<br />
set lazarus_debuglog=c:\lazarus\debug.txt<br />
debug output will be written to c:\lazarus\debug.txt.<br />
<br />
Since this is implemented in lclproc, every application using lclproc, can use this output facility.<br />
<br />
;Debuging Lazarus : Most useful for Windows: If you want output on a console, add {$APPTYPE console} to lazarus.pp ; Then rebuild Lazarus.<br />
<br />
=== What is the meaning of the various file extensions used by Lazarus? ===<br />
<br />
The [[Lazarus Tutorial#The Lazarus files]] explains some extensions by an example.<br />
Here is a brief list:<br />
<br />
; <code>*.lpi</code> : Lazarus Project Information file (stored in XML; contains project-specific settings)<br />
; <code>*.lpr</code> : Lazarus Program file; contains Pascal source of main program<br />
; <code>*.lfm</code> : Lazarus Form file; contains configuration information for all objects on a form (stored in a Lazarus-specific textual format; the actions are described by Pascal source code in a corresponding <code>*.pas</code> file)<br />
; <code>*.pas</code> or <code>*.pp</code> : Unit with Pascal code (typically for a form stored in a corresponding <code>*.lfm</code> file)<br />
; <code>*.lrs</code> : Lazarus Resource file (this is a generated file; not to be confused with a Windows resource file). <br />
: This file can be created with lazres tool (in directory Lazarus/Tools) using commandline: lazres myfile.lrs myfile.lfm<br />
; <code>*.ppu</code> : Compiled unit<br />
; <code>*.lpk</code> : Lazarus package information file. (stored in XML; contains package-specific settings)<br />
<br />
=== I have fixed/improved lazarus. How can I add my changes to the official lazarus source? ===<br />
Create a patch and send it to the developers. For details see [[Creating A Patch]].<br />
=== When I do ''var mytext: text;'' to declare a text file, I get "Unit1.pas(32,15) Error: Error in type definition". How can I fix this?===<br />
The TControl class has a [[doc:lcl/controls/tcontrol.text.html|Text]] property. In a method of a form, that has higher visibility, the [[doc:rtl/system/text.html|Text]] type from the system unit. You can use the [[doc:rtl/system/textfile.html|TextFile]] type, which is just an alias for the Text type or you can add the unit to the type definition.<br />
var<br />
MyTextFile: TextFile;<br />
MyText: System.Text;<br />
A similar name clash exists with assigning and closing a text file. TForm has a ''assign'' and a [[doc:lcl/forms/tcustomform.close.html|Close]] method. You can use [[doc:rtl/objpas/assignfile.html|AssignFile]] and [[doc:rtl/objpas/closefile.html|CloseFile]] or add the unit name ''System''.<br />
<br />
=== I get an error when using Printer.BeginDoc ===<br />
<br />
The unit Printers must be added to the uses section.<br />
<br />
The Printer4Lazarus package must be added to your project requirement in the IDE under:<br />
Project|Project Inspector|Add|New Requirement|Package Name:<br />
<br />
If the package Printer4Lazarus package is not in the list when opening the dropdown box it must be installed. The package is part of the Lazarus installation and can be found in:<br />
[lazarus installed directory]\components\printers<br />
<br />
If you used the default installation directories [lazarus installed directory] is:<br />
*Windows: c:\lazarus <br />
*Linux: /usr/lib/lazarus<br />
<br />
The same solution also applies to the exception you can get when referencing Printer.Printers<br />
<br />
=== Why are TForm.ClientWidth/ClientHeight the same as TForm.Width/Height ===<br />
<br />
The TForm.Width/Height do no include the frame, because there was no way to retrieve the frame size on all platforms. Without a reliable way, the LCL would move the forms around on the screen or resize them endlessly.<br />
<br />
Eventually when there is a reliable way to get the size and position of a window with its frame on all platforms, then it will be changed. To keep compatibility with older LCL forms, a version number and some extra methods will be added.<br />
<br />
=== I created a Patch to dock the IDE Messages form on the "Source Code Editor" form (at bottom) ===<br />
<br />
Such patches will not be applied, because they only implement a small part of the needed docking. The goal is to create a complete dock manager and use that. A complete dock manager can dock all IDE windows and it allows to let the user define how to dock. For example dock the messages window above or below the source editor or ... or not at all. For instance:<br />
<br />
<pre><br />
+-------------------++--+<br />
|menu || |<br />
+-------------------+| |<br />
+--++---------------+| |<br />
|PI|| Source Editor ||CE|<br />
+--+| || |<br />
+--+| || |<br />
| |+---------------++--+<br />
|OI|+-------------------+<br />
| ||messages |<br />
+--++-------------------+<br />
</pre><br />
<br />
The dock manager can store the layout and restore it on next load. Preferably the dock manager can dock in pages too. The dock manager does not need to use drag and drop.<br />
All patches implementing docking without a dock manager makes it harder to implement a real dock manager and will be rejected.<br />
<br />
=== How can I become a developer lazarus and access management in the SVN and bug-tracker? ===<br />
<br />
First of all: you must learn about Lazarus, to prove your knowledge and skill.<br />
Start by reading the [[Lazarus_Documentation|wiki articles]], read the Lazarus source code, giving a look at the [http://www.lazarus.freepascal.org/mantis Lazarus Bug-Tracker], fix some bugs, and if you think you are ready, contact the developers on the [http://www.mail-archive.com/lazarus@miraclec.com mailing list].<br />
<br />
== Where is ... defined ==<br />
<br />
=== Virtual key constants ===<br />
Virtual key constants are defined in LCLType. Add LCLtype to your <b>uses</b>.<br />
<br />
== Using the IDE ==<br />
<br />
=== How can I use "identifier completion"? ===<br />
You can invoke identifier completion by pressing [ctrl][space].<br />
Under the menu item ''Environment -> Editor Options -> Code Tools -> Automatic Features'' you can set how quick this should happen automatically.<br />
<br />
== Linux ==<br />
<br />
=== How can I debug on Linux without the IDE? ===<br />
<br />
First of all you need a debugger. gdb is the standard debugger under linux and<br />
there are several GUI-frontends available. One common frontend is ddd, which is<br />
part of most common distributions. To compile lazarus/lcl with debug-information<br />
you should then use the following commands to start a debug session:<br />
<br />
$ make clean; make OPT=-dDEBUG<br />
$ ddd lazarus<br />
<br />
Be warned however, that ddd is not as comfortable as e.g. the Lazarus debugger.<br />
Specially if it comes to view the contents of a variable you have to take into<br />
account that ddd/gdb are case sensitive whereas Pascal is case-insensitive.<br />
Therefore you have to type all variable names in uppercase to see their<br />
contents. For more information take a look into the fpc-manuals.<br />
<br />
=== I can debug now but ddd does not find my sources or complains that they contain no code. Whats that? ===<br />
<br />
This is a path-related problem with either gdb or ddd. You can aviod this by<br />
<br />
* Use the "Change directory" command from the ddd menu and choose the directory where the sources are located. The drawback of this method is that you now can't use the source of the program you started with (e.g. lazarus). Thus it may be neccessary to change the directory multiple times.<br />
* In ddd goto [Edit] [gdb-settings] and set the search-path<br />
* Create a $(HOME)/.gdbinit file like:<br />
directory /your/path/to/lazarus<br />
directory /your/path/to/lazarus/lcl<br />
directory /your/path/to/lazarus/lcl/include<br />
<br />
=== I receive an error during the linking that states /usr/bin/ld can't find -l<some lib> ===<br />
<br />
; '''Package Based Distributions''' : You need to install the package that provides the lib<somelib>.so or lib<somelib>.a files. Dynamic libs under linux have the extension .so, while static libs have the extension .a. On some Linux distro's you have installed the package (rpm, deb) <packagename> which provides <some lib>, but you also need the development package (rpm, deb), normally called <packagename>-dev, which contains the .a (static lib) and/or the .so (dynamic lib). <br />
: Some distributions have commands to find which package contains a file:<br />
: '''Mandriva'''<br />
<br />
[]$ urpmf lib<somelib>.so<br />
<br />
:will list all packages containing the file named lib<somelib>.so, you'll have to install those ending in -devel<br />
<br />
: '''Debian'''<br />
<br />
:install the apt-file utility (apt-get install apt-file) then<br />
<br />
[]$ apt-file search lib<somelib>.so<br />
<br />
:will list all packages containing the file named lib<somelib>.so, you'll have to install those ending in -dev<br />
<br />
<br />
<br />
; '''Source Based Distributions and Manual Compilation (LFS)''' : Make sure that there is a lib<somelib>.a in the path, and that it contains the right version. To let the linker find the dynamic library, create a symlink called lib<some lib>.so to lib<some lib><version>-x,y.so if necessary (and/or for static lib; lib<some lib>.a to lib<some lib><version>-x,y.a).<br />
<br />
; '''FreeBSD''' : As source based distro's, and also make sure you have -Fl/usr/local/lib in your fpc.cfg and/or Lazarus library path. Keep in mind that GTK1.2 has "gtk12" as package name under FreeBSD. (same for glib) NOTE: This has changed as of late. Newest ports have gtk-12 and glib-12 as well. You might stumble on this problem, since FPC requires the "-less" ones, you will need to symlink them like this:<br />
<br />
[]# cd /usr/local/lib && ln -s libglib-12.so libglib12.so<br />
[]# cd /usr/X11R6/lib && ln -s libgtk-12.so libgtk12.so<br />
[]# cd /usr/X11R6/lib && ln -s libgdk-12.so libgdk12.so<br />
<br />
; '''NetBSD''' : As source based distro's, and also make sure you have -Fl/usr/pkg/lib in your fpc.cfg and/or Lazarus library path<br />
<br />
=== How can I convert a kylix 2 project into a lazarus project? ===<br />
<br />
Nearly the same way as converting a Kylix project into a Delphi/VCL project.<br />
<br />
The LCL (Lazarus Component Library) tries to be compatible to Delphis VCL.<br />
Kylix CLX tries to be QT compatible.<br />
Here are some general hints:<br />
<br />
* Rename all used CLX Q-units like QForms, QControls, QGraphics, ... into their VCL counterparts: Forms, Controls, Graphics, ...<br />
* Add LResources to the uses section of every form source<br />
* Rename or copy all .xfm files to .lfm files.<br />
* Rename or copy .dpr file to .lpr file.<br />
* Add "Interfaces" to the uses section in the .lpr file.<br />
* Remove {$R *.res} directive<br />
* Remove {$R *.xfm} directive<br />
* Add {$mode objfpc}{$H+} or {$mode delphi}{$H+} directive to .pas and .lpr files<br />
* Add an initialization section to the end of each form source and add an include directive for the .lrs file (lazarus resource file):<br />
initialization<br />
{$I unit1.lrs}<br />
:The .lrs files can be created via the lazres tool in: (lazarusdir)/tools/lazres.<br />
:For example: ./lazres unit1.lrs unit1.lfm<br />
<br />
* Fix the differences. The LCL does not yet support every property of the VCL and the CLX is not fully VCL compatible.<br />
<br />
* To make it more platform independant, reduce unit libc (which is deprecated) references and substitute with native FPC units like baseunix/unix as much as possible. This will be necessary to support other targets than linux/x86 (including OS X, FreeBSD and Linux/x86_64)<br />
<br />
=== When compiling lazarus the compiler can not find a unit. e.g.: gtkint.pp(17,16) Fatal: Can't find unit GLIB ===<br />
<br />
1. Check a clean rebuild: do a 'make clean all'<br />
<br />
2. Check if the compiler has the correct version (2.0.4 or higher)<br />
<br />
3. Check if the compiler is using the right config file. The normal installation creates /etc/fpc.cfg. But fpc also searches for ~/.ppc386.cfg, ~/.fpc.cfg, /etc/ppc386.cfg and it uses only the first it finds.<br />
<br />
:'''Hint:''' You can see which config file is used with 'ppc386 -vt bogus'<br />
:Remove any ppc386.cfg as it is really obsolete.<br />
<br />
4. Check if the config file (/etc/fpc.cfg) contains the right paths to your fpc libs. There must be three lines like this:<br />
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget<br />
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/rtl<br />
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/*<br />
:The first part of these paths (/usr/lib/fpc) depends on your system. On some systems this can be for example /usr/local/lib/fpc/... .<br />
:'''Hint:''' You can see your searchpaths with 'ppc386 -vt bogus'<br />
<br />
5. Check that the config file (/etc/fpc.cfg) does not contain search paths to the lcl source files (.pp, .pas):<br />
forbidden: -Fu(lazarus_source_directory)/lcl<br />
forbidden: -Fu(lazarus_source_directory)/lcl/interfaces/gtk<br />
:If you want to add the lcl for all your fpc projects, make sure that the two paths look like the following and are placed after the above fpc lib paths:<br />
-Fu(lazarus_source_directory)/lcl/units/$fpctarget<br />
-Fu(lazarus_source_directory)/lcl/units/$fpctarget/gtk<br />
<br />
6. Check if the missing unit (glib.ppu) exists in your fpc lib directory. For example the gtk.ppu can be found in /usr/lib/fpc/$fpcversion/units/i386-linux/gtk/. If it does not exists, the fpc lib is corrupt and should be reinstalled.<br />
<br />
7. Check if the sources are in a NFS mounted directory. In some cases the NFS updates created files incorrectly. Please, try to move the sources into a non NFS directory and compile there.<br />
<br />
8. If you are still not succeeded try to use samplecfg script as follows:<br />
<br />
''#'' cd /usr/lib/fpc/''version''/<br />
<br />
''#'' sudo ./samplecfg /usr/lib/fpc/''\$version'' /etc<br />
<br />
Note! Do not put - / - after etc because if you do that the system will create a file - /etc/fpc.cfg/fpc.cfg. In fact we want that samplecfg make a file - /etc/fpc.cfg - not the folder /etc/fpc.cfg.<br />
<br />
=== I have installed the binary version, but when compiling a simple project, lazarus gives: Fatal: Can't find unit CONTROLS ===<br />
<br />
Probably you are using a newer fpc package, than that used for building the<br />
lazarus binaries. The best solution is to download the sources and compile<br />
lazarus manually. You can download the source snapshot or get the source<br />
via svn:<br />
<br />
$ bash<br />
$ svn checkout http://svn.freepascal.org/svn/lazarus/trunk lazarus<br />
$ cd lazarus<br />
$ make clean all<br />
<br />
Make sure that lazarus get the new source directory:<br />
Environment->General Options->Files->Lazarus Directory Top<br />
<br />
===Lazarus compiles, but linking fails with: libgdk-pixbuf not found===<br />
Install the gdk-pixbuf library for gtk1.x:<br />
<br />
Where to find the gdk-pixbuf library:<br />
<br />
RPMs:<br />
http://rpmfind.net/linux/rpm2html/search.php?query=gdk-pixbuf&submit=Search+...&system=&arch=<br />
<br />
Debian packages:<br />
libgdk-pixbuf-dev<br />
<br />
Sources:<br />
ftp://ftp.gnome.org/pub/gnome/unstable/sources/gdk-pixbuf/<br />
<br />
===I have SuSE and I get /usr/bin/ld: cannot find -lgtk Error: Error while linking===<br />
SuSE installs the gtk devel libs under /opt/gnome/lib (or /opt/gnome/lib64 for 64 bits), which is not in<br />
the standard lib path. Simply add it to your /etc/fpc.cfg.<br />
(-Fl/opt/gnome/lib).<br />
<br />
===Lazarus crashes with runtime error 211 after I installed a component===<br />
After I installed a component, Lazarus crashes with the following message:<br />
Threading has been used before cthreads was initialized.<br />
Make cthreads one of the first units in your uses clause.<br />
Runtime error 211 at $0066E188<br />
How can I fix this?<br />
<br />
Your freshly installed component is using threads. FPC on *nix doesn't automatically include threading support, but it must be intialized. This initialization is done in the cthreads unit. Every application using the component needs to add this unit to the uses clause of the main program. Lazarus itself is no exception. This can be done in two ways:<br />
<br />
1) Open the package. In the package editor click on ''Options''. Under page ''Usage'' add to the ''custom'' options '''-dUseCThreads'''. Then rebuild the IDE. This way the cthreads unit will be automatically used by the IDE under unix and the cthreads are initialized.<br />
<br />
2) In order to avoid modifying package, a fpc compiler option could be used directly. Open menu Tools->Configure "build Lazarus". Configure "build Lazarus" dialog will be shown, in field "Options:" type -Facthreads and then press "OK" button. The next step is to install the package. Lazarus will be built with option -Facthreads which means that it will treat main program as if unit cthreads where first in uses clause. <br />
<br />
''Hint:'' Maybe your old (non-crashing) lazarus executable is stored as lazarus.old in the same directory as the crashing lazarus executable.<br />
<br />
See also [[Multithreaded_Application_Tutorial#Units_needed_for_a_multithreaded_application]]<br />
<br />
===When I run a program with threads I get runtime error 232===<br />
The complete error message is:<br />
This binary has no thread support compiled in.<br />
Recompile the application with a thread-driver in the program uses<br />
clause before other units using thread.<br />
Runtime error 232<br />
'''Solution''': Add cthreads as first unit to the uses clause of your main program, usually the .lpr-file.<br />
<br />
===I have Ubuntu Breezy and my fonts in Lazarus IDE look too big===<br />
If Lazarus is compiled with Gtk1.2, the settings in Gnome Preferences/Font don't have any effect as<br />
they are related to Gtk2.<br />
You could try this solution:<br />
Create a file named .gtkrc.mine in your home directory (if it's not already there) and add<br />
these lines to it:<br />
<br />
<pre><br />
style "default-text" {<br />
fontset = "-*-arial-medium-r-normal--*-100-*-*-*-*-iso8859-1,\<br />
-*-helvetica-medium-r-normal--*-100-*-*-*-*-*-*"<br />
}<br />
<br />
class "GtkWidget" style "default-text"<br />
</pre><br />
<br />
If this is not enough try and create also a .gtkrc symlink to .gtkrc.mine . It worked in this way under Xubuntu 7.10.<br />
<br />
===How can my gtk programs use custom rc files?===<br />
<br />
Option a)<br />
Name the rc file ''yourprogram.gtkrc'' and put it in the same directory where the executable is.<br />
<br />
Option b)<br />
Use unit ''GtkInt'' and call ''GTKWidgetSet.SetRCFilename('your_preferred_rc_file');''<br />
Best done before ''Application.Initialize'' in the .lpr file with ''{$IFDEF LCLGtk}''.<br />
<br />
===I have Ubuntu and I cannot compile for Gtk2 due to missing libraries===<br />
Ubuntu has a problem with not creating all the symbolic links that you'll need even when the libraries are installed. Make sure that all missing libraries when trying to link for Gtk2 have their appropriate links. For instance, you might need to do:<br />
<br />
<pre><br />
cd /usr/lib<br />
sudo ln -s libgdk-x11-2.0.so.0 libgtk-x11-2.0.so<br />
</pre><br />
<br />
Make sure that the [whatever].so symbolic links are created and point to the actual libraries.<br />
<br />
===How can I compile a program for Gtk2?===<br />
<br />
At the moment, the Gtk2 compiled IDE is a little unstable, but you can compile software for Gtk2 using the Gtk1 IDE.<br />
<br />
To start with recompile LCL for Gtk2. Go to the menu "Tools"->"Configure Build Lazarus" and set LCL to clean+build and everything else to none.<br />
<br />
Now click Ok and go to the menu "Tools"->"Build Lazarus"<br />
<br />
Now you can compile your software with Gtk2 going on the Compiler options and changing the widgetset to Gtk2.<br />
<br />
===I get this message: "[WARNING] ** Multibyte character encodings (like UTF8) are not supported at the moment."===<br />
<br />
Since revision 10535 (0.9.21) this message doesn't exist anymore. <br />
Previously it was used to warn that a UTF-8 encoding was used. The internal keyhandling routines for the gtk1 widgetset couldn't handle such encoding for keypresses, with the result that keypresses with for instance accented chars were not or wrong detected.<br />
<br />
(original text for older versions of lazarus)<br><br />
<strike><br />
This warning message indicates that your locale enconding is set to utf-8. If you are using Gtk 1 this can be a serious problem and prevent the correct working of Lazarus or software created with Lazarus.<br />
<br />
To work around this, just change your locale to a non utf-8 before executing the program on the command line, like this:<br />
<br />
<pre><br />
export LC_CTYPE="pt_BR"<br />
export LANG="pt_BR"<br />
export LANGUAGE="pt_BR"<br />
./lazarus<br />
</pre><br />
<br />
Substitute pt_BR with the locale for your country. You can create a script to automate this.<br />
</strike><br />
<br />
== Windows ==<br />
<br />
=== When I cycle the compiler, I get:The name specified is not recognized as an internal or external command, operable program or batch file.>& was unexpected at this time. ===<br />
<br />
In the compiler directory there is an OS2 scriptfile named make.cmd. Different versions of Windows also see this as a script file, so remove it since what is needed for OS2 becomes a hindrance on Windows.<br />
<br />
=== When I cycle the compiler, I get: make[3]: ./ppc1.exe: Command not found ===<br />
<br />
I don't know why but somehow make has lost its path. Try to cycle with a<br />
basedir set like: make cycle BASEDIR=your_fpc_source_dir_herecompiler<br />
<br />
=== When I try to make Lazarus I get:===<br />
====make.exe: * * * interfaces: No such file or directory (ENOENT). Stop.make.exe: * * * [interfaces_all] Error 2 ====<br />
You need to upgrade your make.<br />
<br />
====makefile:27: *** You need the GNU utils package to use this Makefile. Stop.====<br />
Make sure you didn't install FPC in a path with spaces in the name. The<br />
Makefile doesn't support it.<br />
<br />
<br />
<br />
===How can I give my program an XP look like lazarus has?===<br />
Project -> Project Options -> Check 'Use manifest to enables themes'.<br />
<br />
===When I run Windows program created in Lazarus it starts with a DOS window===<br />
Specify the -WG argument (Windows GUI) on the command line of the compiler or in the Lazarus IDE check the Windows GUI check box on the compiler options dialog box (Project menu -> Compiler Options -> Linking -> target OS Specific options.<br />
<br />
== Mac OS X ==<br />
<br />
=== Why does compiling a project fail with 'unknown section attribute: no_dead_strip'?===<br />
<br />
Dead code stripping is not supported by the assembler and linker before Xcode 1.5 (available for Mac OS X 10.3.9). Disable the compiler options <br />
<br />
*Code > Unit style > Smart linkable (-CX) <br />
*and Linking > Link Style > Link smart (-XX)<br />
<br />
== Licensing ==<br />
<br />
=== Can I make commercial applications with Lazarus ? ===<br />
<br />
Yes, the LCL is licensed under the LGPL with an exception, which allows you to link to it statically without releasing the source of your application. Modifications and enhancements to the LCL must be distributed with source. Lazarus, the IDE, is licensed under the GPL.<br />
<br />
=== Can I make commercial plug-ins for Lazarus ? ===<br />
<br />
Yes, the IDEIntf part of the IDE is licensed under the LGPL with the same exception, so that shared data structures in this part will not force you to license your plug-in or design-time package under the GPL. You are free to choose a plug-in of any license; we don't want to limit your choice. Therefore non-GPL compatible plug-ins are allowed. Note that it's not allowed to distribute a precompiled Lazarus with these non-GPL-compatible plugins included statically; however, we do not see this as a severe limitation, since recompiling Lazarus is easy.<br />
<br />
== Contributors and Comments ==<br />
<br />
This page has been converted from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=LazarusFaq version].</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Coding_style&diff=26383Coding style2008-01-21T09:22:33Z<p>Wstomv: /* Examples */ Added link to viewcvs</p>
<hr />
<div>== Introduction ==<br />
Some people might think that the coding style used by the FPC compiler sources and base rtl is a little bit strange but it has been used for a lot of years and isn't subject to be discussed. So take the following as a standard to be used. <br />
<br />
== Keywords ==<br />
Write all keywords in ''lower case''. There is no need to make them unreadble by writing them in upper case. Modern IDEs support syntax highlighting, so keywords will be easily recognizable.<br />
<br />
== TAB characters ==<br />
Do not use TAB characters (ASCII HT, 0x09). There is no standard default TAB setting, so the look of source files using TAB characters will depend on client settings.<br />
This may result in a chaotic view of source files.<br />
Align by space characters (also see ''Indentation'').<br />
<br />
== Indentation ==<br />
Indentation size is always 2 space characters per level.<br />
<br />
== Newlines ==<br />
<br />
Newlines are set as it is done by most Object Pascal programs (what does this mean? advice: avoid passive voice).<br />
Separate subroutines by three newlines,<br />
that is, put ''two'' blank lines between them.<br />
<br />
== Misc ==<br />
<br />
Please note that the <tt>else</tt> in consecutive <tt>if</tt>s is not indented:<br />
<br />
if ... then<br />
else if ... then<br />
else if ... then<br />
<br />
== Examples ==<br />
How it looks like can be easily checked by having a look at the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/?root=fpc FPC sources].</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Coding_style&diff=26382Coding style2008-01-21T09:19:10Z<p>Wstomv: /* Keywords */ Improved text</p>
<hr />
<div>== Introduction ==<br />
Some people might think that the coding style used by the FPC compiler sources and base rtl is a little bit strange but it has been used for a lot of years and isn't subject to be discussed. So take the following as a standard to be used. <br />
<br />
== Keywords ==<br />
Write all keywords in ''lower case''. There is no need to make them unreadble by writing them in upper case. Modern IDEs support syntax highlighting, so keywords will be easily recognizable.<br />
<br />
== TAB characters ==<br />
Do not use TAB characters (ASCII HT, 0x09). There is no standard default TAB setting, so the look of source files using TAB characters will depend on client settings.<br />
This may result in a chaotic view of source files.<br />
Align by space characters (also see ''Indentation'').<br />
<br />
== Indentation ==<br />
Indentation size is always 2 space characters per level.<br />
<br />
== Newlines ==<br />
<br />
Newlines are set as it is done by most Object Pascal programs (what does this mean? advice: avoid passive voice).<br />
Separate subroutines by three newlines,<br />
that is, put ''two'' blank lines between them.<br />
<br />
== Misc ==<br />
<br />
Please note that the <tt>else</tt> in consecutive <tt>if</tt>s is not indented:<br />
<br />
if ... then<br />
else if ... then<br />
else if ... then<br />
<br />
== Examples ==<br />
How it looks like can be easily checked by having a look at the FPC sources.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Coding_style&diff=26381Coding style2008-01-21T09:17:04Z<p>Wstomv: /* Newlines */ Improve text</p>
<hr />
<div>== Introduction ==<br />
Some people might think that the coding style used by the FPC compiler sources and base rtl is a little bit strange but it has been used for a lot of years and isn't subject to be discussed. So take the following as a standard to be used. <br />
<br />
== Keywords ==<br />
All keywords are written in lower case. There is no need to make them unreadble by writing them upper case. Modern IDEs support highlighting so keywords will be recognized.<br />
<br />
== TAB characters ==<br />
Do not use TAB characters (ASCII HT, 0x09). There is no standard default TAB setting, so the look of source files using TAB characters will depend on client settings.<br />
This may result in a chaotic view of source files.<br />
Align by space characters (also see ''Indentation'').<br />
<br />
== Indentation ==<br />
Indentation size is always 2 space characters per level.<br />
<br />
== Newlines ==<br />
<br />
Newlines are set as it is done by most Object Pascal programs (what does this mean? advice: avoid passive voice).<br />
Separate subroutines by three newlines,<br />
that is, put ''two'' blank lines between them.<br />
<br />
== Misc ==<br />
<br />
Please note that the <tt>else</tt> in consecutive <tt>if</tt>s is not indented:<br />
<br />
if ... then<br />
else if ... then<br />
else if ... then<br />
<br />
== Examples ==<br />
How it looks like can be easily checked by having a look at the FPC sources.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Coding_style&diff=26380Coding style2008-01-21T09:15:27Z<p>Wstomv: /* Newlines */ Marked unclear text.</p>
<hr />
<div>== Introduction ==<br />
Some people might think that the coding style used by the FPC compiler sources and base rtl is a little bit strange but it has been used for a lot of years and isn't subject to be discussed. So take the following as a standard to be used. <br />
<br />
== Keywords ==<br />
All keywords are written in lower case. There is no need to make them unreadble by writing them upper case. Modern IDEs support highlighting so keywords will be recognized.<br />
<br />
== TAB characters ==<br />
Do not use TAB characters (ASCII HT, 0x09). There is no standard default TAB setting, so the look of source files using TAB characters will depend on client settings.<br />
This may result in a chaotic view of source files.<br />
Align by space characters (also see ''Indentation'').<br />
<br />
== Indentation ==<br />
Indentation size is always 2 space characters per level.<br />
<br />
== Newlines ==<br />
<br />
Newlines are set as it is done by most Object Pascal programs (what does this mean? advice: avoid passive voice).<br />
Subroutines separated by three newlines,<br />
that is, there are ''two'' blank lines between them.<br />
<br />
== Misc ==<br />
<br />
Please note that the <tt>else</tt> in consecutive <tt>if</tt>s is not indented:<br />
<br />
if ... then<br />
else if ... then<br />
else if ... then<br />
<br />
== Examples ==<br />
How it looks like can be easily checked by having a look at the FPC sources.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Coding_style&diff=26379Coding style2008-01-21T09:13:35Z<p>Wstomv: /* Newlines */ Improved and cllarified text</p>
<hr />
<div>== Introduction ==<br />
Some people might think that the coding style used by the FPC compiler sources and base rtl is a little bit strange but it has been used for a lot of years and isn't subject to be discussed. So take the following as a standard to be used. <br />
<br />
== Keywords ==<br />
All keywords are written in lower case. There is no need to make them unreadble by writing them upper case. Modern IDEs support highlighting so keywords will be recognized.<br />
<br />
== TAB characters ==<br />
Do not use TAB characters (ASCII HT, 0x09). There is no standard default TAB setting, so the look of source files using TAB characters will depend on client settings.<br />
This may result in a chaotic view of source files.<br />
Align by space characters (also see ''Indentation'').<br />
<br />
== Indentation ==<br />
Indentation size is always 2 space characters per level.<br />
<br />
== Newlines ==<br />
<br />
Newlines are set as it is done by most Object Pascal programs. Subroutines separated by three newlines,<br />
that is, there are ''two'' blank lines between them.<br />
<br />
== Misc ==<br />
<br />
Please note that the <tt>else</tt> in consecutive <tt>if</tt>s is not indented:<br />
<br />
if ... then<br />
else if ... then<br />
else if ... then<br />
<br />
== Examples ==<br />
How it looks like can be easily checked by having a look at the FPC sources.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Coding_style&diff=26378Coding style2008-01-21T09:08:08Z<p>Wstomv: /* Misc */ Improved markup</p>
<hr />
<div>== Introduction ==<br />
Some people might think that the coding style used by the FPC compiler sources and base rtl is a little bit strange but it has been used for a lot of years and isn't subject to be discussed. So take the following as a standard to be used. <br />
<br />
== Keywords ==<br />
All keywords are written in lower case. There is no need to make them unreadble by writing them upper case. Modern IDEs support highlighting so keywords will be recognized.<br />
<br />
== TAB characters ==<br />
Do not use TAB characters (ASCII HT, 0x09). There is no standard default TAB setting, so the look of source files using TAB characters will depend on client settings.<br />
This may result in a chaotic view of source files.<br />
Align by space characters (also see ''Indentation'').<br />
<br />
== Indentation ==<br />
Indentation size is always 2 space characters per level.<br />
<br />
== Newlines ==<br />
<br />
Newlines are set as it is done by most Object Pascal programs. Between subroutines are two newlines used to separate them.<br />
<br />
== Misc ==<br />
<br />
Please note that the <tt>else</tt> in consecutive <tt>if</tt>s is not indented:<br />
<br />
if ... then<br />
else if ... then<br />
else if ... then<br />
<br />
== Examples ==<br />
How it looks like can be easily checked by having a look at the FPC sources.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Coding_style&diff=26377Coding style2008-01-21T09:06:32Z<p>Wstomv: /* Tabulators */ Improved text</p>
<hr />
<div>== Introduction ==<br />
Some people might think that the coding style used by the FPC compiler sources and base rtl is a little bit strange but it has been used for a lot of years and isn't subject to be discussed. So take the following as a standard to be used. <br />
<br />
== Keywords ==<br />
All keywords are written in lower case. There is no need to make them unreadble by writing them upper case. Modern IDEs support highlighting so keywords will be recognized.<br />
<br />
== TAB characters ==<br />
Do not use TAB characters (ASCII HT, 0x09). There is no standard default TAB setting, so the look of source files using TAB characters will depend on client settings.<br />
This may result in a chaotic view of source files.<br />
Align by space characters (also see ''Indentation'').<br />
<br />
== Indentation ==<br />
Indentation size is always 2 space characters per level.<br />
<br />
== Newlines ==<br />
<br />
Newlines are set as it is done by most Object Pascal programs. Between subroutines are two newlines used to separate them.<br />
<br />
== Misc ==<br />
<br />
Please note that the else in consecutive <tt>ifs</tt> isn't indented:<br />
<br />
if ... then<br />
else if ... then<br />
else if ... then<br />
<br />
== Examples ==<br />
How it looks like can be easily checked by having a look at the FPC sources.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Coding_style&diff=26376Coding style2008-01-21T08:56:30Z<p>Wstomv: /* Indentation */ Corrected spelling; clarified text</p>
<hr />
<div>== Introduction ==<br />
Some people might think that the coding style used by the FPC compiler sources and base rtl is a little bit strange but it has been used for a lot of years and isn't subject to be discussed. So take the following as a standard to be used. <br />
<br />
== Keywords ==<br />
All keywords are written in lower case. There is no need to make them unreadble by writing them upper case. Modern IDEs support highlighting so keywords will be recognized.<br />
<br />
== Tabulators ==<br />
Don't use tabulators. People have different ideas how many chars a tabulator might be so sources using tabulators might look strange.<br />
<br />
== Indentation ==<br />
Indentation size is always 2 space characters per level.<br />
<br />
== Newlines ==<br />
<br />
Newlines are set as it is done by most Object Pascal programs. Between subroutines are two newlines used to separate them.<br />
<br />
== Misc ==<br />
<br />
Please note that the else in consecutive <tt>ifs</tt> isn't indented:<br />
<br />
if ... then<br />
else if ... then<br />
else if ... then<br />
<br />
== Examples ==<br />
How it looks like can be easily checked by having a look at the FPC sources.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FCL&diff=20349FCL2007-06-18T09:19:46Z<p>Wstomv: Started a list of FCL components</p>
<hr />
<div>{{FCL}}<br />
<br />
The ''Free Component Library'' (FCL) consists of a collection of units, providing components (mostly classes) for common tasks.<br />
It intends to be compatible with Delphi's ''Visual Component Library'' (VCL), but the FCL is restricted to non-visual components.<br />
On the other hand, the FCL also goes beyond the VCL.<br />
<br />
See [http://www.freepascal.org/fcl/fcl.html Free Component Library] for the current development status and an overview of the available components<br />
(though this seems inconsistent with [http://lazarus-ccr.sourceforge.net/docs/fcl/index.html Reference for 'fcl'] in Lazarus).<br />
You can also check the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/packages/ source repository].<br />
Note that there are also some platform-specific files in the FCL.<br />
<br />
After the example, you can find a list of some FCL components.<br />
<br />
=== Usage ===<br />
<br />
To use an FCL component you need to include its name in a '''uses''' clause of your program or unit (see example below).<br />
The default compiler configuration is set up to search the fcl directory for such units.<br />
You can also set the appropriate search path with a command-line compiler option of the form -Fu<path-to-fcl-units>.<br />
<br />
=== Documentation ===<br />
<br />
Currently, the FCL is not documented (feel free to contribute;<br />
also take a look at [http://lazarus-ccr.sourceforge.net/docs/fcl/index.html Reference for 'fcl']).<br />
For Delphi compatible units, you could consult the Delphi documentation.<br />
You can always take a look at the source files in the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/packages/ source repository].<br />
<br />
=== Example ===<br />
<br />
The following program illustrates the use of the class TObjectList in the FCL unit Contnrs (providing various containers, including lists, stacks, and queues):<br />
<br />
<delphi> program TObjectListExample;<br />
<br />
uses<br />
Classes, { from RTL for TObject }<br />
Contnrs; { from FCL for TObjectList }<br />
<br />
type<br />
TMyObject = class(TObject) { just some application-specific class }<br />
private<br />
FName: String; { with a string field }<br />
public<br />
constructor Create(AName: String); { and a constructor to create it with a given name }<br />
property Name: String read FName; { and a property to read the name }<br />
end;<br />
<br />
constructor TMyObject.Create(AName: String);<br />
begin<br />
inherited Create;<br />
FName := AName;<br />
end;<br />
<br />
var<br />
VObjectList: TObjectList; { for a list of objects; it is a reference to such a list! }<br />
<br />
begin<br />
VObjectList := TObjectList.Create { create an empty list }<br />
with VObjectList do<br />
begin<br />
Add(TMyObject.Create('Thing One'));<br />
Writeln((Last as TMyObject).Name);<br />
Add(TMyObject.Create('Thing Two'));<br />
Writeln((Last as TMyObject).Name);<br />
end;<br />
end.</delphi><br />
<br />
This program must be compiled in an object-oriented mode, such as -Mobjfpc or -Mdelphi.<br />
<br />
=== FCL Components ===<br />
<br />
This is not an exhaustive list (to avoid duplication of effort).<br />
It only mentions some important components, or components that are otherwise not easy to find.<br />
<br />
; Classes : Base classes for Object Pascal extensions in Delphi mode<br />
; Contnrs : Some common container classes<br />
; FPCUnit : Unit testing framework (based on Kent Beck's unit testing framework, e.g. cf. [http://www.junit.org/ JUnit]), [http://www.freepascal.org/docs-html/fpcunit.pdf documenting article about FPCUnit]</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FCL&diff=19798FCL2007-06-12T23:06:43Z<p>Wstomv: Removed path to platform-specific files in source repository (was outdated)</p>
<hr />
<div>The ''Free Component Library'' (FCL) consists of a collection of units, providing components (mostly classes) for common tasks.<br />
It intends to be compatible with Delphi's ''Visual Component Library'' (VCL), but the FCL is restricted to non-visual components.<br />
On the other hand, the FCL also goes beyond the VCL.<br />
<br />
See [http://www.freepascal.org/fcl/fcl.html Free Component Library] for the current development status and an overview of the available components<br />
(though this seems inconsistent with [http://lazarus-ccr.sourceforge.net/docs/fcl/index.html Reference for 'fcl'] in Lazarus).<br />
You can also check the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/packages/ source repository].<br />
Note that there are also some platform specific files in the FCL.<br />
<br />
=== Usage ===<br />
<br />
To use an FCL component you need to include its name in a '''uses''' clause of your program or unit (see example below).<br />
The default compiler configuration is set up to search the fcl directory for such units.<br />
You can also set the appropriate search path with a command-line compiler option of the form -Fu<path-to-fcl-units>.<br />
<br />
=== Documentation ===<br />
<br />
Currently, the FCL is not documented (feel free to contribute;<br />
also take a look at [http://lazarus-ccr.sourceforge.net/docs/fcl/index.html Reference for 'fcl']).<br />
For Delphi compatible units, you could consult the Delphi documentation.<br />
You can always take a look at the source files in the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/packages/ source repository].<br />
<br />
=== Example ===<br />
<br />
The following program illustrates the use of the class TObjectList in the FCL unit Contnrs (providing various containers, including lists, stacks, and queues):<br />
<br />
<delphi> program TObjectListExample;<br />
<br />
uses<br />
Classes, { from RTL for TObject }<br />
Contnrs; { from FCL for TObjectList }<br />
<br />
type<br />
TMyObject = class(TObject) { just some application-specific class }<br />
private<br />
FName: String; { with a string field }<br />
public<br />
constructor Create(AName: String); { and a constructor to create it with a given name }<br />
property Name: String read FName; { and a property to read the name }<br />
end;<br />
<br />
constructor TMyObject.Create(AName: String);<br />
begin<br />
inherited Create;<br />
FName := AName;<br />
end;<br />
<br />
var<br />
VObjectList: TObjectList; { for a list of objects; it is a reference to such a list! }<br />
<br />
begin<br />
VObjectList := TObjectList.Create { create an empty list }<br />
with VObjectList do<br />
begin<br />
Add(TMyObject.Create('Thing One'));<br />
Writeln((Last as TMyObject).Name);<br />
Add(TMyObject.Create('Thing Two'));<br />
Writeln((Last as TMyObject).Name);<br />
end;<br />
end.</delphi><br />
<br />
This program must be compiled in an object-oriented mode, such as -Mobjfpc or -Mdelphi.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FCL&diff=19797FCL2007-06-12T22:57:34Z<p>Wstomv: Do syntax highlighting</p>
<hr />
<div>The ''Free Component Library'' (FCL) consists of a collection of units, providing components (mostly classes) for common tasks.<br />
It intends to be compatible with Delphi's ''Visual Component Library'' (VCL), but the FCL is restricted to non-visual components.<br />
On the other hand, the FCL also goes beyond the VCL.<br />
<br />
See [http://www.freepascal.org/fcl/fcl.html Free Component Library] for the current development status and an overview of the available components<br />
(though this seems inconsistent with [http://lazarus-ccr.sourceforge.net/docs/fcl/index.html Reference for 'fcl'] in Lazarus).<br />
You can also check the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/packages/ source repository].<br />
Note that there are also some platform specific files in the FCL, which you can find under trunk/fcl/<platform>/.<br />
<br />
=== Usage ===<br />
<br />
To use an FCL component you need to include its name in a '''uses''' clause of your program or unit (see example below).<br />
The default compiler configuration is set up to search the fcl directory for such units.<br />
You can also set the appropriate search path with a command-line compiler option of the form -Fu<path-to-fcl-units>.<br />
<br />
=== Documentation ===<br />
<br />
Currently, the FCL is not documented (feel free to contribute;<br />
also take a look at [http://lazarus-ccr.sourceforge.net/docs/fcl/index.html Reference for 'fcl']).<br />
For Delphi compatible units, you could consult the Delphi documentation.<br />
You can always take a look at the source files in the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/packages/ source repository].<br />
<br />
=== Example ===<br />
<br />
The following program illustrates the use of the class TObjectList in the FCL unit Contnrs (providing various containers, including lists, stacks, and queues):<br />
<br />
<delphi> program TObjectListExample;<br />
<br />
uses<br />
Classes, { from RTL for TObject }<br />
Contnrs; { from FCL for TObjectList }<br />
<br />
type<br />
TMyObject = class(TObject) { just some application-specific class }<br />
private<br />
FName: String; { with a string field }<br />
public<br />
constructor Create(AName: String); { and a constructor to create it with a given name }<br />
property Name: String read FName; { and a property to read the name }<br />
end;<br />
<br />
constructor TMyObject.Create(AName: String);<br />
begin<br />
inherited Create;<br />
FName := AName;<br />
end;<br />
<br />
var<br />
VObjectList: TObjectList; { for a list of objects; it is a reference to such a list! }<br />
<br />
begin<br />
VObjectList := TObjectList.Create { create an empty list }<br />
with VObjectList do<br />
begin<br />
Add(TMyObject.Create('Thing One'));<br />
Writeln((Last as TMyObject).Name);<br />
Add(TMyObject.Create('Thing Two'));<br />
Writeln((Last as TMyObject).Name);<br />
end;<br />
end.</delphi><br />
<br />
This program must be compiled in an object-oriented mode, such as -Mobjfpc or -Mdelphi.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FCL&diff=19796FCL2007-06-12T22:49:59Z<p>Wstomv: Corrected links to FCL in the source repository</p>
<hr />
<div>The ''Free Component Library'' (FCL) consists of a collection of units, providing components (mostly classes) for common tasks.<br />
It intends to be compatible with Delphi's ''Visual Component Library'' (VCL), but the FCL is restricted to non-visual components.<br />
On the other hand, the FCL also goes beyond the VCL.<br />
<br />
See [http://www.freepascal.org/fcl/fcl.html Free Component Library] for the current development status and an overview of the available components<br />
(though this seems inconsistent with [http://lazarus-ccr.sourceforge.net/docs/fcl/index.html Reference for 'fcl'] in Lazarus).<br />
You can also check the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/packages/ source repository].<br />
Note that there are also some platform specific files in the FCL, which you can find under trunk/fcl/<platform>/.<br />
<br />
=== Usage ===<br />
<br />
To use an FCL component you need to include its name in a '''uses''' clause of your program or unit (see example below).<br />
The default compiler configuration is set up to search the fcl directory for such units.<br />
You can also set the appropriate search path with a command-line compiler option of the form -Fu<path-to-fcl-units>.<br />
<br />
=== Documentation ===<br />
<br />
Currently, the FCL is not documented (feel free to contribute;<br />
also take a look at [http://lazarus-ccr.sourceforge.net/docs/fcl/index.html Reference for 'fcl']).<br />
For Delphi compatible units, you could consult the Delphi documentation.<br />
You can always take a look at the source files in the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/packages/ source repository].<br />
<br />
=== Example ===<br />
<br />
The following program illustrates the use of the class TObjectList in the FCL unit Contnrs (providing various containers, including lists, stacks, and queues):<br />
<br />
program TObjectListExample;<br />
<br />
uses<br />
Classes, { from RTL for TObject }<br />
Contnrs; { from FCL for TObjectList }<br />
<br />
type<br />
TMyObject = class(TObject) { just some application-specific class }<br />
private<br />
FName: String; { with a string field }<br />
public<br />
constructor Create(AName: String); { and a constructor to create it with a given name }<br />
property Name: String read FName; { and a property to read the name }<br />
end;<br />
<br />
constructor TMyObject.Create(AName: String);<br />
begin<br />
inherited Create;<br />
FName := AName;<br />
end;<br />
<br />
var<br />
VObjectList: TObjectList; { for a list of objects; it is a reference to such a list! }<br />
<br />
begin<br />
VObjectList := TObjectList.Create { create an empty list }<br />
with VObjectList do<br />
begin<br />
Add(TMyObject.Create('Thing One'));<br />
Writeln((Last as TMyObject).Name);<br />
Add(TMyObject.Create('Thing Two'));<br />
Writeln((Last as TMyObject).Name);<br />
end;<br />
end.<br />
<br />
This program must be compiled in an object-oriented mode, such as -Mobjfpc or -Mdelphi.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FCL&diff=19794FCL2007-06-12T21:48:27Z<p>Wstomv: Included link to "Reference for package 'fcl'" in Lazarus doc</p>
<hr />
<div>The ''Free Component Library'' (FCL) consists of a collection of units, providing components (mostly classes) for common tasks.<br />
It intends to be compatible with Delphi's ''Visual Component Library'' (VCL), but the FCL is restricted to non-visual components.<br />
On the other hand, the FCL also goes beyond the VCL.<br />
<br />
See [http://www.freepascal.org/fcl/fcl.html Free Component Library] for the current development status and an overview of the available components<br />
(though this seems inconsistent with [http://lazarus-ccr.sourceforge.net/docs/fcl/index.html Reference for 'fcl'] in Lazarus).<br />
You can also check the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
Note that there are also some platform specific files in the FCL, which you can find under trunk/fcl/<platform>/.<br />
<br />
=== Usage ===<br />
<br />
To use an FCL component you need to include its name in a '''uses''' clause of your program or unit (see example below).<br />
The default compiler configuration is set up to search the fcl directory for such units.<br />
You can also set the appropriate search path with a command-line compiler option of the form -Fu<path-to-fcl-units>.<br />
<br />
=== Documentation ===<br />
<br />
Currently, the FCL is not documented (feel free to contribute;<br />
also take a look at [http://lazarus-ccr.sourceforge.net/docs/fcl/index.html Reference for 'fcl']).<br />
For Delphi compatible units, you could consult the Delphi documentation.<br />
You can always take a look at the source files in the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
<br />
=== Example ===<br />
<br />
The following program illustrates the use of the class TObjectList in the FCL unit Contnrs (providing various containers, including lists, stacks, and queues):<br />
<br />
program TObjectListExample;<br />
<br />
uses<br />
Classes, { from RTL for TObject }<br />
Contnrs; { from FCL for TObjectList }<br />
<br />
type<br />
TMyObject = class(TObject) { just some application-specific class }<br />
private<br />
FName: String; { with a string field }<br />
public<br />
constructor Create(AName: String); { and a constructor to create it with a given name }<br />
property Name: String read FName; { and a property to read the name }<br />
end;<br />
<br />
constructor TMyObject.Create(AName: String);<br />
begin<br />
inherited Create;<br />
FName := AName;<br />
end;<br />
<br />
var<br />
VObjectList: TObjectList; { for a list of objects; it is a reference to such a list! }<br />
<br />
begin<br />
VObjectList := TObjectList.Create { create an empty list }<br />
with VObjectList do<br />
begin<br />
Add(TMyObject.Create('Thing One'));<br />
Writeln((Last as TMyObject).Name);<br />
Add(TMyObject.Create('Thing Two'));<br />
Writeln((Last as TMyObject).Name);<br />
end;<br />
end.<br />
<br />
This program must be compiled in an object-oriented mode, such as -Mobjfpc or -Mdelphi.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Releasing_units_without_source_code&diff=15409Releasing units without source code2006-04-07T09:39:54Z<p>Wstomv: Rephrased to address unit dependencies in general, and some other tweaks</p>
<hr />
<div>It can be useful to release a FreePascal unit without publishing its source code:<br />
* The source code contains proprietary information.<br />
* In teaching, because you want to force students to use a unit by its interface (contract) only, and not by looking at its implementation.<br />
<br />
FreePascal allows you to do so in the following way.<br />
<br />
The '''provider''' of the unit (and owner of its source code) should:<br />
* Compile the unit separately; it is recommended to use the compiler option '''-Ur''' (''Generate release unit files''; see ''User's Manual'' for details)<br />
* Publish both the resulting '''*.ppu''' and '''*.o''' files. Also see Section 3.3 of the ''User's Manual'' (''Compiling a unit'').<br />
The '''user''' of the provided unit should:<br />
* Compile the using program (the ''client''), such that the compiler can find both the '''*.ppu''' and '''*.o''' files of the unit (e.g. through the compiler option '''-Fu''').<br />
<br />
Thus, there are two compiler contexts that matter:<br />
* The compiler installation of the provider<br />
* The compiler installation of the user (client)<br />
<br />
'''Notes'''<br />
* The '''Target OS''' of the provided unit should match the target OS used for compiling the client program.<br />
* If the provided unit depends on another unit ''U'', then the unit ''U'' of the client context needs to be ''compatible'' with the unit ''U'' in the provider context. For that purpose, the providing compiler embeds a checksum of the '''interface section''' of unit ''U'' in the '''*.ppu''' file of the provided unit. The client compiler checks the embedded checksum against the checksum of unit ''U'' in the client context. If the checksums differ, then the client compiler will attempt to recompile the provided unit, and this will fail because the source is missing. With the compiler option '''-vu''' you get more information on the handling of unit files, and you can spot a line stating ''Recompiling ..., checksum changed for ...''.<br />
* In particular, the '''System unit''' of the provider context should be ''compatible'' with the System unit of the client context, because every unit implicitly depends on the System unit. Therefore, it is recommended to use a ''stable release'' of the compiler to compile the provided unit.<br />
* There may be some other compiler options to consider (besides setting the Target OS):<br />
** '''-M''' (''Mode'')<br />
** '''-C''' (''Checking''), such as '''-Cr''' (''range checking''), '''-Ci''' (''i/o checking''), '''-Co''' (''overflow checking''), '''-Ct''' (''stack checking'')<br />
** '''-Sa''' (''Include assert statements in compiled code'')<br />
** '''-O''' (''Optimization'')<br />
** '''-gl''' (''Generating lineinfo code'')<br />
* For older versions of the FreePascal compiler, the name of the provided unit's source file should be in all lower case letters. For recent versions of the compiler, this is no longer an issue. (The ''User's Manual'' is not up to date on this topic, I believe. '''If you know more details, e.g. from which version on this changed, then please put it here.''')</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Releasing_units_without_source_code&diff=15408Releasing units without source code2006-04-06T21:10:45Z<p>Wstomv: Made the explanation about the checksum of the System unit more precise</p>
<hr />
<div>It can be useful to release a FreePascal unit without publishing its source code:<br />
* The source code contains proprietary information.<br />
* In teaching, because you want to force students to use a unit by its interface (contract) only, and not by looking at its implementation.<br />
<br />
FreePascal allows you to do so in the following way.<br />
<br />
The '''provider''' of the unit (and owner of its source code) should:<br />
* Compile the unit separately; it is recommended to use the compiler option '''-Ur''' (''Generate release unit files''; see ''User's Manual'' for details).<br />
* Publish both the resulting '''*.ppu''' and '''*.o''' files. Also see Section 3.3 of the ''User's Manual'' (''Compiling a unit'').<br />
The '''user''' of the provided unit should:<br />
* Compile the using program (the ''client''), such that the compiler can find both the '''*.ppu''' and '''*.o''' files of the unit (e.g. through the compiler option '''-Fu''').<br />
<br />
'''Notes'''<br />
* The '''Target OS''' of the provided unit should match the target OS used for compiling the using program.<br />
* The '''System unit''' of the provided unit should be ''compatible'' with the System unit used for compiling the using program. That is, the compiler versions for compiling the provided unit and the using program should be ''compatible''. The compiler checks for compatibility by comparing the checksum of the '''interface section''' of the System unit used for compiling the provided unit (this checksum is embedded in the '''*.ppu''' file) with that of the current System unit. If the checksums differ, then the compiler will attempt to recompile the provided unit, and will fail because the source is missing. With the compiler option '''-vu''' you get more information on the handling of unit files, and you can spot a line stating ''Recompiling ..., checksum changed for System''.<br />
* There may be some other compiler options to worry about:<br />
** '''-M''' (''Mode'')<br />
** '''-C''' (''Checking''), such as '''-Cr''' (''range checking''), '''-Ci''' (''i/o checking''), '''-Co''' (''overflow checking''), '''-Ct''' (''stack checking'')<br />
** '''-O''' (''Optimization'')<br />
** '''-gl''' (''Generating lineinfo code'')<br />
* For older versions of the FreePascal compiler, the name of the provided unit's source file should be in all lower case letters. For recent version of the compiler, this is no longer an issue. (The ''User's Manual'' is not up to date, I believe.)</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Releasing_units_without_source_code&diff=15407Releasing units without source code2006-04-06T20:36:51Z<p>Wstomv: Page creation</p>
<hr />
<div>It can be useful to release a FreePascal unit without publishing its source code:<br />
* The source code contains proprietary information.<br />
* In teaching, because you want to force students to use a unit by its interface (contract) only, and not by looking at its implementation.<br />
<br />
FreePascal allows you to do so in the following way.<br />
<br />
The '''provider''' of the unit (and owner of its source code) should:<br />
* Compile the unit separately; it is recommended to use the compiler option '''-Ur''' (''Generate release unit files''; see ''User's Manual'' for details).<br />
* Publish both the resulting '''*.ppu''' and '''*.o''' files. Also see Section 3.3 of the ''User's Manual'' (''Compiling a unit'').<br />
The '''user''' of the provided unit should:<br />
* Compile the using program (the ''client''), such that the compiler can find both the '''*.ppu''' and '''*.o''' files of the unit (e.g. through the compiler option '''-Fu''').<br />
<br />
'''Notes'''<br />
* The '''Target OS''' of the provided unit should match the target OS used for compiling the using program.<br />
* The '''System unit''' of the provided unit should be ''compatible'' with the System unit used for compiling the using program. That is, the compiler versions for compiling the provided unit and the using program should be ''compatible''. (The compiler checks for compatibility by comparing the checksum of the System unit embedded in the '''*.ppu''' file with that of the current System unit. If the checksums differ, the compiler will attempt to recompile the provided unit, and will fail because the source is missing. With the compiler option '''-vu''' you get more information on the handling of unit files, and you can spot a line stating ''Recompiling ..., checksum changed for System''.)<br />
* There may be some other compiler options to worry about:<br />
** '''-M''' (''Mode'')<br />
** '''-C''' (''Checking''), such as '''-Cr''' (''range checking''), '''-Ci''' (''i/o checking''), '''-Co''' (''overflow checking''), '''-Ct''' (''stack checking'')<br />
** '''-O''' (''Optimization'')<br />
** '''-gl''' (''Generating lineinfo code'')<br />
* For older versions of the FreePascal compiler, the name of the provided unit's source file should be in all lower case letters. For recent version of the compiler, this is no longer an issue. (The ''User's Manual'' is not up to date, I believe.)</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FPC&diff=13281FPC2006-04-06T19:53:34Z<p>Wstomv: /* Using FPC */ Added an entry point to a new section on releasing units without source code</p>
<hr />
<div>This is the main page of the Free Pascal Compiler (FPC) itself.<br />
<br />
==General Info==<br />
<br />
[[Standard Pascal]]<br><br />
[[Platform list|Supported Platforms]]<br />
<br />
Supported [[Language Mode]]s:<br />
* [[Mode FPC]]<br />
* [[Mode OBJFPC]]<br />
* [[Mode Delphi]]<br />
* [[Mode TP]]<br />
* [[Mode GPC]]<br />
* [[Mode MacPas]]<br />
<br />
==Using FPC==<br />
<br />
[[Writing portable code regarding the processor architecture]]<br />
<br />
[[Writing efficient code]]<br />
<br />
[[Link on target]]<br />
<br />
[[FPC and Qt]]<br />
<br />
[[FPC and SDL]]<br />
<br />
[[FPC and DirectX]]<br />
<br />
[[Setup Cross Compile For ARM]]<br />
<br />
[[Using resourcestrings]]<br />
<br />
[[Cross-compilation from Win32 to GO32v2]]<br />
<br />
[[CGI Web Programming]]<br />
<br />
[[Releasing units without source code]]<br />
<br />
==Developing FPC==<br />
<br />
[[Compiler development articles]]<br />
<br />
[[Language related articles]]<br />
<br />
[[Compile With Delphi]]</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Lazarus_FAQ&diff=6009Lazarus FAQ2006-03-29T15:07:15Z<p>Wstomv: /* General */ Added question on meaning of file extensions in Lazarus</p>
<hr />
<div>{{Lazarus Faq}}<br />
<br />
This FAQ is being copied from the FAQ at www.freepascal.org, as this wiki document is easier to maintain and extend.<br />
<br />
== General ==<br />
<br />
=== Where can I find more FAQ? ===<br />
<br />
See the official website www.lazarus.freepascal.org. There is another FAQ as well. <br />
<br />
===Why are the generated binaries so big?===<br />
The binaries are big because they include a lot of debug information necessary for using gdb (GNU Debugger).<br />
<br />
The compiler has an option to remove the debug information from the executable (-Xs), but due to a bug in the compiler (version 2.0.2 and earlier), this doesn't work correctly. It has been fixed in the development version of the compiler.<br />
<br />
You can use a program called "strip" to remove the debug symbols from the executable file. It is located under lazarus dir lazarus\pp\bin\i386-win32\.<br />
<br />
Just type "strip --strip-all <your executable file with path>" on the command line.<br />
<br />
If you want to make your program even smaller, you should try UPX ([http://upx.sourceforge.net/]) too. UPX is a very good exe compressor. It includes no memory overhead due to in-place decompression. It also has a very fast decompression (~10 MB/sec on an Pentium 133).<br />
<br />
To use upx just type "upx <your executable file with path>" on the command line.<br />
<br />
after using both strip and upx a simple GUI Lazarus program gets:<br />
* ~ 700kb on Linux<br />
* ~ 420kb on Windows<br />
<br />
=== Why is the linking so slow on Windows? ===<br />
<br />
Generally speaking, compilation on Windows takes more time then other platforms because the GNU Linker utilized by Free Pascal is slow on this platform.<br />
<br />
Also, as a test, Lazarus 0.9.12 was released with Smartlinked LCL. This means that executables are now about 30% smaller after strip and upx when compared to previous releases. This also means that the linking is much more complicated now and other GNU Linker problems appeared. A study about this is located here: [[File size and smartlinking]]<br />
<br />
This problem only affects Windows, and is only bad on relatively old computers (less then 1Ghz) and computers with little RAM (128MB or less).<br />
<br />
A internal linker is being developed. It should solve this, but will still take some time to be ready.<br />
<br />
But how to solve this in the mean time? You have two options:<br />
# Turn of smart linking. Unfortunately Lazarus unchecking the checkbox in Project -> Compiler Options -> Linking tab, is not enough. You must also add "-XS" to the custom options on the Other tab. If you compile your application, it will not use smartlinking.<br />
# Just recompile your LCL. Open Lazarus. Go on the menu "Tools" -> "Configure Build Lazarus". Set LCL to clean+build and everything else to None and click "Ok". Now go on "Tools" -> "Build Lazarus". Now your LCL is no longer smartlinked and the compilation should be much faster, but your exes will be bigger too.<br />
<br />
=== Do I need ppc386.cfg or fpc.cfg? ===<br />
<br />
You only need fpc.cfg. This way the compiler knows where to find the libraries.<br />
<br />
=== How do I compile lazarus? ===<br />
<br />
Do something like this:<br />
$ cd lazarus<br />
$ make clean all<br />
<br />
=== How do I build other projects based upon the LCL ===<br />
<br />
Add the following lines to the end of your fpc.cfg<br />
<br />
# Add Lazarus libs<br />
-Fu/your.lazarus.root/lcl/units<br />
-Fu/your.lazarus.root/lcl/units/{YourToolKit}<br />
-Fu/your.lazarus.root/components/units<br />
-Fu/your.lazarus.root/components/units/{YourToolKit}<br />
<br />
:Where {YourToolKit} may be GTK, Gnome or Win32 and run:<br />
::ppc386 your.project.pp<br />
<br />
=== What version of FPC is required? ===<br />
<br />
FPC Version 2.0.2 has been released, and that is the recommended version. You can also use the svn version of fpc 2.0.3 and 2.1.x.<br />
<br />
=== I can't compile Lazarus ===<br />
<br />
# Check if the compiler has the correct version<br />
# Check if the (fpc)libraries are from the same version.<br />
# Check if you have a fpc.cfg and no old ppc386.cfg<br />
# Check also the OS-dependent FAQs<br />
<br />
=== When I try to compile a project, I have an error ===<br />
==== "Cannot find Unit interfaces". How can I solve this?====<br />
This compiled unit can be found in {LazarusDir}\lcl\units\{TargetCPU}-{TargetOS}\{LCLWidgetSet}\interfaces.ppu. <br />
<br />
Make sure, it is only there. If you have multiple versions of interfaces.ppu, then you have probably have a wrong configuration (for instance you added a lcl directory to a search path). Remove all interfaces.ppu, but the one in the directory above.<br />
<br />
If you selected a different widgetset than you used to build lazarus, you need to build the LCL for this widgetset. <br />
<br />
If it is there, but you get this error, you are using a different compiler / rtl for compiling your project than you used for compiling your Lazarus IDE. You can do one of the following<br />
* Rebuild the LCL (or Lazarus completely) with the compiler selected in the Environmnent Options. You can this with Tools -> Build Lazarus. Before doing this, check the current settings in Tools -> Configure Build Lazarus.<br />
* Change the compiler in the Environment Options to the one you used to compile Lazarus. Look carefully also in the Environment Options to see if you are using the correct paths for the Lazarus Directory and the FPC sources directory. Check that there is only one version of the compiler configuration file fpc.cfg - it should reside in /etc/ for Linux/Unix systems or in the same directory as the fpc compiler for Windows systems. Rogue copies often creep in if you have updated your compiler to a new version; they may be found in your home directory or in the same directory as the one in which you built your new compiler. DELETE THESE!!<br />
<br />
=== When I try to compile delphi projects under lazarus, I have an error ===<br />
==== at the line :{$R *.DFM} How can I solve this problem ? ====<br />
<br />
Lazarus (or better Linux) doesn't know about resources, so you can't use them in the way Delphi/win32 does. However Lazarus uses a method pretty compatible with this. You can still use your Delphi layouts (.dfm files) if you use the following steps:<br />
<br />
*You need a textual version of the .dfm files. D5 and higher are doing this as default. If you have older files: ALT-F12 to see the layout as text and paste/copy. When you have a text .dfm file, just copy it to a .lfm file.<br />
*Create a file with lazres (in lazarus/tools) lazres yourform.lrs yourform.lfm<br />
*Add the following initialization section to<br />
<br />
initialization<br />
{$I yourform.lrs}<br />
<br />
Please keep in mind that not all properties in the dfm are supported yet by<br />
lazarus, so you might get a crash.<br />
<br />
==== 'Identifier not found LazarusResources'. ====<br />
<br />
When creating a form Lazarus automaticaly add some extra units to the uses section of your form unit. During the conversion of a delphi unit to a Lazarus unit this does not happen. So you need to add LResources to the Uses section of your form unit.<br />
<br />
=== When accessing events of objects e.g. the onclick event of a button I get the following error. ERROR unit not found: stdCtrls ===<br />
<br />
Make sure, in the Project -> Project Inspector, that your project depends on the package 'LCL' and that you have installed the FPC sources.<br />
<br />
Lazarus is the IDE and the visual components library LCL.<br />
All other stuff, like IO, Database, FCL and RTL are provided by FPC.<br />
The IDE needs the paths to all sources.<br />
<br />
The FPC source path can be set via:<br />
Environment -> General Options -> Files -> FPC source path<br />
<br />
===How to embed a small file in the executable, without the need of a separate file? How to embed a resource?===<br />
<br />
For example:<br />
/your/lazarus/path/tools/lazres sound.lrs sound1.wav sound2.wav ...<br />
will create sound.lrs from sound1.wav and sound2.wav.<br />
<br />
Then include it *behind* the form lrs file:<br />
<br />
...<br />
initialization<br />
{$i unit1.lrs} // this is main resource file (first)<br />
{$i sound.lrs} // user defined resource file<br />
<br />
end.<br />
In your program you can then use:<br />
Sound1AsString:=LazarusResources.Find('sound1').Value;<br />
<br />
=== How can I see debug output? ===<br />
<br />
The LCL has in the LCLProc procedure to write debug output: <br />
* '''DebugLn:''' works about the same as WriteLn, but accepts only strings.<br />
* '''DbgOut:''' works about the same as Write, but accepts only strings.<br />
<br />
In normal circumstances the output is written to stdout. If stdout is closed, (for example when the application is {$AppType Gui} or compiled with -WG on windows), no output is written.<br />
<br />
Debug output can also be written to file. The LCLProc unit checks in its initialization the command line parameters for '--debug-log=<file>'. If it finds it sends debug output to <file>.<br />
<br />
If it doesn't find a --debug-log command line parameter, it looks if an environment variable xxx_debuglog exists, where xxx is the program file name without extension. For lazarus this would be lazarus_debuglog. If <br />
such an environment variable exists, it uses that as file to write debug output to. Example: if you do:<br />
set lazarus_debuglog=c:\lazarus\debug.txt<br />
debug output will be written to c:\lazarus\debug.txt.<br />
<br />
Since this is implemented in lclproc, every application using lclproc, can use this output facility.<br />
<br />
;Debuging Lazarus : Most usefull for windows: If you want output on a console, add {$APPTYPE console} to lazarus.pp ; Then rebuild Lazarus.<br />
<br />
=== What is the meaning of the various file extensions used by Lazarus? ===<br />
<br />
The [[Lazarus Tutorial#The Lazarus files]] explains some extensions by an example.<br />
Here is a brief list:<br />
<br />
; <code>*.lpi</code> : Lazarus Project Information file (stored in XML; contains project-specific settings)<br />
; <code>*.lpr</code> : Lazarus Program file; contains Pascal source of main program<br />
; <code>*.lfm</code> : Lazarus Form file; contains configuration information for all objects on a form (stored in a Lazarus-specific format; the actions are described by Pascal source code in a corresponding <code>*.pas</code> file)<br />
; <code>*.pas</code> : Unit with Pascal code (typically for a form stored in a corresponding <code>*.lfm</code> file)<br />
; <code>*.lrs</code> : Lazarus Resource file (this is a generated file; not to be confused with a Windows resource file)<br />
; <code>*.ppu</code> : Compiled unit<br />
<br />
=== I have fixed/improved lazarus. How can I add my changes to the official lazarus source? ===<br />
Create a patch and send it to the developers. For details see [[Creating A Patch]].<br />
<br />
== Where is ... defined ==<br />
<br />
=== Virtual key constants ===<br />
Virtual key constants are defined in LCLType. Add LCLtype to your <b>uses</b>.<br />
<br />
== Using the IDE ==<br />
<br />
=== How can I use "identifier completion"? ===<br />
You can invoke identifier completion by pressing [ctrl][space].<br />
Under the menu item ''Environment -> Editor Options -> Code Tools -> Automatic Features'' you can set how quick this should happen automatically.<br />
<br />
== Linux ==<br />
<br />
=== How can I debug on Linux without the IDE? ===<br />
<br />
First of all you need a debugger. gdb is the standard debugger under linux and<br />
there are several GUI-frontends available. One common frontend is ddd, which is<br />
part of most common distributions. To compile lazarus/lcl with debug-information<br />
you should then use the following commands to start a debug session:<br />
<br />
$ make clean; make OPT=-dDEBUG<br />
$ ddd lazarus<br />
<br />
Be warned however, that ddd is not as comfortable as e.g. the Lazarus debugger.<br />
Specially if it comes to view the contents of a variable you have to take into<br />
account that ddd/gdb are case sensitive whereas Pascal is case-insensitive.<br />
Therefore you have to type all variable names in uppercase to see their<br />
contents. For more information take a look into the fpc-manuals.<br />
<br />
=== I can debug now but ddd does not find my sources or complains that they contain no code. Whats that? ===<br />
<br />
This is a path-related problem with either gdb or ddd. You can aviod this by<br />
<br />
* Use the "Change directory" command from the ddd menu and choose the directory where the sources are located. The drawback of this method is that you now can't use the source of the program you started with (e.g. lazarus). Thus it may be neccessary to change the directory multiple times.<br />
* In ddd goto [Edit] [gdb-settings] and set the search-path<br />
* Create a $(HOME)/.gdbinit file like:<br />
directory /your/path/to/lazarus<br />
directory /your/path/to/lazarus/lcl<br />
directory /your/path/to/lazarus/lcl/include<br />
<br />
=== I receive an error during the linking that states /usr/bin/ld can't find -l<some lib> ===<br />
<br />
; '''Package Based Distributions''' : You need to install the package that provides the lib<somelib>.so or lib<somelib>.a files. Dynamic libs under linux have the extension .so, while static libs have the extension .a. On some Linux distro's you have installed the package (rpm, deb) <packagename> which provides <some lib>, but you also need the development package (rpm, deb), normally called <packagename>-dev, which contains the .a (static lib) and/or the .so (dynamic lib).<br />
<br />
; '''Source Based Distributions and Manual Compilation (LFS)''' : Make sure that there is a lib<somelib>.a in the path, and that it contains the right version. To let the linker find the dynamic library, create a symlink called lib<some lib>.so to lib<some lib><version>-x,y.so if necessary (and/or for static lib; lib<some lib>.a to lib<some lib><version>-x,y.a).<br />
<br />
; '''FreeBSD''' : As source based distro's, and also make sure you have -Fl/usr/local/lib in your fpc.cfg and/or Lazarus library path. Keep in mind that GTK1.2 has "gtk12" as package name under FreeBSD. (same for glib)<br />
<br />
; '''NetBSD''' : As source based distro's, and also make sure you have -Fl/usr/pkg/lib in your fpc.cfg and/or Lazarus library path<br />
<br />
=== How can I convert a kylix 2 project into a lazarus project? ===<br />
<br />
Nearly the same way as converting a Kylix project into a Delphi/VCL project.<br />
<br />
The LCL (Lazarus Component Library) tries to be compatible to Delphis VCL.<br />
Kylix CLX tries to be QT compatible.<br />
Here are some general hints:<br />
<br />
* Rename all used CLX Q-units like QForms, QControls, QGraphics, ... into their VCL counterparts: Forms, Controls, Graphics, ...<br />
* Add LResources to the uses section of every form source<br />
* Rename or copy all .xfm files to .lfm files.<br />
* Rename or copy .dpr file to .lpr file.<br />
* Add "Interfaces" to the uses section in the .lpr file.<br />
* Remove {$R *.res} directive<br />
* Remove {$R *.xfm} directive<br />
* Add {$mode objfpc}{$H+} or {$mode delphi}{$H+} directive to .pas and .lpr files<br />
* Add an initialization section to the end of each form source and add an include directive for the .lrs file (lazarus resource file):<br />
initialization<br />
{$I unit1.lrs}<br />
:The .lrs files can be created via the lazres tool in: (lazarusdir)/tools/lazres.<br />
:For example: ./lazres unit1.lrs unit1.lfm<br />
<br />
* Fix the differences. The LCL does not yet support every property of the VCL and the CLX is not fully VCL compatible.<br />
<br />
=== When compiling lazarus the compiler can not find a unit. e.g.: gtkint.pp(17,16) Fatal: Can't find unit GLIB ===<br />
<br />
1. Check a clean rebuild: do a 'make clean all'<br />
<br />
2. Check if the compiler has the correct version (2.0.0 or higher)<br />
<br />
3. Check if the compiler is using the right config file. The normal installation creates /etc/fpc.cfg. But fpc also searches for ~/.ppc386.cfg, ~/.fpc.cfg, /etc/ppc386.cfg and it uses only the first it finds.<br />
<br />
:'''Hint:''' You can see which config file is used with 'ppc386 -vt bogus'<br />
:Remove any ppc386.cfg as it is really obsolete.<br />
<br />
4. Check if the config file (/etc/fpc.cfg) contains the right paths to your fpc libs. There must be three lines like this:<br />
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget<br />
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/rtl<br />
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/*<br />
:The first part of these paths (/usr/lib/fpc) depends on your system. On some systems this can be for example /usr/local/lib/fpc/... .<br />
:'''Hint:''' You can see your searchpaths with 'ppc386 -vt bogus'<br />
<br />
5. Check that the config file (/etc/fpc.cfg) does not contain search paths to the lcl source files (.pp, .pas):<br />
forbidden: -Fu(lazarus_source_directory)/lcl<br />
forbidden: -Fu(lazarus_source_directory)/lcl/interfaces/gtk<br />
:If you want to add the lcl for all your fpc projects, make sure that the two paths look like the following and are placed after the above fpc lib paths:<br />
-Fu(lazarus_source_directory)/lcl/units/$fpctarget<br />
-Fu(lazarus_source_directory)/lcl/units/$fpctarget/gtk<br />
<br />
6. Check if the missing unit (glib.ppu) exists in your fpc lib directory. For example the gtk.ppu can be found in /usr/lib/fpc/$version/units/i386-linux/gtk/. If it does not exists, the fpc lib is corrupt and should be reinstalled.<br />
<br />
7. Check if the sources are in a NFS mounted directory. In some cases the NFS updates created files incorrectly. Please, try to move the sources into a non NFS directory and compile there.<br />
<br />
=== I have installed the binary version, but when compiling a simple project, lazarus gives: Fatal: Can't find unit CONTROLS ===<br />
<br />
Probably you are using a newer fpc package, than that used for building the<br />
lazarus binaries. The best solution is to download the sources and compile<br />
lazarus manually. You can download the source snapshot or get the source<br />
via svn:<br />
<br />
$ bash<br />
$ svn checkout http://svn.freepascal.org/svn/lazarus/trunk lazarus<br />
$ cd lazarus<br />
$ make clean all<br />
<br />
Make sure that lazarus get the new source directory:<br />
Environment->General Options->Files->Lazarus Directory Top<br />
<br />
===Lazarus compiles, but linking fails with: libgdk-pixbuf not found===<br />
Either install the gdk-pixbuf library for gtk1.x or disable the use:<br />
<br />
Where to find the gdk-pixbuf library:<br />
<br />
RPMs:<br />
http://rpmfind.net/linux/rpm2html/search.php?query=gdk-pixbuf&submit=Search+...&system=&arch=<br />
<br />
Debian packages:<br />
libgdk-pixbuf-dev<br />
<br />
Sources:<br />
ftp://ftp.gnome.org/pub/gnome/unstable/sources/gdk-pixbuf/<br />
<br />
<br />
How to disable the use in lazarus: In Tools->Configure "Build Lazarus" add the option<br />
'-dNoGdkPixBufLib'<br />
or at command line:<br />
"make clean all OPT=-dNoGdkPixBufLib".<br />
<br />
===I have SuSE and I get /usr/bin/ld: cannot find -lgtk Error: Error while linking===<br />
SuSE installs the gtk devel libs under /opt/gnome/lib (or /opt/gnome/lib64 for 64 bits), which is not in<br />
the standard lib path. Simply add it to your /etc/fpc.cfg.<br />
(-Fl/opt/gnome/lib).<br />
<br />
===Lazarus crashes with runtime error 211 after I installed a component===<br />
After I installed a component, Lazarus crashes with the following message:<br />
Threading has been used before cthreads was initialized.<br />
Make cthreads one of the first units in your uses clause.<br />
Runtime error 211 at $0066E188<br />
How can I fix this?<br />
<br />
Your freshly installed component is using threads. Fpc on *nix doesn't automatically include threading support, but it must be intialized. This initialization is done in the cthreads unit. Every application using the component needs to add this unit to the uses clause of the main program. Lazarus itself is no exception. This can be done in two ways:<br />
<br />
1) Change the source of ide/lazarus.pp: add the cthreads as first unit to the uses clause, so that is looks like this:<br />
uses<br />
//cmem,<br />
cthreads, <br />
{$IFDEF IDE_MEM_CHECK}<br />
...<br />
and rebuild lazarus.<br />
<br />
2) In order to avoid modifying lazarus.pp file, a fpc compiler option could be used. Once package that uses threads has been compiled, open menu Tools->Configure "build Lazarus". Configure "build Lazarus" dialog will be shown, in field "Options:" type -Facthreads and then press "OK" button. The next step is to install the package. Lazarus will be built with option -Facthreads which means that it will treat main program as if unit cthreads where first in uses clause. <br />
<br />
''Hint:'' Maybe your old (non-crashing) lazarus executable is stored as lazarus.old in the same directory as the crashing lazarus executable.<br />
<br />
===When I run a program with threads I get runtime error 232===<br />
The complete error message is:<br />
This binary has no thread support compiled in.<br />
Recompile the application with a thread-driver in the program uses<br />
clause before other units using thread.<br />
Runtime error 232<br />
'''Solution''': Add cthreads as first unit to the uses clause of your main program, usually the .lpr-file.<br />
<br />
===I have Ubuntu Breezy and my fonts in Lazarus IDE look too big===<br />
If Lazarus is compiled with Gtk1.2, the settings in Gnome Preferences/Font don't have any effect as<br />
they are related to Gtk2.<br />
You could try this solution:<br />
Create a file named .gtkrc.mine in your home directory (if it's not already there) and add<br />
these lines to it:<br />
<br />
<pre><br />
style "default-text" {<br />
fontset = "-*-arial-medium-r-normal--*-100-*-*-*-*-iso8859-1,\<br />
-*-helvetica-medium-r-normal--*-100-*-*-*-*-*-*"<br />
}<br />
<br />
class "GtkWidget" style "default-text"<br />
</pre><br />
<br />
===How can I compile a program for Gtk2?===<br />
<br />
At the moment, the Gtk2 compiled IDE is a little unstable, but you can compile software for Gtk2 using the Gtk1 IDE.<br />
<br />
To start with recompile LCL for Gtk2. Go to the menu "Tools"->"Configure Build Lazarus" and set LCL to clean+build and everything else to none.<br />
<br />
Now click Ok and go to the menu "Tools"->"Build Lazarus"<br />
<br />
Now you can compile your software with Gtk2 going on the Compiler options and changing the widgetset to Gtk2.<br />
<br />
== Windows ==<br />
<br />
=== When I cycle the compiler, I get:The name specified is not recognized as an internal or external command, operable program or batch file.>& was unexpected at this time. ===<br />
<br />
In the compiler dir exists an OS2 scriptfile named make.cmd. NT sees this also<br />
as a script file, so remove it since on NT we don't need it.<br />
<br />
=== When I cycle the compiler, I get: make[3]: ./ppc1.exe: Command not found ===<br />
<br />
I don't know why but somehow make has lost its path. Try to cycle with a<br />
basedir set like: make cycle BASEDIR=your_fpc_source_dir_herecompiler<br />
<br />
=== When I try to make Lazarus I get:===<br />
====make.exe: * * * interfaces: No such file or directory (ENOENT). Stop.make.exe: * * * [interfaces_all] Error 2 ====<br />
You need to upgrade your make.<br />
<br />
====makefile:27: *** You need the GNU utils package to use this Makefile. Stop.====<br />
Make sure you didn't install FPC in a path with spaces in the name. The<br />
Makefile doesn't support it.<br />
<br />
<br />
<br />
===How can I give my program an XP look like lazarus has?===<br />
If you have a myprogram.exe then create a file which called myprogram.exe.manifest and copy-paste<br />
this to the file:<br />
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><br />
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><br />
<assemblyIdentity processorArchitecture="*" version="1.0.0.0" type="win32" name="myprogram"/><br />
<description>programom</description><br />
<dependency><br />
<dependentAssembly><br />
<assemblyIdentity<br />
type="win32"<br />
name="Microsoft.Windows.Common-Controls"<br />
version="6.0.0.0"<br />
publicKeyToken="6595b64144ccf1df"<br />
language="*"<br />
processorArchitecture="*" /><br />
</dependentAssembly><br />
</dependency><br />
</assembly><br />
Voila! XP looks.<br />
<br />
===When I run Windows program created in Lazarus it starts with a DOS window===<br />
Specify the -WG argument (Windows GUI) on the command line of the compiler or in the Lazarus IDE check the Windows GUI check box on the compiler options dialog box (Project menu -> Compiler Options -> Linking -> target OS Specific options.<br />
<br />
<br />
== Contributors and Comments ==<br />
<br />
This page has been converted from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=LazarusFaq version].</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Lazarus_FAQ&diff=5995Lazarus FAQ2006-03-29T12:30:01Z<p>Wstomv: /* What version of FPC is required? */ Updated (needs to be updated elsewhere as well!)</p>
<hr />
<div>{{Lazarus Faq}}<br />
<br />
This FAQ is being copied from the FAQ at www.freepascal.org, as this wiki document is easier to maintain and extend.<br />
<br />
== General ==<br />
<br />
=== Where can I find more FAQ? ===<br />
<br />
See the official website www.lazarus.freepascal.org. There is another FAQ as well. <br />
<br />
===Why are the generated binaries so big?===<br />
The binaries are big because they include a lot of debug information necessary for using gdb (GNU Debugger).<br />
<br />
The compiler has an option to remove the debug information from the executable (-Xs), but due to a bug in the compiler (version 2.0.2 and earlier), this doesn't work correctly. It has been fixed in the development version of the compiler.<br />
<br />
You can use a program called "strip" to remove the debug symbols from the executable file. It is located under lazarus dir lazarus\pp\bin\i386-win32\.<br />
<br />
Just type "strip --strip-all <your executable file with path>" on the command line.<br />
<br />
If you want to make your program even smaller, you should try UPX ([http://upx.sourceforge.net/]) too. UPX is a very good exe compressor. It includes no memory overhead due to in-place decompression. It also has a very fast decompression (~10 MB/sec on an Pentium 133).<br />
<br />
To use upx just type "upx <your executable file with path>" on the command line.<br />
<br />
after using both strip and upx a simple GUI Lazarus program gets:<br />
* ~ 700kb on Linux<br />
* ~ 420kb on Windows<br />
<br />
=== Why is the linking so slow on Windows? ===<br />
<br />
Generally speaking, compilation on Windows takes more time then other platforms because the GNU Linker utilized by Free Pascal is slow on this platform.<br />
<br />
Also, as a test, Lazarus 0.9.12 was released with Smartlinked LCL. This means that executables are now about 30% smaller after strip and upx when compared to previous releases. This also means that the linking is much more complicated now and other GNU Linker problems appeared. A study about this is located here: [[File size and smartlinking]]<br />
<br />
This problem only affects Windows, and is only bad on relatively old computers (less then 1Ghz) and computers with little RAM (128MB or less).<br />
<br />
A internal linker is being developed. It should solve this, but will still take some time to be ready.<br />
<br />
But how to solve this in the mean time? You have two options:<br />
# Turn of smart linking. Unfortunately Lazarus unchecking the checkbox in Project -> Compiler Options -> Linking tab, is not enough. You must also add "-XS" to the custom options on the Other tab. If you compile your application, it will not use smartlinking.<br />
# Just recompile your LCL. Open Lazarus. Go on the menu "Tools" -> "Configure Build Lazarus". Set LCL to clean+build and everything else to None and click "Ok". Now go on "Tools" -> "Build Lazarus". Now your LCL is no longer smartlinked and the compilation should be much faster, but your exes will be bigger too.<br />
<br />
=== Do I need ppc386.cfg or fpc.cfg? ===<br />
<br />
You only need fpc.cfg. This way the compiler knows where to find the libraries.<br />
<br />
=== How do I compile lazarus? ===<br />
<br />
Do something like this:<br />
$ cd lazarus<br />
$ make clean all<br />
<br />
=== How do I build other projects based upon the LCL ===<br />
<br />
Add the following lines to the end of your fpc.cfg<br />
<br />
# Add Lazarus libs<br />
-Fu/your.lazarus.root/lcl/units<br />
-Fu/your.lazarus.root/lcl/units/{YourToolKit}<br />
-Fu/your.lazarus.root/components/units<br />
-Fu/your.lazarus.root/components/units/{YourToolKit}<br />
<br />
:Where {YourToolKit} may be GTK, Gnome or Win32 and run:<br />
::ppc386 your.project.pp<br />
<br />
=== What version of FPC is required? ===<br />
<br />
FPC Version 2.0.2 has been released, and that is the recommended version. You can also use the svn version of fpc 2.1.x.<br />
<br />
=== I can't compile Lazarus ===<br />
<br />
# Check if the compiler has the correct version<br />
# Check if the (fpc)libraries are from the same version.<br />
# Check if you have a fpc.cfg and no old ppc386.cfg<br />
# Check also the OS-dependent FAQs<br />
<br />
=== When I try to compile a project, I have an error ===<br />
==== "Cannot find Unit interfaces". How can I solve this?====<br />
This compiled unit can be found in {LazarusDir}\lcl\units\{TargetCPU}-{TargetOS}\{LCLWidgetSet}\interfaces.ppu. <br />
<br />
Make sure, it is only there. If you have multiple versions of interfaces.ppu, then you have probably have a wrong configuration (for instance you added a lcl directory to a search path). Remove all interfaces.ppu, but the one in the directory above.<br />
<br />
If you selected a different widgetset than you used to build lazarus, you need to build the LCL for this widgetset. <br />
<br />
If it is there, but you get this error, you are using a different compiler / rtl for compiling your project than you used for compiling your Lazarus IDE. You can do one of the following<br />
* Rebuild the LCL (or Lazarus completely) with the compiler selected in the Environmnent Options. You can this with Tools -> Build Lazarus. Before doing this, check the current settings in Tools -> Configure Build Lazarus.<br />
* Change the compiler in the Environment Options to the one you used to compile Lazarus. Look carefully also in the Environment Options to see if you are using the correct paths for the Lazarus Directory and the FPC sources directory. Check that there is only one version of the compiler configuration file fpc.cfg - it should reside in /etc/ for Linux/Unix systems or in the same directory as the fpc compiler for Windows systems. Rogue copies often creep in if you have updated your compiler to a new version; they may be found in your home directory or in the same directory as the one in which you built your new compiler. DELETE THESE!!<br />
<br />
=== When I try to compile delphi projects under lazarus, I have an error ===<br />
==== at the line :{$R *.DFM} How can I solve this problem ? ====<br />
<br />
Lazarus (or better Linux) doesn't know about resources, so you can't use them in the way Delphi/win32 does. However Lazarus uses a method pretty compatible with this. You can still use your Delphi layouts (.dfm files) if you use the following steps:<br />
<br />
*You need a textual version of the .dfm files. D5 and higher are doing this as default. If you have older files: ALT-F12 to see the layout as text and paste/copy. When you have a text .dfm file, just copy it to a .lfm file.<br />
*Create a file with lazres (in lazarus/tools) lazres yourform.lrs yourform.lfm<br />
*Add the following initialization section to<br />
<br />
initialization<br />
{$I yourform.lrs}<br />
<br />
Please keep in mind that not all properties in the dfm are supported yet by<br />
lazarus, so you might get a crash.<br />
<br />
==== 'Identifier not found LazarusResources'. ====<br />
<br />
When creating a form Lazarus automaticaly add some extra units to the uses section of your form unit. During the conversion of a delphi unit to a Lazarus unit this does not happen. So you need to add LResources to the Uses section of your form unit.<br />
<br />
=== When accessing events of objects e.g. the onclick event of a button I get the following error. ERROR unit not found: stdCtrls ===<br />
<br />
Make sure, in the Project -> Project Inspector, that your project depends on the package 'LCL' and that you have installed the FPC sources.<br />
<br />
Lazarus is the IDE and the visual components library LCL.<br />
All other stuff, like IO, Database, FCL and RTL are provided by FPC.<br />
The IDE needs the paths to all sources.<br />
<br />
The FPC source path can be set via:<br />
Environment -> General Options -> Files -> FPC source path<br />
<br />
===How to embed a small file in the executable, without the need of a separate file? How to embed a resource?===<br />
<br />
For example:<br />
/your/lazarus/path/tools/lazres sound.lrs sound1.wav sound2.wav ...<br />
will create sound.lrs from sound1.wav and sound2.wav.<br />
<br />
Then include it *behind* the form lrs file:<br />
<br />
...<br />
initialization<br />
{$i unit1.lrs} // this is main resource file (first)<br />
{$i sound.lrs} // user defined resource file<br />
<br />
end.<br />
In your program you can then use:<br />
Sound1AsString:=LazarusResources.Find('sound1').Value;<br />
<br />
=== How can I see debug output? ===<br />
<br />
The LCL has in the LCLProc procedure to write debug output: <br />
* '''DebugLn:''' works about the same as WriteLn, but accepts only strings.<br />
* '''DbgOut:''' works about the same as Write, but accepts only strings.<br />
<br />
In normal circumstances the output is written to stdout. If stdout is closed, (for example when the application is {$AppType Gui} or compiled with -WG on windows), no output is written.<br />
<br />
Debug output can also be written to file. The LCLProc unit checks in its initialization the command line parameters for '--debug-log=<file>'. If it finds it sends debug output to <file>.<br />
<br />
If it doesn't find a --debug-log command line parameter, it looks if an environment variable xxx_debuglog exists, where xxx is the program file name without extension. For lazarus this would be lazarus_debuglog. If <br />
such an environment variable exists, it uses that as file to write debug output to. Example: if you do:<br />
set lazarus_debuglog=c:\lazarus\debug.txt<br />
debug output will be written to c:\lazarus\debug.txt.<br />
<br />
Since this is implemented in lclproc, every application using lclproc, can use this output facility.<br />
<br />
;Debuging Lazarus : Most usefull for windows: If you want output on a console, add {$APPTYPE console} to lazarus.pp ; Then rebuild Lazarus.<br />
<br />
=== I have fixed/improved lazarus. How can I add my changes to the official lazarus source? ===<br />
Create a patch and send it to the developers. For details see [[Creating A Patch]].<br />
<br />
== Where is ... defined ==<br />
<br />
=== Virtual key constants ===<br />
Virtual key constants are defined in LCLType. Add LCLtype to your <b>uses</b>.<br />
<br />
== Using the IDE ==<br />
<br />
=== How can I use "identifier completion"? ===<br />
You can invoke identifier completion by pressing [ctrl][space].<br />
Under the menu item ''Environment -> Editor Options -> Code Tools -> Automatic Features'' you can set how quick this should happen automatically.<br />
<br />
== Linux ==<br />
<br />
=== How can I debug on Linux without the IDE? ===<br />
<br />
First of all you need a debugger. gdb is the standard debugger under linux and<br />
there are several GUI-frontends available. One common frontend is ddd, which is<br />
part of most common distributions. To compile lazarus/lcl with debug-information<br />
you should then use the following commands to start a debug session:<br />
<br />
$ make clean; make OPT=-dDEBUG<br />
$ ddd lazarus<br />
<br />
Be warned however, that ddd is not as comfortable as e.g. the Lazarus debugger.<br />
Specially if it comes to view the contents of a variable you have to take into<br />
account that ddd/gdb are case sensitive whereas Pascal is case-insensitive.<br />
Therefore you have to type all variable names in uppercase to see their<br />
contents. For more information take a look into the fpc-manuals.<br />
<br />
=== I can debug now but ddd does not find my sources or complains that they contain no code. Whats that? ===<br />
<br />
This is a path-related problem with either gdb or ddd. You can aviod this by<br />
<br />
* Use the "Change directory" command from the ddd menu and choose the directory where the sources are located. The drawback of this method is that you now can't use the source of the program you started with (e.g. lazarus). Thus it may be neccessary to change the directory multiple times.<br />
* In ddd goto [Edit] [gdb-settings] and set the search-path<br />
* Create a $(HOME)/.gdbinit file like:<br />
directory /your/path/to/lazarus<br />
directory /your/path/to/lazarus/lcl<br />
directory /your/path/to/lazarus/lcl/include<br />
<br />
=== I receive an error during the linking that states /usr/bin/ld can't find -l<some lib> ===<br />
<br />
; '''Package Based Distributions''' : You need to install the package that provides the lib<somelib>.so or lib<somelib>.a files. Dynamic libs under linux have the extension .so, while static libs have the extension .a. On some Linux distro's you have installed the package (rpm, deb) <packagename> which provides <some lib>, but you also need the development package (rpm, deb), normally called <packagename>-dev, which contains the .a (static lib) and/or the .so (dynamic lib).<br />
<br />
; '''Source Based Distributions and Manual Compilation (LFS)''' : Make sure that there is a lib<somelib>.a in the path, and that it contains the right version. To let the linker find the dynamic library, create a symlink called lib<some lib>.so to lib<some lib><version>-x,y.so if necessary (and/or for static lib; lib<some lib>.a to lib<some lib><version>-x,y.a).<br />
<br />
; '''FreeBSD''' : As source based distro's, and also make sure you have -Fl/usr/local/lib in your fpc.cfg and/or Lazarus library path. Keep in mind that GTK1.2 has "gtk12" as package name under FreeBSD. (same for glib)<br />
<br />
; '''NetBSD''' : As source based distro's, and also make sure you have -Fl/usr/pkg/lib in your fpc.cfg and/or Lazarus library path<br />
<br />
=== How can I convert a kylix 2 project into a lazarus project? ===<br />
<br />
Nearly the same way as converting a Kylix project into a Delphi/VCL project.<br />
<br />
The LCL (Lazarus Component Library) tries to be compatible to Delphis VCL.<br />
Kylix CLX tries to be QT compatible.<br />
Here are some general hints:<br />
<br />
* Rename all used CLX Q-units like QForms, QControls, QGraphics, ... into their VCL counterparts: Forms, Controls, Graphics, ...<br />
* Add LResources to the uses section of every form source<br />
* Rename or copy all .xfm files to .lfm files.<br />
* Rename or copy .dpr file to .lpr file.<br />
* Add "Interfaces" to the uses section in the .lpr file.<br />
* Remove {$R *.res} directive<br />
* Remove {$R *.xfm} directive<br />
* Add {$mode objfpc}{$H+} or {$mode delphi}{$H+} directive to .pas and .lpr files<br />
* Add an initialization section to the end of each form source and add an include directive for the .lrs file (lazarus resource file):<br />
initialization<br />
{$I unit1.lrs}<br />
:The .lrs files can be created via the lazres tool in: (lazarusdir)/tools/lazres.<br />
:For example: ./lazres unit1.lrs unit1.lfm<br />
<br />
* Fix the differences. The LCL does not yet support every property of the VCL and the CLX is not fully VCL compatible.<br />
<br />
=== When compiling lazarus the compiler can not find a unit. e.g.: gtkint.pp(17,16) Fatal: Can't find unit GLIB ===<br />
<br />
1. Check a clean rebuild: do a 'make clean all'<br />
<br />
2. Check if the compiler has the correct version (2.0.0 or higher)<br />
<br />
3. Check if the compiler is using the right config file. The normal installation creates /etc/fpc.cfg. But fpc also searches for ~/.ppc386.cfg, ~/.fpc.cfg, /etc/ppc386.cfg and it uses only the first it finds.<br />
<br />
:'''Hint:''' You can see which config file is used with 'ppc386 -vt bogus'<br />
:Remove any ppc386.cfg as it is really obsolete.<br />
<br />
4. Check if the config file (/etc/fpc.cfg) contains the right paths to your fpc libs. There must be three lines like this:<br />
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget<br />
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/rtl<br />
-Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/*<br />
:The first part of these paths (/usr/lib/fpc) depends on your system. On some systems this can be for example /usr/local/lib/fpc/... .<br />
:'''Hint:''' You can see your searchpaths with 'ppc386 -vt bogus'<br />
<br />
5. Check that the config file (/etc/fpc.cfg) does not contain search paths to the lcl source files (.pp, .pas):<br />
forbidden: -Fu(lazarus_source_directory)/lcl<br />
forbidden: -Fu(lazarus_source_directory)/lcl/interfaces/gtk<br />
:If you want to add the lcl for all your fpc projects, make sure that the two paths look like the following and are placed after the above fpc lib paths:<br />
-Fu(lazarus_source_directory)/lcl/units/$fpctarget<br />
-Fu(lazarus_source_directory)/lcl/units/$fpctarget/gtk<br />
<br />
6. Check if the missing unit (glib.ppu) exists in your fpc lib directory. For example the gtk.ppu can be found in /usr/lib/fpc/$version/units/i386-linux/gtk/. If it does not exists, the fpc lib is corrupt and should be reinstalled.<br />
<br />
7. Check if the sources are in a NFS mounted directory. In some cases the NFS updates created files incorrectly. Please, try to move the sources into a non NFS directory and compile there.<br />
<br />
=== I have installed the binary version, but when compiling a simple project, lazarus gives: Fatal: Can't find unit CONTROLS ===<br />
<br />
Probably you are using a newer fpc package, than that used for building the<br />
lazarus binaries. The best solution is to download the sources and compile<br />
lazarus manually. You can download the source snapshot or get the source<br />
via svn:<br />
<br />
$ bash<br />
$ svn checkout http://svn.freepascal.org/svn/lazarus/trunk lazarus<br />
$ cd lazarus<br />
$ make clean all<br />
<br />
Make sure that lazarus get the new source directory:<br />
Environment->General Options->Files->Lazarus Directory Top<br />
<br />
===Lazarus compiles, but linking fails with: libgdk-pixbuf not found===<br />
Either install the gdk-pixbuf library for gtk1.x or disable the use:<br />
<br />
Where to find the gdk-pixbuf library:<br />
<br />
RPMs:<br />
http://rpmfind.net/linux/rpm2html/search.php?query=gdk-pixbuf&submit=Search+...&system=&arch=<br />
<br />
Debian packages:<br />
libgdk-pixbuf-dev<br />
<br />
Sources:<br />
ftp://ftp.gnome.org/pub/gnome/unstable/sources/gdk-pixbuf/<br />
<br />
<br />
How to disable the use in lazarus: In Tools->Configure "Build Lazarus" add the option<br />
'-dNoGdkPixBufLib'<br />
or at command line:<br />
"make clean all OPT=-dNoGdkPixBufLib".<br />
<br />
===I have SuSE and I get /usr/bin/ld: cannot find -lgtk Error: Error while linking===<br />
SuSE installs the gtk devel libs under /opt/gnome/lib (or /opt/gnome/lib64 for 64 bits), which is not in<br />
the standard lib path. Simply add it to your /etc/fpc.cfg.<br />
(-Fl/opt/gnome/lib).<br />
<br />
===Lazarus crashes with runtime error 211 after I installed a component===<br />
After I installed a component, Lazarus crashes with the following message:<br />
Threading has been used before cthreads was initialized.<br />
Make cthreads one of the first units in your uses clause.<br />
Runtime error 211 at $0066E188<br />
How can I fix this?<br />
<br />
Your freshly installed component is using threads. Fpc on *nix doesn't automatically include threading support, but it must be intialized. This initialization is done in the cthreads unit. Every application using the component needs to add this unit to the uses clause of the main program. Lazarus itself is no exception. This can be done in two ways:<br />
<br />
1) Change the source of ide/lazarus.pp: add the cthreads as first unit to the uses clause, so that is looks like this:<br />
uses<br />
//cmem,<br />
cthreads, <br />
{$IFDEF IDE_MEM_CHECK}<br />
...<br />
and rebuild lazarus.<br />
<br />
2) In order to avoid modifying lazarus.pp file, a fpc compiler option could be used. Once package that uses threads has been compiled, open menu Tools->Configure "build Lazarus". Configure "build Lazarus" dialog will be shown, in field "Options:" type -Facthreads and then press "OK" button. The next step is to install the package. Lazarus will be built with option -Facthreads which means that it will treat main program as if unit cthreads where first in uses clause. <br />
<br />
''Hint:'' Maybe your old (non-crashing) lazarus executable is stored as lazarus.old in the same directory as the crashing lazarus executable.<br />
<br />
===When I run a program with threads I get runtime error 232===<br />
The complete error message is:<br />
This binary has no thread support compiled in.<br />
Recompile the application with a thread-driver in the program uses<br />
clause before other units using thread.<br />
Runtime error 232<br />
'''Solution''': Add cthreads as first unit to the uses clause of your main program, usually the .lpr-file.<br />
<br />
===I have Ubuntu Breezy and my fonts in Lazarus IDE look too big===<br />
If Lazarus is compiled with Gtk1.2, the settings in Gnome Preferences/Font don't have any effect as<br />
they are related to Gtk2.<br />
You could try this solution:<br />
Create a file named .gtkrc.mine in your home directory (if it's not already there) and add<br />
these lines to it:<br />
<br />
<pre><br />
style "default-text" {<br />
fontset = "-*-arial-medium-r-normal--*-100-*-*-*-*-iso8859-1,\<br />
-*-helvetica-medium-r-normal--*-100-*-*-*-*-*-*"<br />
}<br />
<br />
class "GtkWidget" style "default-text"<br />
</pre><br />
<br />
===How can I compile a program for Gtk2?===<br />
<br />
At the moment, the Gtk2 compiled IDE is a little unstable, but you can compile software for Gtk2 using the Gtk1 IDE.<br />
<br />
To start with recompile LCL for Gtk2. Go to the menu "Tools"->"Configure Build Lazarus" and set LCL to clean+build and everything else to none.<br />
<br />
Now click Ok and go to the menu "Tools"->"Build Lazarus"<br />
<br />
Now you can compile your software with Gtk2 going on the Compiler options and changing the widgetset to Gtk2.<br />
<br />
== Windows ==<br />
<br />
=== When I cycle the compiler, I get:The name specified is not recognized as an internal or external command, operable program or batch file.>& was unexpected at this time. ===<br />
<br />
In the compiler dir exists an OS2 scriptfile named make.cmd. NT sees this also<br />
as a script file, so remove it since on NT we don't need it.<br />
<br />
=== When I cycle the compiler, I get: make[3]: ./ppc1.exe: Command not found ===<br />
<br />
I don't know why but somehow make has lost its path. Try to cycle with a<br />
basedir set like: make cycle BASEDIR=your_fpc_source_dir_herecompiler<br />
<br />
=== When I try to make Lazarus I get:===<br />
====make.exe: * * * interfaces: No such file or directory (ENOENT). Stop.make.exe: * * * [interfaces_all] Error 2 ====<br />
You need to upgrade your make.<br />
<br />
====makefile:27: *** You need the GNU utils package to use this Makefile. Stop.====<br />
Make sure you didn't install FPC in a path with spaces in the name. The<br />
Makefile doesn't support it.<br />
<br />
<br />
<br />
===How can I give my program an XP look like lazarus has?===<br />
If you have a myprogram.exe then create a file which called myprogram.exe.manifest and copy-paste<br />
this to the file:<br />
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><br />
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><br />
<assemblyIdentity processorArchitecture="*" version="1.0.0.0" type="win32" name="myprogram"/><br />
<description>programom</description><br />
<dependency><br />
<dependentAssembly><br />
<assemblyIdentity<br />
type="win32"<br />
name="Microsoft.Windows.Common-Controls"<br />
version="6.0.0.0"<br />
publicKeyToken="6595b64144ccf1df"<br />
language="*"<br />
processorArchitecture="*" /><br />
</dependentAssembly><br />
</dependency><br />
</assembly><br />
Voila! XP looks.<br />
<br />
===When I run Windows program created in Lazarus it starts with a DOS window===<br />
Specify the -WG argument (Windows GUI) on the command line of the compiler or in the Lazarus IDE check the Windows GUI check box on the compiler options dialog box (Project menu -> Compiler Options -> Linking -> target OS Specific options.<br />
<br />
<br />
== Contributors and Comments ==<br />
<br />
This page has been converted from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=LazarusFaq version].</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Code_Conversion_Guide&diff=2461Code Conversion Guide2005-08-10T09:00:36Z<p>Wstomv: /* Converting Delphi projects/forms/units to Lazarus */</p>
<hr />
<div>Delphi to Lazarus Code Conversion Guide<br />
<br />
== About ==<br />
<br />
This page is about how to convert existing code to work with the [[Free Pascal]] Compiler and Lazarus IDE. While Lazarus and the Free Pascal Compiler have aspects in common with Delphi and Kylix, they are not clones. There are a number of library call and convention differences... and in some areas, FPC is enhanced and can be more demanding about correct syntax. Please see the [[Lazarus For Delphi Users]] guide for a description of some of the functional differences. <br />
<br />
The purpose of this guide is to document some of the specific differences that are frequently encountered during the code conversion process when translating existing code from Delphi to Lazarus.<br />
<br />
This document was placed into the wiki knowledge-base area so it could be easily extended by anyone who had encountered a unique problem and would like to post it for others to be aware of.<br />
<br />
== Selecting a component or library for conversion ==<br />
<br />
=== Where to find code to convert ===<br />
<br />
There is a LOT of code available on the net that can be converted for use with FPC and Lazarus. Here is a [PageOfCodeSites|] that is just a start. Please add to it if you know of any other good locations. Turbo-Power Software has recently released their entire commercial offering under the MPL. A list of available packages can be found [http://sourceforge.net/users/tpsfadmin/|here].<br />
<br />
To avoid duplicating effort, packages that have already been converted are listed on the [CodeAndComponents|] page. If you've converted a package or are working on one, please add a note on the [CurrentProjects|] page.<br />
<br />
=== Licensing ===<br />
<br />
Licenses for existing code range from freeware/public domain to restrictive versions that prohibit modification, re-distribution and commercial use. Before converting any package, it's a good idea to examine its licensing and make sure it's going to be compatible with Lazarus and the Free Pascal Compiler. License selection is especially important with components since dropping one on a form can impose an unwanted or incompatible license on an entire application.<br />
<br />
When converting components, please respect the wishes of the original author and retain all copyright and licensing headers along with email addresses and url's. It's courteous and often useful to inform the author that their component is being converted... especially if the component is under a restrictive license. New interest in an old or forgotten component can sometimes inspire authors to revise their original and overly restrictive licensing.<br />
<br />
In general, Public Domain (freeware), and the LGPL/MPL are the the most flexible for distributing components. For more information, the [http://www.opensource.org/docs/definition.php Open Source Definition] is a good place to start. There are also several comparisons available to help clarify how the various types of licenses work and what impact they'll have on code they're linked to. Search for "open source license comparison"<br />
<br />
=== Dependencies ===<br />
<br />
Another step before starting to work on a conversion is to verify that the code doesn't have deep dependancies on other packages that might not be available or represent a considerable conversion challenge. Some freeware offerings are bound to or extend proprietary packages that are frequently no longer available or come with inappropriate licenses.<br />
<br />
=== Compiler Issues ===<br />
<br />
Currently the stable 1.0.x version of the Free Pascal Compiler doesn't support interfaces, threads or Variant records. If the code you're converting needs these constructs, you'll have to use the 1.1 development branch of the compiler... which isn't always guaranteed to work with Lazarus.<br />
<br />
=== Platform and OS Issues ===<br />
<br />
Lazarus and the Free Pascal Compiler are cross-platform and cross-architecture development tools. In contrast, most existing Delphi code was specifically designed to run on an Intel processor under Win32. If your candidate component has a lot of Win32 specific code, it might be wise to try and find a less platform dependant alternative. But don't let this stop you... it's genuinely amazing what the LCL supports!<br />
<br />
== Doing the conversion ==<br />
<br />
=== Setting up the Lazarus environment for a conversion project ===<br />
<br />
====Create a test project====<br />
* Place code to be converted into a subdirectory (ie: convertdir)<br />
* Bring up Lazarus<br />
* File->Save All to the convertdir subdirectory. Meaningful names for the Project and default unit are optional.<br />
* Open the "main" unit to be converted in convertdir<br />
* Add it to the project: Project->Add Active Unit to Project<br />
* Run Tools->Quick Syntax Check or Run Build All to get started.<br />
====Initial items to watch out for====<br />
* Filenames are case sensitive with the 1.0.x series compilers. If you're working with this version, make all your filenames lower case. You'll get "File not found" errors if you don't.<br />
====Delphi VCL, Kylix CLX Sources in Lazarus====<br />
<br />
When converting Delphi/Kylix sources, it is often useful to do a find declaration to see, what a specific function is doing. The Lazarus IDE can parse the Delphi/Kylix sources. To do this it needs some searchpaths and compiler settings. You can easily setup this in<br />
Environment->CodeTools Defines Editor->Insert Template<br />
<br />
=== Conversion problems and solutions ===<br />
<br />
==== Delphi / Kylix file equivalents in Lazarus ====<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi / Kylix || class="header" | Lazarus || class="header" | Description<br />
|- class="code"<br />
| class="code" |.pas<br />
.dfm / .xfm<br />
.dcu / .dpu<br />
.dpr<br />
.res<br />
.dof / .kof<br />
---<br />
---<br />
---<br />
| class="code" |.pas, .pp<br />
.lfm<br />
.o<br />
.lpr<br />
---<br />
---<br />
.lrs<br />
.lpi<br />
.ppu<br />
| class="code" |Pascal unit file<br />
Form data file<br />
Compiled unit file<br />
Project file<br />
Resource file<br />
Project options file<br />
Lazarus resource file<br />
Lazarus project information file<br />
FPC unit description file<br />
|}<br />
<br />
==== Converting Delphi projects/forms/units to Lazarus ====<br />
<br />
Rename or copy the .dpr file to a .lpr file. Comment out or remove the <div class="dir">{$R *.res}</div> directive and add a <div class="dir">{$mode delphi}{$H+}</div> or <div class="dir">{$mode objfpc}{$H+}</div> directive to the .lpr file. The Lazarus IDE can assist in this conversion through the Tools menu item "Convert Delphi Project to Lazarus Project". It asks for a .dpr (Delphi Project) file and converts it to .lpr; furthermore, it creates the .lpi file.<br />
<br />
Many existing Delphi forms can be converted to work with Lazarus by using the IDE's built in .dfm to .lfm form converter. It can be found under the Tools menu item as "Convert DFM file to LFM". Bring up the file dialog, select the dfm and the converter will do the rest.<br />
<br />
If you need to convert the whole unit (with or without a form), Lazarus also includes a built in "Convert Delphi unit to Lazarus unit" which will do the following for you -<br />
<br />
# renames the .pas and .dfm file to lowercase.<br />
# converts .dfm file to .lfm file (currently without content check, just format)<br />
# creates an empty .lrs file (the content will be created later)<br />
# adds <div class="dir">{$mode delphi}</div> directive<br />
# replaces windows unit with LCLIntf<br />
# adds LResources unit if needed (i.e., if unit.lrs is to be used; <div class="dir">uses LResources </div> can be in the implementation part)<br />
# removes variants unit<br />
# removes <div class="dir">{$R *.dfm}</div> directive<br />
# adds initialization section and <div class="dir">{$i unit.lrs}</div> directive<br />
<br />
This allows quick and easy conversion of most units from Delphi format to Lazarus format. It does not do any validity check, or automatic syntax changes, so any syntax changes you need to make, additional unit/unit name changes, or dfm/pas changes for control/component differences you must still do manually, though in time some wizards to help facilitate some of this, especially the repairing of converted forms(lfm), may become available.<br />
<br />
==== Selecting the right compiler mode ====<br />
<br />
The [[Free Pascal]] Compiler supports 5 different pascal modes. For example TP for turbo pascal, lets you compile turbo pascal units. There is also a DELPHI compatibility mode that can be set to make existing code easier to convert. Lazarus prefers the OBJFPC mode, which almost equals the DELPHI mode, but is less ambigious than the Delphi syntax. Here are the important points:<br />
<br />
The mode can be selected at command line or at the start of the source. Using the command line has the advantage, that you don't need to change the source, but the disadvantage, that others must be told.<br />
<br />
Most Delphi units can be compiled by the [[Free Pascal]] compiler by adding <br />
{$IFDEF FPC}<br />
{$MODE DELPHI}<br />
{$ENDIF}<br />
right after the unit name.<br />
<br />
For more details about [[Free Pascal]] modes see the [http://www.freepascal.org/docs-html/prog/progap4.html#progse62.html Free Pascal Documentation]<br />
<br />
==== Cross-Platform considerations ====<br />
<br />
* Inline assembler is always a problem because it will bind the code to the Intel architecture. Some developers do algorithm prototypes in Pascal and ifdef the their optimized assembler. Fortunately Turbo-Power did this in numerous places with their code. If this is the case with the package you're converting, throw the switch back to Pascal.<br />
* Don't reference specific memory location like the BIOS data area. Find out what the code needs and try to find a cross platform alternative.<br />
* Don't do processor specific tricks (like using the Intel TSC) without enclosing your code in an ifdef for the platform the code needs... and providing an alternative for environments that don't have the hardware capability.<br />
* If you need some OS specific code, then you can use IFDEFs. See below for a list of macros.<br />
<br />
==== Useful compiler variables ====<br />
<br />
To write code, that behaves on different systems differently, you can use the <div class="dir">{$IFDEF Name}</div> directives.<br />
<br />
* <div class="dir">{$IfDef LCL}</div><br />
This variable is defined, when using the LCL package. Useful to write code, that works with the LCL and Delphi.<br />
* <div class="dir">{$IfDef FPC}</div><br />
This variable is defined, when using the FPC compiler. Useful to write code, that works with FPC and Delphi.<br />
* <div class="dir">{$IfDef Unix}</div>, <div class="dir">{$IfDef Win32}</div>, ...<br />
Defined by FPC for the current Target OS. Delphi defines "Linux", "Win32" and "MSWindows". [[Free Pascal]] runs on much more platforms and so it is recommended to use the more general items. For example "Unix" is defined for Linux, FreeBSD, NetBSD and OpenBSD, where Lazarus already runs.<br />
Use<br />
{$IfDef Linux}<br />
{$Define Unix}<br />
{$EndIf}<br />
to work around this for Kylix.<br />
<br />
For more details see the [http://www.freepascal.org/docs-html/prog/prog.html#QQ2-23-21 Free Pascal Documentation].<br />
<br />
==== Finding a missing identifier ====<br />
<br />
There are differences in how the LCL is organized when compared to the Delphi VCL. If you get a "not found" compiler error about a major class or identifier, the chances are good that it's in a different unit. A complete cross reference can be found by grep'ing lazarus/docs/xml or the lcl subdirectory.<br />
<br />
For example the commonly used tbutton typically throws an error in Delphi code because it's located in a unit named buttons.pp. The following command finds the correct unit very quickly (in the lazarus source directory):<br />
<br />
grep -in ' tbutton =' lcl/*<br />
<br />
<br />
==== Major unit differences between Lazarus and Delphi ====<br />
<br />
** Please add to this topic! **<br />
<br />
* Windows->Interfaces, LCLIntf, LCLType, LCLProc, VCLGlobals, ...)<br />
<br />
As the LCL is not windows specific, the code that is in the Delphi Windows unit for directly accessing the Win32 API is abstracted into seperate interfaces, which can be accessed from the LCLIntf unit. Keep in mind, that Lazarus does not emulate win32, so many functions are missing and some do not work as their win32 counterparts. These functions only exist for Delphi compatibility and should only be used for quick & dirty porting. LCL also breaks out many of the types, so often LCLType, and sometimes VCLGlobals are required. LCLProc also contains a few functions which can be useful for lower level handling such as "FreeThenNil" as is in Delphi 5 and higher, "DeleteAmpersands" to remove additional ampersands from a string for controls(& vs && etc). The Interfaces unit needs to be included in the .lpr file to initialize the appropriate widgetset.<br />
<br />
* Messages->LMessages<br />
<br />
TControl Messages for win32 event callbacks of the format WM_CALLBACK and the structs associated with them are often found in the Messages unit in Delphi. In the LCL these types of messages and there structs are usually found in LMessages, usually with name changes of WM to LM, so for instance WM_MOUSEENTER becomes LM_MOUSEENTER, and TWMMouse becomes TLMMouse.<br />
<br />
* Graphics, Controls->GraphTypes, GraphMath, Graphics, Controls<br />
<br />
To simplify some things and break complexity of circles between units, a few types have been abstracted into a shared unit called GraphType, which includes things, which in Delphi are located in Graphics or Controls, for instance the bvNone etc of panels. So sometimes you have to include it. Also a unit which, although incompatible with Delphi, adds other useful functionality is GraphMath, which adds a TFloatPoint for precision, misc routines for dealing with beziers, lines, and arcs, as well as some operator overloading for use with TPoints and TRect, such as for instance Point1 := Point2 + Point3, and comparing two rects like if (rect1 = rect2) then ...<br />
<br />
* Mask->MaskEdit<br />
<br />
For more intelligent naming considerations, the unit for TMaskEdit is called [MaskEdit|] instead of the slightly more nebulous Mask as in many versions of Delphi.<br />
<br />
* StdCtrls->StdCtrls,Buttons<br />
<br />
In many version of Delphi TButton is located in StdCtrls, while TSpeedButton and TBitBtn are in Buttons. For consistency and simplicity the LCL puts all button types in Buttons, which can occasionally break code conversion, so it is always a good idea to include.<br />
<br />
==== Property and method differences Delphi -> FPC/LCL ====<br />
* TBitmap contains a canvas in the LCL<br />
==== Syntax differences ====<br />
<br />
'''Please add to this topic!'''<br />
<br />
Because of the inherent strictness in FPC, some syntax changes are necessary, even though !!;dir {$Mode Delphi}!!;! does allow more lazyness like Delphi does. For this reason complying as much with the syntax rules of !!;dir {$Mode ObjFPC}!!;! as possible is highly recommended, even when the codebase is still going to be shared between Delphi and the LCL. Some of these are simply better coding practises, and sometimes because occasionally Delphi mode is not entirely accurate, or in a few instances Delphi acceptible code does not function as expected with FPC, even though it might compile. To that end even though not all such are strictly required, the following list of changes should be considered mandatory :<br />
<br />
;Variables initialization in FPC 1.0.x<br />
<br />
With Delphi it is possible (and quite common) to initialize a variable in its declaration, however this is not possible in FPC 1.0.x, const must be used instead, or prefereably in many situations, initialized elsewhere at some point before the variable is used (like unit initialization). <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">var</div><br />
MyObject: TSomeObject= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
| class="code" | <div class="key">var</div><br />
MyObject<div class="symbol">:</div> TSomeObject;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
MyObject:= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
;When assigning an event handling entry point, prefix it with an "@"<br />
<br />
For instance, you might assign a button callback manually <br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">begin</div> <br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= SomeFunction; <div class="cmt">//@ not required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">begin</div><br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= @SomeFunction; <div class="cmt">//@ IS required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When calling a procedure variable use this syntax: theprocname()<br />
<br />
In Delphi there is no difference between a procedure and a procedure variable, however there is in FPC, so to call a procedure, even if it has no paramaters, you must append parenthesis. For Example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div> <br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div> <br />
OnMyCallback; <div class="cmt">//parenthesis not required</div> <br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div><br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div><br />
OnMyCallback(); <div class="cmt">//parenthesis required</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When accessing values in a pointer to a record you must dereference first<br />
<br />
In Delphi it is not required to dereference a pointer to a record to acces values within it, it can in fact be treated just like the record itself, or any other object. In FPC it must be first dereferenced. As an example,<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord^.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>; <br />
|}<br />
<br />
;When accessing chars of an indexed string Property of an object, it must be enclosed in parenthesis<br />
<br />
With Delphi it is possible to treat a Property exactly like some other const or var, even to accessing for instance individual chars of a string directly, while this is not always possible in FPC, specifically for indexed properties. Instead it must be enclosed in parenthesis, to make distinct. While this may not always hold true it is probably a good practice to consider anyway. For example<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//no parenthesis needed</div><br />
MyChar:= MyString[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//parenthesis sometimes needed</div><br />
MyChar:= (MyString)[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
<br />
;You must typecast pointers to actual type when using with var or function of that type<br />
<br />
Sometimes in Delphi you will have a null pointer variable representing an object. While it might seem a complex situation, it is oddly quite common especially in large component packs as a method of preventing too many circular includes between objects in different units. In Delphi it is then possible to send this null pointer to a function expecting that object, without bothering to typecast to actual type, in fpc you must typecast. <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div><br />
<div class="symbol">Application</div><br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> GetSomeObject;<br />
<div class="cmt">//More code...</div><br />
DoSomething(MyComponent.SomeObject)<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="symbol">Application</div> <br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> Pointer(GetSomeObject);<br />
<div class="cmt">//More code...</div><br />
DoSomething(TSomeObject(MyComponent.SomeObject))<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Resources ====<br />
<br />
Delphi resource files are win32 specific and not compatible with Lazarus, so you'll have to recreate and compile them using the lazres. Lazres can be found in the lazarus/tools subdirectory. If you've downloaded the Lazarus sources, you'll need to compile it first.<br />
* cd lazarus/tools<br />
* make install<br />
To add a resource to your application:<br />
* lazres myresource.lrs mypix.xpm anotherpix.xpm<br />
* Add the LResources unit to your Uses clause<br />
* Include the .lrs file you created under the initialization block<br />
Example:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> TForm1.LoadGlyph(<div class="key">const</div> GlyphName: <div class="key">String</div>): TBitMap;<br />
<div class="key">begin</div><br />
Result:= TPixmap.Create<div class="symbol">;</div><br />
Result.LoadFromLazarusResource(GlyphName)<div class="symbol">;</div><br />
<div class="key">end</div>; <br />
<div class="cmt">//More code...</div><br />
<div class="key">begin</div><br />
Speedbutton1.glyph:= LoadGlyph('mypix')<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
<div></div> <br />
<div class="key">initialization</div><br />
<div class="dir">{$I unit1.lrs}</div><br />
<div class="dir">{$I myresource.lrs}</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
== Getting Help ==<br />
<br />
If you encounter a problem during conversion that you just can't solve, there are a wide variety of places to get help. For pure Object Pascal and FPC issues, the best place to start is the Free Pascal [http://www.freepascal.org/docs-html/ Documentation] by Michaël Van Canneyt and Florian Klämpfl. For more Lazarus oriented problems, the Lazarus Project Documentation in the Lazarus-CCR Knowledgebase [Main Page] is the next place to look. Finally you can post a question on any of the [http://www.freepascal.org/maillist.html mailing lists for the Free Pascal Compiler] or the [http://community.freepascal.org:10000/bboard/ FPC forums] where a lot of experts are subscribed.<br />
<br />
There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems. Tamarack Associates operates a fast [http://www.tamaracka.com/search.htm search] engine specifically for the Borland usenet archives. Mer Systems Inc. provides a similar search [http://www.mers.com/searchsite.html engine]. Another outstanding source of information along with a sitewide [http://www.efg2.com/Lab/search.htm search] capability is Earl F. Glynn's Computer Lab and Reference [http://www.efg2.com/ Library].<br />
<br />
== Packaging and Releasing your component ==<br />
<br />
=== Creating a Lazarus package for your component(s) ===<br />
<br />
Creating a package makes installing the code you've converted a much easier process... especially if you're providing more then one component. Mattias Gärtner has written an overview of [[Lazarus Packages]] that should be read before beginning this process.<br />
<br />
=== Documentation ===<br />
<br />
The purpose of this site and the wiki format is to make the generation of professional documentation an easy and quick process. The wiki also makes it possible to see the results of your posting immediately and make any changes you'd like in real time.<br />
<br />
Using the Lazarus-CCR wiki to create nice looking documentation is very easy. If you've never used wiki markup before, you can get familiar with it in the [[Sand Box]] practice area.<br />
<br />
=== Creating a Code Release Page ===<br />
<br />
The Code Release Page contains vital information about your component that a potential downloader will need to know, such as license, intended platform, status (alpha, beta, stable...), where to download it, who wrote it, is support available... etc.<br />
<br />
The following procedure will let you create a Code Release Page with your browser: <br />
<br />
* Edit the [[Code And Components]] page and add a project name wiki link entry for your component in the "Released Components" section. Save the modified page.<br />
<br />
* Go to the [[Component Release Template]], select all and copy. Hit the back button on your browser to return to the [[Code And Components]] page.<br />
* Click on your new wiki component name entry and paste the release template into the blank edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your document looks the way you want it to.<br />
<br />
=== Creating a Comment Page for your component ===<br />
<br />
When your component is posted to the Sourceforge File Release System, the Lazarus-CCR admins will lock your code release page to prevent the unlikely event of someone changing your license, name or other release info.<br />
<br />
While you're building your code release page, you have the option to create another wiki link to a "news and comments" page for your component that will always be writable. This is called a ComponentCommentTemplate. The link to it should be added to the bottom of the code release template where there's a topic heading and a brief howto. The wiki name link should be your wiki component name with a Comments suffix like [[EpikTimer Comments]] or [[JpegLazarus Comments]] . The comments page will remain writable to collect feedback from users and for you to post updated information.<br />
<br />
A comment page can be added like this:<br />
<br />
* Edit your component release page and add the wiki comment link (in the format described above). Save the modified page.<br />
* Go to the [[Component Comment Template]] , select all and copy. Hit the back button on your browser to return to your component release page.<br />
* Click on the comment entry entry you created and paste the comment template into the edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your comment page looks the way you want it to.<br />
<br />
While the Lazarus-CCR admins initially lock code release pages, any member of the project can use their shell acount to unlock, edit and re-lock their pages.<br />
<br />
=== Submitting the component ===<br />
<br />
If you're a release technician on the project, upload your component to the SourceForge File Release System and add it to the list of release packages. Otherwise send it to one of the project administrators and we'll add it to the repository. We'll also put it into CVS so you'll continue to have access to it.<br />
<br />
== Contributors and Changes ==<br />
<br />
This page has been converted from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=CodeConversionGuide version].<br />
* Initial version by Tom Lisjac and Mattias Gärtner - 9/22/2003 [[User:Tom | VlxAdmin]]<br />
* Moved Getting help from the main page. T. Lisjac - 9/24/2003 [[User:Tom | VlxAdmin]]<br />
* Added documentation templates, procedure and links. 9/25/2003 [[User:Tom | VlxAdmin]]<br />
* LCLLinux was renamed to LCLIntf, [[User:Jesusrmx | Jesus Reyes]], 9/27/2003<br />
* added more information on Unit changes, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Updated Syntax differences, including some examples, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* FPC 1.0.x doesn't support interfaces, [[User:Vincent | Vincent Snijders]] 9/28/2003<br />
* Fixed some of the examples per new WikiWord definition, 9/28/2003 [[User:Tom | VlxAdmin]]<br />
* Made code more consistant to remove last accidental Pascal WikiWord definitions, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/17/2003<br />
* Use pascal stylesheet to make example code more readable, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/18/2003</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Lazarus_Tutorial&diff=2858Lazarus Tutorial2005-08-08T20:26:36Z<p>Wstomv: /* The Run sub-menu */</p>
<hr />
<div>''This is the start of a Lazarus Tutorial. Please feel free to add your experiences to it.''<br />
==Overview==<br />
Lazarus is a free and open source development tool for the FreePascal Compiler (object pascal), which is also free and open source. The Lazarus IDE ([http://lazarus-ccr.sourceforge.net/kbdata/lazide.jpg screenshot]) is a stable and feature rich programming environment for creating self-standing graphical and console applications. It currently runs on Linux, FreeBSD and Win32 and provides a customizable source editor and visual form creation environment along with a package manager, debugger and complete GUI integration with the FreePascal Compiler.<br />
<br />
==Getting Started - Your first Lazarus Program!==<br />
<br />
(Thanks to [[User:Kirkpatc]])<br />
<br />
Get, install ([[Installing Lazarus]]) and launch Lazarus which will also make available the FreePascal Compiler.<br />
<br />
Several windows will appear on the desktop: the main menu at the top, the Object Inspector on the left, the Lazarus Source Editor occupying most of the desktop, and a ready-made Form1 window overlying the Source Editor.<br />
<br />
On the top Menu window, underneath the menu line, is a row of tabs. If the 'Standard' tab is not already selected, select it by clicking with the mouse. Then find the Button icon (a rectangle with 'OK' on it) and click on that with the mouse. Then click on the Form1 window, somewhere to the left of the middle. A shadowed rectangle labelled 'Button1' will appear. Click again on the Button icon in the Standard tab, and click on the Form1 somewhere to the right of centre: a rectangle labelled 'Button2' will appear.<br />
<br />
Now click on Button1 to select it. The Object Inspector will display the properties of the object Button1. Near the top is a property named 'Caption', with the displayed value 'Button1'. Click on that box, and change 'Button1' to 'Press'. If you hit ENTER or click in another box, you will see the label of the first button on Form1 change to 'Press'. Now click on the Events tab on the Object Inspector, to see the various events that can be associated with the button. These include OnClick, OnEnter, OnExit etc. Select the box to the right of OnClick: a smaller box with three dots (... ellipsis) appears. When you click on this, you are taken automatically into the Source Editor and your cursor will be placed in a piece of code starting:<br />
<br />
procedure TForm1.Button1Click(Sender: TObject);<br />
begin<br />
{now type:} Button1.caption := 'Press again';<br />
{the editor has already completed the procedure with}<br />
end;<br />
<br />
Press F12 to select the Form1 window instead of the Source Editor.<br />
<br />
Now edit the properties of Button2: click on Button2 to display its properties in the Object Inspector. Change its Caption property to 'Exit' instead of 'Button2'. Now select the Events tab, and click on the box for OnClick. Click on the ... ellipsis, and you will be taken into the Source Editor, in the middle of another procedure:<br />
<br />
procedure TForm1.Button2Click(Sender: TObject);<br />
begin<br />
{now type:} Close;<br />
{the editor has already completed the procedure with} <br />
end;<br />
<br />
Now Press F12 to see the Form1 window again. You are now ready to try to compile. The simplest way to do this is to select 'Run' from the main menu at the top, and then the 'Run' option on the sub-menu. Alternatively you could simply type F9. This will first compile and then (if all is well) link and execute your program.<br />
<br />
Several text windows will appear and all sorts of compiler messages will be typed, but eventually your Form1 window will re-appear, but without the grid of dots; this is the actual main window of your application, and it is waiting for you to push buttons or otherwise interact with it.<br />
<br />
Try clicking on the button labelled 'Press'. You will notice that it changes to 'Press again'. If you press it again, it will still say 'Press again'!!<br />
<br />
Now click on the button marked 'Exit'. The window will close and the program will exit. The original Form1 window with the grid of dots will reappear, ready to accept more editing activity.<br />
<br />
You should save your work now (and frequently!!) by selecting Project > Save As > your_selected_file_name.pas<br />
<br />
===Second session.===<br />
Re-open your saved Project.<br />
On the Form1 window click on the 'Press' button (Button1) to select it.<br />
Select the 'Events' tab on the Object Inspector, click on the right side box next to OnClick, click on the ... ellipsis, to go back to the appropriate point in the Source Editor.<br />
<br />
Edit your code to read as follows:<br />
<br />
procedure TForm1.Button1Click(Sender: TObject);<br />
{Makes use of the Tag property, setting it to either 0 or 1}<br />
begin<br />
if Button1.tag =0 then<br />
begin<br />
Button1.caption := 'Press again';<br />
Button1.tag := 1<br />
end else<br />
begin<br />
Button1.caption := 'Press';<br />
Button1.tag := 0<br />
end<br />
end;<br />
<br />
Save your work, re-compile and run. The left button will now toggle between two alternative messages.<br />
<br />
The rest is up to you!<br />
<br />
If you prefer to write Console- or text-based Pascal programs (for example if you are following a basic Pascal programming course, or you need to write programs to use in batch mode or for system programming), you can still use Lazarus to edit, compile and run your programs. It make an ideal environment for Pascal development. See [[Console Mode Pascal]].<br />
<br />
==The Editor==<br />
When you launch Lazarus for the first time, a series of separate disconnected or 'floating' windows will appear on your desk-top.<br />
<br />
The first, running right along the top of the desk-top, is titled '''Lazarus Editor vXXXXXX - project1''' (which will subsequently be modified to reflect the name of your currently-open project). This is the main controlling window for your project, and contains the Main Menu and the Component Palette.<br />
<br />
<center>[[Image:Lazmain.jpg]]</center><br />
<br />
On the line below the title bar is the ''Main Menu'' with the usual entries for File, Edit, Search, View functions and so on, with a few selections that are specific to Lazarus.<br />
Below this on the left is a set of BitButtons (which take you rapidly to particular Main Menu options) and on the right is the Component Palette.<br />
<br />
Under the Lazarus Editor window will appear the '''[http://lazarus-ccr.sourceforge.net/kbdata/objinsp.jpg Object Inspector]''' window on the left, and the '''[http://lazarus-ccr.sourceforge.net/kbdata/editor.jpg Lazarus Source Editor]''' on the right. There may be another smaller window, labelled '''[http://lazarus-ccr.sourceforge.net/kbdata/blankform.jpg Form1]''', overlying the Lazarus Source Editor window. If this is not visible immediately, it can be made to appear by pressing the '''F12''' key, which toggles between the Source Editor view and the Form view. The Form window is the one on which you will construct the graphical interface for your application, while the Source Editor is the window which displays the Pascal code associated with the application which you are developing. The operation of the Object Inspector is discussed in more detail below while the Component Palette is described.<br />
<br />
When you start a new project (or when you first launch Lazarus) a default Form will be constructed, which consists of a box in which there is a grid of dots to help you to position the various components of the form, and a bar along the top which contains the usual '''Minimise''', '''Maximise''' and '''Close buttons'''. If you click with your mouse cursor anywhere in this box, you will see the properties of this form displayed in the Object Inspector on the left side of the desk-top.<br />
<br />
Other windows that may become visible during your work: the '''[http://lazarus-ccr.sourceforge.net/kbdata/projinsp.jpg Project Inspector]''', which contains details of the files included in your project, and allows you to add files to or delete files from your project; the '''Messages''' window, which displays compiler messages, errors or progress reports on your project; if Lazarus was launched from a terminal window, the original terminal remains visible and detailed compiler messages are also printed there.<br />
<br />
<br />
===The Main Menu===<br />
<br />
The main menu line contains the following entries:<br />
<u>F</u>ile <u>E</u>dit <u>S</u>earch <u>V</u>iew <u>P</u>roject <u>R</u>un <u>C</u>omponents <u>T</u>ools E<u>n</u>vironment <u>W</u>indows <u>H</u>elp<br />
<br />
As usual, the options can be selected either by placing the mouse cursor over the menu option and clicking the left mouse button, or by typing Alt-F on the keyboard (provided the main menu window has focus: if it has not, hit TAB repeatedly to cycle focus through the various windows until the desired window has its title bar highlighted in colour).<br />
<br />
====The File sub-menu====<br />
<div class="floatright"> http://lazarus-ccr.sourceforge.net/kbdata/FileMenuSnapshot.png </div><br />
* '''New Unit''': Creates a new Unit file (Pascal Source).<br />
* '''New Form''': Creates a new Form: both the visual on-screen window and the associated Pascal source file.<br />
* '''New ...''': Offers a pop-up menu box ([http://lazarus-ccr.sourceforge.net/kbdata/menu-new.jpg screenshot]) with a variety of new document types to create.<br />
* '''Open''': Offers a pop-up Dialog Box to enable you to navigate the filesystem and choose an existing file to open.<br />
* '''Revert''': Abandon editing changes and restore the file to its original state. <br />
* '''Save''': Save the current file, using its original filename. If there is no name, the system will prompt for one (just like Save As).<br />
* '''Save As''': Allows you to choose a directory and filename for saving the current file.<br />
* '''Close''': Closes the current file, prompting wheter to save all editor changes.<br />
* '''Close all editor files''': Close all files currently open in the editor. Prompt for saving changes.<br />
* '''Clean directory''': Offers a dialog with a series of editable filters for removing files from the current directory. Useful for removing .bak files and remnants of former Delphi projects.<br />
* '''Quit''': Exit Lazarus, after prompting for saving all edited files.<br />
<div style="clear:both;"></div><br />
====The Edit sub-menu====<br />
<div class="floatright"> http://lazarus-ccr.sourceforge.net/kbdata/EditMenuSnapshot.png </div><br />
* '''Undo''': Undo the last edit action, leaving the Editor in the state just before the last action.<br />
* '''Redo''': Re-instates the last action that was reversed by Undo.<br />
* '''Cut''': Remove the selected text or other item and place it on the Clipboard.<br />
* '''Copy''': Make a copy of the selected text, leaving the original in place, and placing the copy on the Clipboard.<br />
* '''Paste''': Places the contents of the Clipboard at the cursor position. If text has been selected at the cursor position, the contents of the Clipboard will replace the selected text.<br />
* '''Indent selection''': Move the selected text to the right by the amount specified in Environment -> Editor options -> General -> Block indent. This feature is useful for formatting your Pascal source code to show the underlying Block structure.<br />
* '''Unindent selection''': Removes one level of indenting, moving the text to the left by the amount specified in Block indent.<br />
* '''Enclose selection''': Provides a pop-up menu with a number of options for logically enclosing the selected text (begin ... end; try ... except; try ... finally; repeat ... until; { ... } etc).<br />
* '''Uppercase selection''': Convert selected text to uppercase.<br />
* '''Lowercase selection''': Convert selected text to lowercase.<br />
* '''Tabs to spaces in selection''': Converts any tabs in the selected text to the number of spaces specified by Environment -> Editor options -> General -> Tab widths. The number of spaces is not a fixed quantity, but is the number needed to fill the remaining width of the tab.<br />
* '''Break lines in selection''': If any lines in the selected text are longer than 80 characters or the number specified in Environment -> Editor options -> Display -> Right Margin, then the line is broken at a word boundary and continued on the next line.<br />
* '''Comment selection''': Makes the selected text into comments by inserting // on each line.<br />
* '''Uncomment selection''': Removes comment marks.<br />
* '''Sort selection''': Sort lines (or words or paragraphs) alphabetically; options for ascending or descending order, case sensitive or insensitive. In the middle of program source code, of course, it makes no sense, but if you have a list you need to have sorted this will do the trick.<br />
* '''Select''': Allows selection of blocks of text. Options include select all, select to brace, select paragraph or line etc.<br />
* '''Insert from character map''': Allows insertion of non-keyboard symbols such as accented characters, picked from a pop-up character map.<br />
* '''Insert text''': Displays pop-up menu to allow insertion of standard text such as CVS keywords (Author, Date, Header etc) or GPL notice, username or Current date and time.<br />
* '''Complete code''': Completes the code at the cursor. It is context sensitive and saves you a lot of time. For example: it completes classes, by adding private variables, Get and Set property access methods and adding method bodies. On variable assignments (e.g. i:=3;) it adds the variable declarations. On forward defined procedures it adds the procedure bodies. On event assignments (OnClick:=) it adds the method definition and the method body. See [[Lazarus IDE Tools]].<br />
* '''Extract procedure''': Uses the selected text (a statement or series of statements) to build a new procedure.<br />
<div style="clear:both;"></div><br />
<br />
====The Search sub-menu====<br />
<div class="floatright"> http://lazarus-ccr.sourceforge.net/kbdata/SearchMenuSnapshot.png </div><br />
* '''Find''': Similar to the facility in almost all graphic text editors: a pop-up dialog box appears allowing entry of a search text string, with options such as case sensitivity, whole words, origin, scope and direction of search.<br />
* '''Find Next, Find previous''': Search again for the previously entered text string, in the specified direction.<br />
* '''Find in files''': Search for text string in files: pop-up dialog with options all open files, all files in project, or all directories; masks available for selecting file types.<br />
* '''Replace''': Similar to '''Find'''; shows pop-up dialog with place to enter search text string and replacement text, and options for case sensitivity, direction etc.<br />
* '''Incremental find''': Search for the string while you are entering the search string. Example: after you choose "Incremental Find" if you press "l" the first "l" will be highlighted. If then you press "a", the editor will find the next "la" and so on.<br />
* '''Goto line''': Move editing cursor to specified line in file.<br />
* '''Jump back''': Move back in file to next Bookmark (need to have used '''Add jump point to history'''). Will move to Bookmarks in other files open in the Editor.<br />
* '''Jump forward''': Move forward to next Bookmark.<br />
* '''Add jump point to history''': Add Bookmarks or jump points to file.<br />
* '''View Jump-History''': Look at list of bookmarks in file: '''Not implemented yet'''.<br />
* '''Find other end of code block''': If positioned on a '''begin''', finds the corresponding '''end''' or vice versa.<br />
* '''Find code block start''': Moves to the '''begin''' of the procedure or function in which the cursor is placed.<br />
* '''Find Declaration at cursor''': Finds the place at which the selected identifier is declared. This may be in the same file or another file already open in the Editor; if the file is not open, it will be opened (so if a procedure or function is declared, for example, in <u>classesh.inc </u>, this will be opened in the Editor).<br />
* '''Open filename at cursor''': Opens the file whose name is selected at the cursor. Useful for looking at <u>Include </u> files or the files containing other <u>Units </u> used in the project.<br />
* '''Goto include directive''': If the cursor is positioned in a file which is <u>Included</u> in another file, goes to the place in the other file that called the <u>Include</u> file.<br />
'''<div style="clear:both;"></div><br />
<br />
====The View sub-menu====<br />
<div class="floatright"> http://lazarus-ccr.sourceforge.net/kbdata/ViewMenuSnapshot.png </div><br />
Controls the display of various windows and panels on the screen.<br />
* '''Object Inspector''': The window that usually occupies the left side of the Desktop, and displays the features of the Form which is on the desktop. Clicking with the mouse on any component of the form will cause the details of that component to be displayed in the Object Inspector. There is a panel at the top which shows the tree-structure of the current project, and the components of the form may optionally be selected in this panel: this will also cause the corresponding details to be displayed in the Object Inspector. The main lower panel has two tabs which allow selection of either '''Properties''' or '''Events''' to be displayed. Selection of '''Properties''' causes features such as name, colour, caption, font, size etc to be displayed: there are two columns, the left showing the property, and the right showing the value associated with that property. Selection of '''Events''' displays two columns: the left lists the possible events such as MouseClick or KeyDown associated with that component, and the right shows the action that results from that event. If there is no action defined, then clicking in the appropriate box or on the <div class="box">...</div> button causes the Source Editor to be displayed, with the cursor already positioned in a dummy Procedure declaration, waiting for event-defining code to be typed in.<br />
* '''Source Editor''': The main window in which source code is edited. Its behaviour is very like that of most other graphical text editors, so that the mouse can move the cursor over the displayed text, and clicking with the left mouse button while dragging the mouse will select and highlight text. Right clicking with the mouse displays a pop-up menu, but if you are familiar with Windows, Gnome or KDE editors, you will find that the pop-up menu DOES NOT include the usual Edit Cut, Copy or Paste functions, but does include options like Find Declaration or Open File at Cursor. The top of the Source Editor window has a number of tabs, corresponding to the files that are open for the current project; clicking on any tab makes that file visible, and you can move easily from file to file, copying and pasting between files and performing most of the normal editing functions. The Source Editor performs colour syntax highlighting on the code, with different colours for punctuation marks, comments, string constants etc. It will also maintain the level of indentation from line to line as you type in code, until you change the indentation. The function and appearance of the Source Editor are very configurable from the Main Menu by selecting Environment -> Editor options and then selecting one of several tabs in the pop-up dialog box.<br />
* '''Code Explorer''': A window usually placed on the right of the Desktop which displays, in tree form, the structure of the code in the current unit or program. It usually opens with just the Unit name and branches for Interface and Implementation sections, but clicking on the <div class="box">+</div> box to the left of any branch will open up its sub-branches or twigs, in more and more detail until individual constants, types and variables are displayed as well as procedure and function declarations. If you change the file displayed in the main Source Editor window, you need to click on the Refresh button of the Code Explorer to display the structure of the new file.<br />
* '''Units...''': Opens a pop-up dialog window with a list of the unit files in the current project.Clicking with the mouse on a filename selects that file; click on Open to display that file in the Source Editor. Checking the Multi box allows several files to be selected simultaneously, and they will all be opened in the Source Editor (but only one at a time will be displayed). This Menu Option is rather like the Project -> Project Inspector option, but only displays the list of Unit files and allows them to be opened.<br />
* '''Forms...''': Opens a pop-up dialog window with a list of the Forms in the current project, and allows the selection of one or more of them for display.<br />
* '''View Unit Dependencies''': Opens a pop-up dialog window that shows, in a tree-like manner, the structure of dependencies of the currently open unit file. Most of the files listed as dependencies will have their own <div class="box">+</div> boxes, which allow the dependencies of the individual files to be explored, often in a highly recursive manner.<br />
* '''Toggle form / unit view F12''': Toggles whether the Source Editor or the current Form is placed on the top layer of the Desktop, and given focus. If the Source Editor has focus, then you can edit the source code; if the Form is given focus, you can manipulate the components on the desktop and edit the appearance of the Form. The easiest way to toggle the display between Editor and Form is to use the F12 key on the keyboard, but the same effect is achieved by selecting this option on the Main Menu.<br />
* '''Messages''': A window that displays compiler messages, showing the progress of a successful compilation or listing the errors found.<br />
* '''Search Results''': A window that displays the results of find in files.<br />
* '''Debug windows''': Opens a pop-up menu with several options for operating and configuring the Debugger. See below where the [[#The_Debugger|debugger]] is described.<br />
<div style="clear:both;"></div><br />
<br />
====The Project sub-menu====<br />
<div class="floatright"> http://lazarus-ccr.sourceforge.net/kbdata/ProjectMenuSnapshot.png </div><br />
* '''New Project''': Create a new project. A pop-up dialog window appears offering a choice of types of project to create.<br />
* '''New Project from file''': A Navigation dialog window appears, alowing selection of a file from which to create a new project.<br />
* '''Open Project''' Open a project which has already been created and saved. A navigation dialog appears with a list of Lazarus Project Information (.lpi) files from which a project may be chosen.<br />
* '''Open Recent Project''': Displays a pop-up list of recent projects on which you have been working, and allows selection of one of these.<br />
* '''Save Project''': Similar to File -> Save: all the files of the current project are saved; if they have not previously been saved, there is a prompt for filename(s)- similar to Save Project As...<br />
* '''Save Project As...''': Prompts for filename to save project. A default filename of Project1.lpi is offered, but you should choose your own filename. Lazarus will not permit you to use the same name for the Project file and the Unit File (see [[Lazarus Tutorial#The_Lazarus_files| below]]).<br />
* '''Publish Project''': Creates a copy of the whole project. If you want to send someone just the sources and compiler settings of your code, this function is your friend. A normal project directory contains a lot of information. Most of it is not needed to be published: the .lpi file contains session information (like caret position and bookmarks of closed units) and the project directory contains a lot of .ppu, .o files and the executable. To create a lpi file with only the base information and only the sources, along with all sub directories use "Publish Project". In the dialog you can setup the exclude and include filter, and with the command after you can compress the output into one archive. See [[Lazarus IDE Tools]]<br />
* '''Project Inspector''': Opens a pop-up dialog with a tree-like display of the files in the current project. Allows you to add, remove or open selected files, or change options of the project.<br />
* '''Project Options...''': Opens a pop-up dialog window with tabs for setting options for Application (Title, Output Target file name), Forms (allowing you to select among the available forms, make them Auto-create) and Info (specifying whether editor information should be saved for closed files, or only for project files). '''I'M NOT REALLY VERY SURE WHAT IS THE SIGNIFICANCE OF THIS: HELP!!'''<br />
* '''Compiler options ...''': (Recently moved here from the Run Menu). Opens a multi-page tabbed window which allows configuration of the compiler. Tabs include '''Paths''' which allows definition of search paths for units, include files, libraries etc as well as allowing choice of widget type for the forms (gtk, gnome, win32); '''Parsing''' which allows choice of rules for parsing source programs, '''Code''' which allows choice of optimisation for faster or smaller programs, choice of target processor, types of checks, heap size etc; '''Linking''' allowing choice of whether or how to use debugging, static or dynamic libraries, and whether to pass options through to the linker; '''Messages''' to define what type of messages should be generated during error conditions; '''Other''' which allows decision to use default configuration file (fpc.cfg) or some other file; '''Inherited''' which shows a tree structure diagram to indicate how options have been inherited from units already incorporated; '''Compilation''' which allows definition of commands to be executed before or after the compiler is launched and can allow use of Make files. <br />
* '''Add editor file to Project''': Add the file currently being edited to the Project<br />
* '''Remove from Project''': Gives a pop-up menu of files available for removal from project.<br />
* '''View Source''': No matter which file you are editing, takes you back to the main program file (.lpr)or the main .pas file if there is no .lpr.<br />
* '''View ToDo List''':Opens a dialog box with a list of ToDo items associated with this project. This will list any ToDo comments in your project (lines commencing //TODO), and any others in the Lazarus units you have used. You need to Refresh the ToDo items in the dialog (using arrow symbol button of toolbar) before new 'ToDos' appear. The first column of the ToDo list contains numbers you have allocated to your ToDo comments; a simple //TODO comment will appear as a zero, but a comment of //TODO999 (for example) will place the number 999 in the first column. Remember there should be no spaces on the line before //TODO and ToDo comments added after the last save will not be shown!<br />
<br />
====The Run sub-menu====<br />
<div class="floatright"> http://lazarus-ccr.sourceforge.net/kbdata/RunMenuSnapshot.png </div><br />
* '''Build''': Causes Lazarus to build (ie compile) any files in the project that have been changed since the last build.<br />
* '''Build all''': Builds all files in the project, whether or not there have been any changes.<br />
* '''Abort build''': Stop the build process once it is running - either you have remembered that you did something silly and want to stop the build, or the system seems to be taking far too long and something is obviously wrong.<br />
<br />
* '''Run''': This is the usual way to launch the compiler and, if compilation is successful, to start execution of the application. What actually happens is that Lazarus saves a copy of your files, then starts the compiler and linker, then begins execution of the final linked binary program.<br />
* '''Pause''': Suspend execution of the currently running program. This may allow you to inspect any output that has been generated; execution may be resumed by selecting '''Run''' again.<br />
* '''Step into''': Used in conjunction with the debugger, causes execution of the program one step at a time up to a bookmarked point in the source.<br />
* '''Step over''': Causes stepwise execution up to the statement marked, then skips the marked statement, and continues execution at normal speed. Useful in trying to isolate a statement that introduces a logical error.<br />
* '''Run to cursor''': Causes execution at normal speed (ie NOT one statement at a time) until the statement is reached where the cursor is located; then stops. Resume execution at normal speed by selecting '''Run'''.<br />
* '''Stop''': Cease execution of the running program. Cannot be resumed by selecting '''Run'''; this will start the program again from the beginning (re-compiling if necessary).<br />
<br />
* '''Run Parameters''': Opens a multi-page pop-up window which allows command-line options and parameters to be passed to the program to be executed; allows selection of display to run program (eg a remote X terminal may be used in Linux); some system Environment variables may be overridden.<br />
: One very important use of this sub-menu is to activate a terminal window in which conventional Pascal console input/output is displayed. If you are developing a console-mode Pascal program (ie one that doesn't use the Graphical User Interface with its forms, buttons and boxes) then you should check the box for "Use launching application". The first time you do this and try the Compile/Run sequence, you will probably get a rude message to say <br />
"xterm: Can't execvp /usr/share/lazarus//tools/runwait.sh: Permission denied". <br />
: If this happens, you need to change the permissions on the appropriate file (for example using chmod +x ''filename'', or using the Windows utility for changing permissions); you might have to do this as root. After this, each time you launch you program, a console box will appear and all your text i/o (readln, writeln etc) will appear in it.<br />
: After your program has finished execution, a message "Press enter" appears on the screen. Thus any output your program generated will remain on the screen until you have had a chance to read it; after you press 'enter' the console window closes.<br />
: See the separate tutorial on [[Console Mode Pascal]] programming.<br />
* '''Reset debugger''': Restores the debugger to its original state, so that breakpoints and values of variables etc are forgotten.<br />
<br />
* '''Build file''': Compile (build) just the file that is currently open in the Editor.<br />
* '''Run file''': Compile, link and execute just the currently open file.<br />
* '''Configure Build + Run File''': Opens a multi-page tabbed window with options to allow for build of just this file when '''Build Project''' is selected, allows selection of the working directory, the use of various Macros, etc. Then Builds and Runs the file.<br />
:These last three options enable you to open (and maintain) a test project. Use File -> Open to open an .lpr file, pressing cancel on the next dialog to open this file as "normal source" file. <br />
<br />
<div style="clear:both;"></div><br />
<br />
====The Components sub-menu====<br />
* '''Open Package''': Displays a [http://lazarus-ccr.sourceforge.net/kbdata/OpenPackageSnapshot.png list of installed packages], with an invitation to [http://lazarus-ccr.sourceforge.net/kbdata/PackageContentsSnapshot.png open one or more of them], or to select various general or compiler options.<br />
* '''Open Package File''': Open one of the files in the selected package.<br />
* '''Open Recent Package''': Open a package that was opened recently.<br />
* '''Add Active Unit to Package''': Place the unit file (currently in the editor) into a package.<br />
* '''Package Graph''': Displays a [http://lazarus-ccr.sourceforge.net/kbdata/PackageGraphSnapshot.png graph] showing the relationships of the packages currently being used (if you aren't using any other packages, the Lazarus package and the FCL and LCL will be displayed).<br />
* '''Configure custom components''': If you have created some components, allows you to configure them.<br />
<br />
====The Tools sub-menu====<br />
<div class="floatright"> http://lazarus-ccr.sourceforge.net/kbdata/ToolsMenuSnapshot.png </div><br />
* '''Configure custom tools''': Allows the user to add various external tools (usually macros) to the toolkit<br />
* '''Quick syntax check''': Perform a quick check of the syntax in your source file without actually compiling anything. Essential step in developing long or complicated programs, where you don't want to waste time compiling if the code is wrong.<br />
* '''Guess unclosed block''': useful utility if you have a complex nested block structure and you have left out an 'end' somewhere<br />
* '''guess misplaced IFDEF/ENDIF''': useful if there is a complex or nested macro structure and you think you have left out an ENDIF directive<br />
* '''Make resource string''': Makes the selected string a resource string by placing it in the resourcestrings section. An advantage of resource strongs is you can change them without the need to recompile your project! <br />
* '''Diff''': Allows comparison between two files (or, usually, two versions of the same file) to find differences. Options to ignore white space at beginning or end of lines or differences in line termination: CR+LF versus LF). Useful for checking if there have been changes since last CVS update etc.<br />
* '''Check LFM file in editor''': Allows inspection of the LFM file which contains the settings that describe the current form<br />
* '''Convert Delphi unit to Lazarus unit''': Helps in porting Delphi applications to Lazarus; makes the necessary changes to the source file. See [[Lazarus For Delphi Users]] and [[Code Conversion Guide]].<br />
* '''Convert DFM file to LFM''': For porting from Delphi to Lazarus: converts the Form Description files from Delphi to Lazarus. See [[Lazarus For Delphi Users]] and [[Code Conversion Guide]].<br />
* '''Build Lazarus''': Launches a re-build of Lazarus from the most recently downloaded or updated CVS files. Hit the button and sit back to watch it happen! (track the process on your '''Messages''' window).<br />
* '''Configure "Build Lazarus"''': Allows the user to determine which parts of Lazarus should be re-built, and how. For example, you could select to have just the LCL re-built, or to have everything except the examples built; you can select which LCL interface to use (ie which set of widgets), and you can select the target operating system and specify a different target directory.<br />
<div style="clear:both;"></div><br />
<br />
====The Environment sub-menu====<br />
<div class="floatright"> http://lazarus-ccr.sourceforge.net/kbdata/EnvironmentMenuSnapshot.png </div><br />
* '''Environment options''': Displays a multi-page window with tabs for<br />
** '''Files''' - allowing the user to specify path to default directory, compiler, source directory and temporary directory for compilation; <br />
** '''Desktop''' - options for Language, Auto save behaviour, saving desktop properties, hints for component palette and speed buttons; <br />
** '''Windows''', to allow specification of size and behaviour of the various windows; <br />
** '''Form Editor''' - choose colours for editing forms; <br />
** '''Object Inspector''' - choose colour and height of items; <br />
** '''Backup''' - specify how to backup files when editing; <br />
** '''Naming''' - specify what extension to use in naming pascal files ('.pp' or '.pas'), whether to save files with names in lowercase, whether to perform auto-delete or auto-rename.<br />
* '''Editor options''': Multi-page window, with tabs for <br />
** '''General''' - determines behaviour like auto-indent, bracket highlighting, drag-drop editing, scrolling, syntax highlighting, showing hints, size of block indent and tabs, limit of Undo; <br />
** '''Display''' - options for showing line numbers, presence of gutters, size and type of font for editor, and contains a preview panel showing the colours of the various syntax features such as comments, directives, punctuation, errors and breakpoints; <br />
** '''Key Mappings''' - options to select Lazarus or Turbo Pascal scheme; <br />
** '''Color''' - allows choice of colour scheme for text features, for a number of language types such as Object Pascal, C++, Perl, HTML, XML and shell scripts. It shows preview panel again (for whichever language is selected); <br />
** '''Code Tools''' - allows selection of features like Identifier Completion, tooltips, specification of template file names, specific templates for code completion.<br />
* '''Debugger Options''': Multi-page window with tabs for <br />
** '''General''' - choose debugger: none, GNU debugger (gdb) or gdb through SSH, specify search paths for debuggers,and specific options for chosen debugger; <br />
** '''Event log''' - specify whether to clear log on run, and which messages to display; <br />
** '''Language Exceptions''' - select which exceptions can be ignored; <br />
** '''OS Exceptions''' - allows user to add certain signals which apply to current operating system (not implemented).<br />
* '''Code Tool Options''': Multi-page window, tabs for <br />
** '''General''' - Allows entry of additional source search paths, specify Jumping Method; <br />
** '''Code Creation''' - determines whether created code is added before or after certain features; <br />
** '''Words''' - determines whether Pascal keywords are to be entered in upper or lower case, or as Capitalised Words; <br />
** '''Line Splitting''' - establish rules about where lines are allowed to be split (before or after punctuation, after keywords etc); <br />
** '''Space''' - decide whether a space is to be added automatically before or after certain syntactic features such as keywords or punctuation marks. <br />
* '''Code Tools Defines Editor''': I NEED SOME HELP IN DESCRIBING THIS, AS I HAVEN'T A CLUE WHAT THIS ITEM IS FOR! [[User:Kirkpatc]]<br />
<br />
<br />
* '''Re-scan FPC Source directory''' Looks through the directory again. Lazarus uses the fpc sources to generate correct event handlers and while looking for declarations. If somebody changes the directory in the environment options, then this directory is rescanned, to make sure lazarus uses the version stored in that location. But if this directory has changed without lazarus noticing, then you may get some errors when designing forms or doing "Find declaration". If you get such an error, you can do two things:<br />
*# Check the fpc source directory setting in the environment option.<br />
*# Re-scan FPC source directory.<br />
<br />
====The Windows sub-menu====<br />
<div class="floatright"> http://lazarus-ccr.sourceforge.net/kbdata/WindowsMenuSnapshot.png </div><br />
Contains a list of the currently opened files and the available windows such as '''Source Editor''', '''Object Inspector''' and '''Project Inspector'''. Clicking on the name of one of the windows brings it to the foreground and gives it focus.<br />
<div style="clear:both;"></div><br />
<br />
====The Help sub-menu====<br />
<br />
At present this has three selections:<br />
* '''Online Help''' which at present opens a browser window that contains a picture of the running cheetah and a few links to the Lazarus, FreePascal and WiKi websites<br />
* '''Configure Help''' which opens a pop-up menu with options to select viewers and databases from which to read Help information. This option allows the user to specify either the on-line documents section of the Lazarus-CCR website, some other website containing the documents, or a local store for the documentation (this would eventually become the default, when the Help system is fully developed).<br />
At present by default, if you place your Editor cursor over any keyword from the FreePascal Components Library FCL or the RunTime Library RTL (but not the Lazarus Components Library LCL) and then press <<F1>> you will be taken to the appropriate definition on the website. THIS SECTION STILL REPRESENTS WORK IN PROGRESS<br />
<br />
* '''About Lazarus''' Displays a pop-up box with some information about Lazarus.<br />
<br />
Eventually there will be a full on-line Help service, with information about Pascal syntax, the use of the IDE, how to use, modify or create Components, and hints on how to perform certain tasks. This part of the Documentation section (the thing you are currently reading) represents the beginning of the process. '''We need contributions from anyone who feels able to provide them: the WiKi is very easy to edit.'''<br />
<br />
===The Button bar===<br />
A small toolbar area on the left of the main editor window, just below the Main Menu and to the left of the Component Palette, contains a set of buttons which replicate frequently-used Main Menu selections:<br />
: '''New unit''', '''Open''' (with a down-arrow to display a drop-down list of recently used files), '''Save''', '''Save all''', '''New Form''', '''Toggle Form/Unit''' (ie show either form or source code of Unit), '''View Units''', '''View Forms''', '''Run''' (ie compile and Run), '''Pause''', '''Step Into''', '''Step over''' (the last two are Debugger functions).<br />
<br />
==The Component Palette==<br />
A Tabbed toolbar which displays a large number of icons representing commonly used components for building Forms.<br />
<br />
Each tab causes the display of a different set of icons, representing a functional group of components. The left-most icon in each tabbed group is an obliquely leftward-facing arrow, called the Selection Tool.<br />
<br />
If you allow the mouse cursor to hover over any of the icons on the Component Palette, without clicking on the icon, the title of that component will pop-up. Note that each title begins with a 'T' - this signifies 'Type' or more accurately 'Class' of the component. When you select a component for inclusion in a form, the Class is added to the '''type''' section of the '''interface''' part of the Unit (usually as part of the overall TForm1), and an '''instance''' of that class is added to the '''var''' section (usually as the variable Form1). Any '''Methods''' that you design to be used by the Form or its Components (ie Procedures or Functions) will be placed in the '''implementation''' part of the Unit<br />
<br />
In the following list of the Components, you will find links to files that contain descriptions of the Units in which they are found. If you want to find out about the properties of a particular component, it is often worth looking at the Inheritance of that component and then inspecting the properties of the base type from which it is derived. For example, to understand TMaskEdit it is also useful to examine TCustomMaskEdit.<br />
<br />
'''TABS''' (the names are largely self-explanatory):<br />
* '''[http://lazarus-ccr.sourceforge.net/index.php?wiki=StdCtrls Standard]'''<br />
<center>http://lazarus-ccr.sourceforge.net/kb/images/4/4d/Component_Palette_Standart.png</center><br />
:''Frequently used components:'' [http://lazarus-ccr.sourceforge.net/index.php?wiki=MenuUnit TMainMenu], [http://lazarus-ccr.sourceforge.net/index.php?wiki=MenuUnit TPopupMenu], [http://lazarus-ccr.sourceforge.net/index.php?wiki=ButtonsTxt TButton], TLabel, TEdit, TMemo, TToggleBox, TCheckBox, TRadioButton, TListBox, TComboBox, TScrollBar, TGroupBox, TStaticText, [http://lazarus-ccr.sourceforge.net/index.php?wiki=ExtCtrls TRadioGroup], TCheckGroup, [http://lazarus-ccr.sourceforge.net/index.php?wiki=ExtCtrls TPanel], TActionList<br />
* '''[http://lazarus-ccr.sourceforge.net/index.php?wiki=ExtCtrls Additional]'''<br />
<center>http://lazarus-ccr.sourceforge.net/kb/images/7/7d/Component_Palette_Additional.png</center><br />
:''More, often-used components:'' [http://lazarus-ccr.sourceforge.net/index.php?wiki=ButtonsTxt TBitBtn], [http://lazarus-ccr.sourceforge.net/index.php?wiki=ButtonsTxt TSpeedButton], [http://lazarus-ccr.sourceforge.net/index.php?wiki=ExtCtrls TImage], TShape, TBevel, TPaintBox, TNotebook, TLabeledEdit, TSplitter, [http://lazarus-ccr.sourceforge.net/index.php?wiki=MaskEdit TMaskEdit], TCheckListBox, [http://lazarus-ccr.sourceforge.net/index.php?wiki=FormsTxt TScrollBox], [http://lazarus-ccr.sourceforge.net/index.php?wiki=FormsTxt TApplicationProperties], TStringGrid, TDrawGrid, TPairSplitter<br />
* '''[http://lazarus-ccr.sourceforge.net/index.php?wiki=ComCtrls Common Controls]'''<br />
<center>http://lazarus-ccr.sourceforge.net/kb/images/4/4a/Component_Palette_Common_Controls.png</center><br />
: TTrackBar, TProgressBar, TTreeView, TListView, TStatusBar, TToolBar, TUpDown, TPageControl, TImageList<br />
* '''[http://lazarus-ccr.sourceforge.net/index.php?wiki=DialogsTxt Dialogs]'''<br />
<center>http://lazarus-ccr.sourceforge.net/kb/images/7/72/Component_Palette_Dialogs.png</center><br />
: TOpenDialog, TSaveDialog, TSelectDirectoryDialog, TColorDialog, TFontDialog, TOpenPictureDialog, TSavePictureDialog, TCalendarDialog, TCalculatorDialog<br />
<br />
Several useful '''[http://lazarus-ccr.sourceforge.net/index.php?wiki=DialogExamples Dialog]''' procedures or functions don't appear on the Palette, but are easily used as direct calls from your source program.<br />
<br />
For several good examples of the use of Components see the $LazarusPath/lazarus/examples subdirectory of your source installation. Many of the programs show how to use dialogs and other components directly without using the IDE and component palette or having a separate form definition file: all the components are fully and explicitly defined in the main Pascal program. Other example programs make full use of the IDE.<br />
<br />
Some examples don't work straight away: you may need to play about with paths and permissions of files or directories. If you want to compile any of the examples, make sure that you have read/write/execute permissions for the files and directories, or copy the files to a directory where you do have the appropriate permissions.<br />
<br />
Try running the 'testall' program to see a menu of the available components together with small example test forms for most of them; then inspect the code to find out how they work!<br />
* '''Misc'''<br />
<center>http://lazarus-ccr.sourceforge.net/kb/images/8/8e/Component_Palette_Misc.png</center><br />
: [http://lazarus-ccr.sourceforge.net/index.php?wiki=DialogsTxt TColorButton], TSpinEdit, TArrow, TCalendar, TEditButton, TFileNameEdit, TDirectoryEdit, TDateEdit, TCalcEdit, TFileListBox <br />
* '''Data Controls'''<br />
<center>http://lazarus-ccr.sourceforge.net/kb/images/6/62/Component_Palette_DataControls.png</center><br />
: ''Data-aware components, which largely replicate the Standard and Additional groups but are applicable to Databases:'' TDBNavigation, TDBText, TDBEdit, TDBMemo, TDBImage, TDBListBox,TDBComboBox, TDBCheckBox, TDBRadioGroup, TDBCalendar, TDBGroupBox, TdbGrid<br />
* '''Data Access'''<br />
<center>http://lazarus-ccr.sourceforge.net/kb/images/c/cc/Component_Palette_DataAccess.png</center><br />
: TDatasource<br />
* '''System'''<br />
<center>http://lazarus-ccr.sourceforge.net/kb/images/f/fe/Component_Palette_System.png</center><br />
: [http://lazarus-ccr.sourceforge.net/index.php?wiki=ExtCtrls TTimer], TIdleTimer, TProcess<br />
* '''SynEdit'''<br />
<center>http://lazarus-ccr.sourceforge.net/kb/images/2/22/Component_Palette_SynEdit.png</center><br />
: ''A group of components to help interfacing with other languages and software tools. SynEdit is an advanced multi-line edit control, for Borland Delphi, Kylix and C++Builder. It supports Syntax Highlighting and code completion, and includes exporters for html, tex and rtf. It is a full-VCL/CLX control, meaning it is not a wrapper for Microsoft Windows controls, and no run-time library is required; this make SynEdit a crossplatform component. Compatibility with FreePascal is also planned, and SynEdit is the edit component in Lazarus IDE.'' see [http://synedit.sourceforge.net synedit at sourceforge]. TSynEdit, TSynAutoComplete, TSynExporterHTML, TSynMacroRecorder, TSynMemo, TSynPasSyn, TSynCppSyn, TSynJavaSyn, TSynPerlSyn, TSynHTMLSyn, TSynXMLSyn, TSynLFMSyn, TSynUNIXShellScriptSyn, TSynCssSyn, TSynPHPSyn, TSynTeXSyn, TSynSQLSyn, TSynMultiSyn<br />
<br />
To use the Palette, there must be an open form on view in the editor (if there isn't one, select File -> New Form). Click on the icon in the appropriate tab of the Palette for the component you want to use, then click on the Form, near where you want the component to appear. When the desired component appears, you can select it by clicking with the mouse, then move it to the exact place on the Form where you want it and adjust its size. Adjustments can be made to the appearance either by altering the picture itself on the Form using the mouse, or by changing the relevant Property in the Object Editor for that component.<br />
<br />
If you install additional components, either those you have written yourself, or some coming as a package from some other source, then extra tabs with the relevant icons will appear in your Component Palette. These new components can be selected and used on your forms in the same way as those supplied by default.<br />
<br />
==The Debugger==<br />
: ''Still to be written''.<br />
<br />
==The Lazarus files==<br />
(Thanks to Kevin Whitefoot.)<br />
(Additions by Giuseppe Ridinò, [[User:Kirkpatc]] and Tom Lisjac)<br />
When you save you will actually be saving two files: <br />
<br />
xxx.pas and yyy.lpr <br />
(You save more than that but those are the ones you get to name). The project file (lpr) and the unit file (pas) must not have the same name because Lazarus will helpfully rename the unit (inside the source code) to the same as the unit file name and the program to the name of the project file (it needs to do this or the compiler will probably not be able to find the unit later when referred to in the project file). Of course to be consistent it changes all the occurrences of unit1 to xxx.<br />
<br />
So if you are saving a project called '''again''', trying to save again.pas and again.lpr fails because unit names and program names are in the same name space resulting in a duplicate name error.<br />
<br />
So here is what I ended up with:<br />
<br />
e:/lazarus/kj/lazhello:<br />
total 4740 free 76500<br />
-rwxrwxrwx 1 kjwh root 4618697 Mar 24 11:19 again.exe<br />
-rw-rw-rw- 1 kjwh root 3002 Mar 24 11:21 again.lpi<br />
-rw-rw-rw- 1 kjwh root 190 Mar 24 11:18 again.lpr<br />
-rw-rw-rw- 1 kjwh root 506 Mar 24 11:08 againu.lfm<br />
-rw-rw-rw- 1 kjwh root 679 Mar 24 11:08 againu.lrs<br />
-rw-rw-rw- 1 kjwh root 677 Mar 24 11:08 againu.pas<br />
-rw-rw-rw- 1 kjwh root 2124 Mar 24 11:08 againu.ppu<br />
-rwxrwxrwx 1 kjwh root 335 Mar 24 11:07 ppas.bat<br />
<br />
Note that there are many more files than the two that I thought I was saving.<br />
<br />
Here is a brief note about each file:<br />
<br />
'''again.exe:'''<br />
The main program binary executable. Win32 adds an "exe" extension. Linux has none. This file will be huge on Linux due to the inclusion of debugging symbols. Run the "strip" utility to remove them and substantially shrink the executable size.<br />
<br />
'''again.lpi:'''<br />
This is the main file of a Lazarus project (Lazarus Project Information); the equivalent Delphi main file of an application will be the .dpr file. It is stored in an XML format.<br />
<br />
'''again.lpr:'''<br />
The main program source file. Despite its lazarus specific extension it is in fact a perfectly normal Pascal source file. It has a uses clause that lets the compiler find all the units it needs. Note that the program statement does not have to name the program the same as the file name.<br />
<br />
'''againu.lfm:'''<br />
This is where Lazarus stores the layout of the form unit. Lazarus uses this to generate a resource file that is included in the initialisation section of the againu.pas unit. Delphi dfm files can be converted to lfm format in the Lazarus IDE using the Tools->Convert DFM file to LFM utility.<br />
<br />
'''again.lrs:'''<br />
This is the generated resource file. Note that it is not a Windows resource file.<br />
<br />
'''againu.pas:'''<br />
The unit that contains the code for the form.<br />
<br />
'''again.ppu:'''<br />
This is the compiled unit.<br />
<br />
'''ppas.bat:'''<br />
This is a simple script that links the program to produce the executable. If compilation is successfull, it is deleted by the compiler.<br />
<br />
==Original contributors and changes==<br />
This page has been imported from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=LazarusTutorial version].<br />
* Created initial page and template. T. Lisjac - 11/04/2003 [[User:Tom | VlxAdmin]]<br />
* Inserted a note containing instructions for writing your first Lazarus Program. Suggest an administrator places it in the appropriate place on the Tutorial menu. 3/09/2004 [[User:Kirkpatc]]<br />
* Per above, moved Chris's writeup to the main body of the tutorial [[User:Tom | VlxAdmin]]<br />
* Began to insert text describing the Lazarus Editor - more to follow! 24 Mar 2004 [[User:Kirkpatc]]<br />
* Added some more to Lazarus Editor section of Tutorial. 25 Mar 2004 [[User:Kirkpatc]]<br />
* Added screenshots and revised some of the page formatting [[User:Tom | VlxAdmin]] 3/25/2004<br />
* Moved some of kwhitefoot's comments into Tutorial section. Formatting not quite right, but have to go to bed now! 26 Mar 2004 [[User:Kirkpatc]]<br />
* Formatted, added credits and comments. Removed original notes. [[User:Tom | VlxAdmin]] 3/26/2004<br />
* More material added to Editor section of tutorial. 26 Mar 2004 [[User:Kirkpatc]]<br />
* More material added describing the Main Menu. Renamed 'Hello World' to 'Getting Started' and moved it to nearer the top. 31 March 2004 [[User:Kirkpatc]]<br />
* Inserted section on Run sub-menu. Some general editing (eg ended each entry with a period to ensure consistency). 9 Apr 2004 [[User:Kirkpatc]]<br />
* Inserted a new section on How to get started with MySQL in FPC/Lazarus. 13 Apr 2004 [[User:Kirkpatc]]<br />
* Deleted the section on MySQL from here: it has been copied to Lazarus Database section of tutorial. 14 Apr 2004 [[User:Kirkpatc]]<br />
* Added some more to the description of the Editor Main Menu. 18 Apr 2004 [[User:Kirkpatc]]<br />
* Added section on Environment sub-menu. 19 Apr 2004 [[User:Kirkpatc]]<br />
* Added section on Components sub-menu. 4 May 2004 [[User:Kirkpatc]]<br />
* Adding Tools sub-menu description (incomplete). 7 May 2004 [[User:Kirkpatc]]<br />
* Added some screenshots to Menu descriptions. 9 May 2004 [[User:Kirkpatc]]<br />
* Fixed a bit in Environment Options - thanks VincentSnijders. 14 May 2004 [[User:Kirkpatc]]<br />
* More additions to Tools sub-menu. 19 May 2004 [[User:Kirkpatc]]<br />
* Added a section on the Button Bar and started work on The Component Palette. 20 May 2004 [[User:Kirkpatc]]<br />
* Posted a description file for the StdCtrls unit of the LCL, in the hope that people will add comments. 26 May 2004 [[User:Kirkpatc]]<br />
* Edited the StdCtrls file, removing a lot of repetitive material and doing some formatting. It is still far too long. 28 May 2004 [[User:Kirkpatc]]<br />
* Expanding on the Components Palette. 5 June 2004 [[User:Kirkpatc]]<br />
* Added a lot to the DialogExamples page. 10 June 2004 [[User:Kirkpatc]]<br />
* Considerable revision of the StdCtrls page, hopefully making it clearer and encouraging people to contribute - particularly in the 'Description' sections. 14 June 2004 [[User:Kirkpatc]]<br />
* Added pages for Menus and Dialogs units (linked to Component Palette description) - please feel free to add to these pages. 14 June 2004 [[User:Kirkpatc]]<br />
* Added page for Common Controls (linked to Component Palette). 16 June 2004 [[User:Kirkpatc]]<br />
* Added MaskEdit page (linked to Component Palette). 17 June 2004 [[User:Kirkpatc]]<br />
* Added Buttons, ExtCtrls pages (linked to Component Palette). 17 June 2004 [[User:Kirkpatc]]<br />
* Edited MainMenu component description page. 23 June 2004 [[User:Kirkpatc]]<br />
* Some additions to Common Controls. 28 June 2004 [[User:Kirkpatc]]<br />
* A new tutorial on Text-mode Pascal programming has been added. 5 July 2004 [[User:Kirkpatc]]<br />
* Minor changes to ComCtrls, ExtCtrls, Environment Menu. 10 July [[User:Kirkpatc]]<br />
* Added FormsTxt, component description page for Component Palette. 20 July 2004 [[User:Kirkpatc]]<br />
* Some corrections to ConsoleModePascal. 21 July 2004 [[User:Kirkpatc]]<br />
* Some small changes to ComponentPalette. 22 July 2004 [[User:Kirkpatc]]</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Code_Conversion_Guide&diff=2430Code Conversion Guide2005-08-08T20:01:24Z<p>Wstomv: /* Major unit differences between Lazarus and Delphi */</p>
<hr />
<div>Delphi to Lazarus Code Conversion Guide<br />
<br />
== About ==<br />
<br />
This page is about how to convert existing code to work with the [[Free Pascal]] Compiler and Lazarus IDE. While Lazarus and the Free Pascal Compiler have aspects in common with Delphi and Kylix, they are not clones. There are a number of library call and convention differences... and in some areas, FPC is enhanced and can be more demanding about correct syntax. Please see the [[Lazarus For Delphi Users]] guide for a description of some of the functional differences. <br />
<br />
The purpose of this guide is to document some of the specific differences that are frequently encountered during the code conversion process when translating existing code from Delphi to Lazarus.<br />
<br />
This document was placed into the wiki knowledge-base area so it could be easily extended by anyone who had encountered a unique problem and would like to post it for others to be aware of.<br />
<br />
== Selecting a component or library for conversion ==<br />
<br />
=== Where to find code to convert ===<br />
<br />
There is a LOT of code available on the net that can be converted for use with FPC and Lazarus. Here is a [PageOfCodeSites|] that is just a start. Please add to it if you know of any other good locations. Turbo-Power Software has recently released their entire commercial offering under the MPL. A list of available packages can be found [http://sourceforge.net/users/tpsfadmin/|here].<br />
<br />
To avoid duplicating effort, packages that have already been converted are listed on the [CodeAndComponents|] page. If you've converted a package or are working on one, please add a note on the [CurrentProjects|] page.<br />
<br />
=== Licensing ===<br />
<br />
Licenses for existing code range from freeware/public domain to restrictive versions that prohibit modification, re-distribution and commercial use. Before converting any package, it's a good idea to examine its licensing and make sure it's going to be compatible with Lazarus and the Free Pascal Compiler. License selection is especially important with components since dropping one on a form can impose an unwanted or incompatible license on an entire application.<br />
<br />
When converting components, please respect the wishes of the original author and retain all copyright and licensing headers along with email addresses and url's. It's courteous and often useful to inform the author that their component is being converted... especially if the component is under a restrictive license. New interest in an old or forgotten component can sometimes inspire authors to revise their original and overly restrictive licensing.<br />
<br />
In general, Public Domain (freeware), and the LGPL/MPL are the the most flexible for distributing components. For more information, the [http://www.opensource.org/docs/definition.php Open Source Definition] is a good place to start. There are also several comparisons available to help clarify how the various types of licenses work and what impact they'll have on code they're linked to. Search for "open source license comparison"<br />
<br />
=== Dependencies ===<br />
<br />
Another step before starting to work on a conversion is to verify that the code doesn't have deep dependancies on other packages that might not be available or represent a considerable conversion challenge. Some freeware offerings are bound to or extend proprietary packages that are frequently no longer available or come with inappropriate licenses.<br />
<br />
=== Compiler Issues ===<br />
<br />
Currently the stable 1.0.x version of the Free Pascal Compiler doesn't support interfaces, threads or Variant records. If the code you're converting needs these constructs, you'll have to use the 1.1 development branch of the compiler... which isn't always guaranteed to work with Lazarus.<br />
<br />
=== Platform and OS Issues ===<br />
<br />
Lazarus and the Free Pascal Compiler are cross-platform and cross-architecture development tools. In contrast, most existing Delphi code was specifically designed to run on an Intel processor under Win32. If your candidate component has a lot of Win32 specific code, it might be wise to try and find a less platform dependant alternative. But don't let this stop you... it's genuinely amazing what the LCL supports!<br />
<br />
== Doing the conversion ==<br />
<br />
=== Setting up the Lazarus environment for a conversion project ===<br />
<br />
====Create a test project====<br />
* Place code to be converted into a subdirectory (ie: convertdir)<br />
* Bring up Lazarus<br />
* File->Save All to the convertdir subdirectory. Meaningful names for the Project and default unit are optional.<br />
* Open the "main" unit to be converted in convertdir<br />
* Add it to the project: Project->Add Active Unit to Project<br />
* Run Tools->Quick Syntax Check or Run Build All to get started.<br />
====Initial items to watch out for====<br />
* Filenames are case sensitive with the 1.0.x series compilers. If you're working with this version, make all your filenames lower case. You'll get "File not found" errors if you don't.<br />
====Delphi VCL, Kylix CLX Sources in Lazarus====<br />
<br />
When converting Delphi/Kylix sources, it is often useful to do a find declaration to see, what a specific function is doing. The Lazarus IDE can parse the Delphi/Kylix sources. To do this it needs some searchpaths and compiler settings. You can easily setup this in<br />
Environment->CodeTools Defines Editor->Insert Template<br />
<br />
=== Conversion problems and solutions ===<br />
<br />
==== Delphi / Kylix file equivalents in Lazarus ====<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi / Kylix || class="header" | Lazarus || class="header" | Description<br />
|- class="code"<br />
| class="code" |.pas<br />
.dfm / .xfm<br />
.dcu / .dpu<br />
.dpr<br />
.res<br />
.dof / .kof<br />
---<br />
---<br />
---<br />
| class="code" |.pas, .pp<br />
.lfm<br />
.o<br />
.lpr<br />
---<br />
---<br />
.lrs<br />
.lpi<br />
.ppu<br />
| class="code" |Pascal unit file<br />
Form data file<br />
Compiled unit file<br />
Project file<br />
Resource file<br />
Project options file<br />
Lazarus resource file<br />
Lazarus project information file<br />
FPC unit description file<br />
|}<br />
<br />
==== Converting Delphi projects/forms/units to Lazarus ====<br />
<br />
Rename or copy the .dpr file to a .lpr file. Comment out or remove the <div class="dir">{$R *.res}</div> directive and add a <div class="dir">{$mode delphi}{$H+}</div> or <div class="dir">{$mode objfpc}{$H+}</div> directive to the .lpr file. The Lazarus IDE can assist in this conversion through the Tools menu item "Convert Delphi Project to Lazarus Project". It asks for a .dpr (Delphi Project) file and converts it to .lpr; furthermore, it creates the .lpi file.<br />
<br />
Many existing Delphi forms can be converted to work with Lazarus by using the IDE's built in .dfm to .lfm form converter. It can be found under the Tools menu item as "Convert DFM file to LFM". Bring up the file dialog, select the dfm and the converter will do the rest.<br />
<br />
If you need to convert the whole unit (with or without a form), Lazarus also includes a built in "Convert Delphi unit to Lazarus unit" which will do the following for you -<br />
<br />
# renames the .pas and .dfm file to lowercase.<br />
# converts .dfm file to .lfm file (currently without content check, just format)<br />
# creates an empty .lrs file (the content will be created later)<br />
# adds <div class="dir">{$mode delphi}</div> directive<br />
# replaces windows unit with LCLIntf<br />
# adds LResources unit if needed<br />
# removes variants unit<br />
# removes <div class="dir">{$R *.dfm}</div> directive<br />
# adds initialization section and <div class="dir">{$i unit.lrs}</div> directive<br />
<br />
This allows quick and easy conversion of most units from Delphi format to Lazarus format. It does not do any validity check, or automatic syntax changes, so any syntax changes you need to make, additional unit/unit name changes, or dfm/pas changes for control/component differences you must still do manually, though in time some wizards to help facilitate some of this, especially the repairing of converted forms(lfm), may become available.<br />
<br />
==== Selecting the right compiler mode ====<br />
<br />
The [[Free Pascal]] Compiler supports 5 different pascal modes. For example TP for turbo pascal, lets you compile turbo pascal units. There is also a DELPHI compatibility mode that can be set to make existing code easier to convert. Lazarus prefers the OBJFPC mode, which almost equals the DELPHI mode, but is less ambigious than the Delphi syntax. Here are the important points:<br />
<br />
The mode can be selected at command line or at the start of the source. Using the command line has the advantage, that you don't need to change the source, but the disadvantage, that others must be told.<br />
<br />
Most Delphi units can be compiled by the [[Free Pascal]] compiler by adding <br />
{$IFDEF FPC}<br />
{$MODE DELPHI}<br />
{$ENDIF}<br />
right after the unit name.<br />
<br />
For more details about [[Free Pascal]] modes see the [http://www.freepascal.org/docs-html/prog/progap4.html#progse62.html Free Pascal Documentation]<br />
<br />
==== Cross-Platform considerations ====<br />
<br />
* Inline assembler is always a problem because it will bind the code to the Intel architecture. Some developers do algorithm prototypes in Pascal and ifdef the their optimized assembler. Fortunately Turbo-Power did this in numerous places with their code. If this is the case with the package you're converting, throw the switch back to Pascal.<br />
* Don't reference specific memory location like the BIOS data area. Find out what the code needs and try to find a cross platform alternative.<br />
* Don't do processor specific tricks (like using the Intel TSC) without enclosing your code in an ifdef for the platform the code needs... and providing an alternative for environments that don't have the hardware capability.<br />
* If you need some OS specific code, then you can use IFDEFs. See below for a list of macros.<br />
<br />
==== Useful compiler variables ====<br />
<br />
To write code, that behaves on different systems differently, you can use the <div class="dir">{$IFDEF Name}</div> directives.<br />
<br />
* <div class="dir">{$IfDef LCL}</div><br />
This variable is defined, when using the LCL package. Useful to write code, that works with the LCL and Delphi.<br />
* <div class="dir">{$IfDef FPC}</div><br />
This variable is defined, when using the FPC compiler. Useful to write code, that works with FPC and Delphi.<br />
* <div class="dir">{$IfDef Unix}</div>, <div class="dir">{$IfDef Win32}</div>, ...<br />
Defined by FPC for the current Target OS. Delphi defines "Linux", "Win32" and "MSWindows". [[Free Pascal]] runs on much more platforms and so it is recommended to use the more general items. For example "Unix" is defined for Linux, FreeBSD, NetBSD and OpenBSD, where Lazarus already runs.<br />
Use<br />
{$IfDef Linux}<br />
{$Define Unix}<br />
{$EndIf}<br />
to work around this for Kylix.<br />
<br />
For more details see the [http://www.freepascal.org/docs-html/prog/prog.html#QQ2-23-21 Free Pascal Documentation].<br />
<br />
==== Finding a missing identifier ====<br />
<br />
There are differences in how the LCL is organized when compared to the Delphi VCL. If you get a "not found" compiler error about a major class or identifier, the chances are good that it's in a different unit. A complete cross reference can be found by grep'ing lazarus/docs/xml or the lcl subdirectory.<br />
<br />
For example the commonly used tbutton typically throws an error in Delphi code because it's located in a unit named buttons.pp. The following command finds the correct unit very quickly (in the lazarus source directory):<br />
<br />
grep -in ' tbutton =' lcl/*<br />
<br />
<br />
==== Major unit differences between Lazarus and Delphi ====<br />
<br />
** Please add to this topic! **<br />
<br />
* Windows->Interfaces, LCLIntf, LCLType, LCLProc, VCLGlobals, ...)<br />
<br />
As the LCL is not windows specific, the code that is in the Delphi Windows unit for directly accessing the Win32 API is abstracted into seperate interfaces, which can be accessed from the LCLIntf unit. Keep in mind, that Lazarus does not emulate win32, so many functions are missing and some do not work as their win32 counterparts. These functions only exist for Delphi compatibility and should only be used for quick & dirty porting. LCL also breaks out many of the types, so often LCLType, and sometimes VCLGlobals are required. LCLProc also contains a few functions which can be useful for lower level handling such as "FreeThenNil" as is in Delphi 5 and higher, "DeleteAmpersands" to remove additional ampersands from a string for controls(& vs && etc). The Interfaces unit needs to be included in the .lpr file to initialize the appropriate widgetset.<br />
<br />
* Messages->LMessages<br />
<br />
TControl Messages for win32 event callbacks of the format WM_CALLBACK and the structs associated with them are often found in the Messages unit in Delphi. In the LCL these types of messages and there structs are usually found in LMessages, usually with name changes of WM to LM, so for instance WM_MOUSEENTER becomes LM_MOUSEENTER, and TWMMouse becomes TLMMouse.<br />
<br />
* Graphics, Controls->GraphTypes, GraphMath, Graphics, Controls<br />
<br />
To simplify some things and break complexity of circles between units, a few types have been abstracted into a shared unit called GraphType, which includes things, which in Delphi are located in Graphics or Controls, for instance the bvNone etc of panels. So sometimes you have to include it. Also a unit which, although incompatible with Delphi, adds other useful functionality is GraphMath, which adds a TFloatPoint for precision, misc routines for dealing with beziers, lines, and arcs, as well as some operator overloading for use with TPoints and TRect, such as for instance Point1 := Point2 + Point3, and comparing two rects like if (rect1 = rect2) then ...<br />
<br />
* Mask->MaskEdit<br />
<br />
For more intelligent naming considerations, the unit for TMaskEdit is called [MaskEdit|] instead of the slightly more nebulous Mask as in many versions of Delphi.<br />
<br />
* StdCtrls->StdCtrls,Buttons<br />
<br />
In many version of Delphi TButton is located in StdCtrls, while TSpeedButton and TBitBtn are in Buttons. For consistency and simplicity the LCL puts all button types in Buttons, which can occasionally break code conversion, so it is always a good idea to include.<br />
<br />
==== Property and method differences Delphi -> FPC/LCL ====<br />
* TBitmap contains a canvas in the LCL<br />
==== Syntax differences ====<br />
<br />
'''Please add to this topic!'''<br />
<br />
Because of the inherent strictness in FPC, some syntax changes are necessary, even though !!;dir {$Mode Delphi}!!;! does allow more lazyness like Delphi does. For this reason complying as much with the syntax rules of !!;dir {$Mode ObjFPC}!!;! as possible is highly recommended, even when the codebase is still going to be shared between Delphi and the LCL. Some of these are simply better coding practises, and sometimes because occasionally Delphi mode is not entirely accurate, or in a few instances Delphi acceptible code does not function as expected with FPC, even though it might compile. To that end even though not all such are strictly required, the following list of changes should be considered mandatory :<br />
<br />
;Variables initialization in FPC 1.0.x<br />
<br />
With Delphi it is possible (and quite common) to initialize a variable in its declaration, however this is not possible in FPC 1.0.x, const must be used instead, or prefereably in many situations, initialized elsewhere at some point before the variable is used (like unit initialization). <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">var</div><br />
MyObject: TSomeObject= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
| class="code" | <div class="key">var</div><br />
MyObject<div class="symbol">:</div> TSomeObject;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
MyObject:= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
;When assigning an event handling entry point, prefix it with an "@"<br />
<br />
For instance, you might assign a button callback manually <br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">begin</div> <br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= SomeFunction; <div class="cmt">//@ not required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">begin</div><br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= @SomeFunction; <div class="cmt">//@ IS required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When calling a procedure variable use this syntax: theprocname()<br />
<br />
In Delphi there is no difference between a procedure and a procedure variable, however there is in FPC, so to call a procedure, even if it has no paramaters, you must append parenthesis. For Example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div> <br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div> <br />
OnMyCallback; <div class="cmt">//parenthesis not required</div> <br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div><br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div><br />
OnMyCallback(); <div class="cmt">//parenthesis required</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When accessing values in a pointer to a record you must dereference first<br />
<br />
In Delphi it is not required to dereference a pointer to a record to acces values within it, it can in fact be treated just like the record itself, or any other object. In FPC it must be first dereferenced. As an example,<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord^.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>; <br />
|}<br />
<br />
;When accessing chars of an indexed string Property of an object, it must be enclosed in parenthesis<br />
<br />
With Delphi it is possible to treat a Property exactly like some other const or var, even to accessing for instance individual chars of a string directly, while this is not always possible in FPC, specifically for indexed properties. Instead it must be enclosed in parenthesis, to make distinct. While this may not always hold true it is probably a good practice to consider anyway. For example<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//no parenthesis needed</div><br />
MyChar:= MyString[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//parenthesis sometimes needed</div><br />
MyChar:= (MyString)[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
<br />
;You must typecast pointers to actual type when using with var or function of that type<br />
<br />
Sometimes in Delphi you will have a null pointer variable representing an object. While it might seem a complex situation, it is oddly quite common especially in large component packs as a method of preventing too many circular includes between objects in different units. In Delphi it is then possible to send this null pointer to a function expecting that object, without bothering to typecast to actual type, in fpc you must typecast. <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div><br />
<div class="symbol">Application</div><br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> GetSomeObject;<br />
<div class="cmt">//More code...</div><br />
DoSomething(MyComponent.SomeObject)<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="symbol">Application</div> <br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> Pointer(GetSomeObject);<br />
<div class="cmt">//More code...</div><br />
DoSomething(TSomeObject(MyComponent.SomeObject))<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Resources ====<br />
<br />
Delphi resource files are win32 specific and not compatible with Lazarus, so you'll have to recreate and compile them using the lazres. Lazres can be found in the lazarus/tools subdirectory. If you've downloaded the Lazarus sources, you'll need to compile it first.<br />
* cd lazarus/tools<br />
* make install<br />
To add a resource to your application:<br />
* lazres myresource.lrs mypix.xpm anotherpix.xpm<br />
* Add the LResources unit to your Uses clause<br />
* Include the .lrs file you created under the initialization block<br />
Example:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> TForm1.LoadGlyph(<div class="key">const</div> GlyphName: <div class="key">String</div>): TBitMap;<br />
<div class="key">begin</div><br />
Result:= TPixmap.Create<div class="symbol">;</div><br />
Result.LoadFromLazarusResource(GlyphName)<div class="symbol">;</div><br />
<div class="key">end</div>; <br />
<div class="cmt">//More code...</div><br />
<div class="key">begin</div><br />
Speedbutton1.glyph:= LoadGlyph('mypix')<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
<div></div> <br />
<div class="key">initialization</div><br />
<div class="dir">{$I unit1.lrs}</div><br />
<div class="dir">{$I myresource.lrs}</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
== Getting Help ==<br />
<br />
If you encounter a problem during conversion that you just can't solve, there are a wide variety of places to get help. For pure Object Pascal and FPC issues, the best place to start is the Free Pascal [http://www.freepascal.org/docs-html/ Documentation] by Michaël Van Canneyt and Florian Klämpfl. For more Lazarus oriented problems, the Lazarus Project Documentation in the Lazarus-CCR Knowledgebase [Main Page] is the next place to look. Finally you can post a question on any of the [http://www.freepascal.org/maillist.html mailing lists for the Free Pascal Compiler] or the [http://community.freepascal.org:10000/bboard/ FPC forums] where a lot of experts are subscribed.<br />
<br />
There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems. Tamarack Associates operates a fast [http://www.tamaracka.com/search.htm search] engine specifically for the Borland usenet archives. Mer Systems Inc. provides a similar search [http://www.mers.com/searchsite.html engine]. Another outstanding source of information along with a sitewide [http://www.efg2.com/Lab/search.htm search] capability is Earl F. Glynn's Computer Lab and Reference [http://www.efg2.com/ Library].<br />
<br />
== Packaging and Releasing your component ==<br />
<br />
=== Creating a Lazarus package for your component(s) ===<br />
<br />
Creating a package makes installing the code you've converted a much easier process... especially if you're providing more then one component. Mattias Gärtner has written an overview of [[Lazarus Packages]] that should be read before beginning this process.<br />
<br />
=== Documentation ===<br />
<br />
The purpose of this site and the wiki format is to make the generation of professional documentation an easy and quick process. The wiki also makes it possible to see the results of your posting immediately and make any changes you'd like in real time.<br />
<br />
Using the Lazarus-CCR wiki to create nice looking documentation is very easy. If you've never used wiki markup before, you can get familiar with it in the [[Sand Box]] practice area.<br />
<br />
=== Creating a Code Release Page ===<br />
<br />
The Code Release Page contains vital information about your component that a potential downloader will need to know, such as license, intended platform, status (alpha, beta, stable...), where to download it, who wrote it, is support available... etc.<br />
<br />
The following procedure will let you create a Code Release Page with your browser: <br />
<br />
* Edit the [[Code And Components]] page and add a project name wiki link entry for your component in the "Released Components" section. Save the modified page.<br />
<br />
* Go to the [[Component Release Template]], select all and copy. Hit the back button on your browser to return to the [[Code And Components]] page.<br />
* Click on your new wiki component name entry and paste the release template into the blank edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your document looks the way you want it to.<br />
<br />
=== Creating a Comment Page for your component ===<br />
<br />
When your component is posted to the Sourceforge File Release System, the Lazarus-CCR admins will lock your code release page to prevent the unlikely event of someone changing your license, name or other release info.<br />
<br />
While you're building your code release page, you have the option to create another wiki link to a "news and comments" page for your component that will always be writable. This is called a ComponentCommentTemplate. The link to it should be added to the bottom of the code release template where there's a topic heading and a brief howto. The wiki name link should be your wiki component name with a Comments suffix like [[EpikTimer Comments]] or [[JpegLazarus Comments]] . The comments page will remain writable to collect feedback from users and for you to post updated information.<br />
<br />
A comment page can be added like this:<br />
<br />
* Edit your component release page and add the wiki comment link (in the format described above). Save the modified page.<br />
* Go to the [[Component Comment Template]] , select all and copy. Hit the back button on your browser to return to your component release page.<br />
* Click on the comment entry entry you created and paste the comment template into the edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your comment page looks the way you want it to.<br />
<br />
While the Lazarus-CCR admins initially lock code release pages, any member of the project can use their shell acount to unlock, edit and re-lock their pages.<br />
<br />
=== Submitting the component ===<br />
<br />
If you're a release technician on the project, upload your component to the SourceForge File Release System and add it to the list of release packages. Otherwise send it to one of the project administrators and we'll add it to the repository. We'll also put it into CVS so you'll continue to have access to it.<br />
<br />
== Contributors and Changes ==<br />
<br />
This page has been converted from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=CodeConversionGuide version].<br />
* Initial version by Tom Lisjac and Mattias Gärtner - 9/22/2003 [[User:Tom | VlxAdmin]]<br />
* Moved Getting help from the main page. T. Lisjac - 9/24/2003 [[User:Tom | VlxAdmin]]<br />
* Added documentation templates, procedure and links. 9/25/2003 [[User:Tom | VlxAdmin]]<br />
* LCLLinux was renamed to LCLIntf, [[User:Jesusrmx | Jesus Reyes]], 9/27/2003<br />
* added more information on Unit changes, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Updated Syntax differences, including some examples, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* FPC 1.0.x doesn't support interfaces, [[User:Vincent | Vincent Snijders]] 9/28/2003<br />
* Fixed some of the examples per new WikiWord definition, 9/28/2003 [[User:Tom | VlxAdmin]]<br />
* Made code more consistant to remove last accidental Pascal WikiWord definitions, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/17/2003<br />
* Use pascal stylesheet to make example code more readable, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/18/2003</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Code_Conversion_Guide&diff=2425Code Conversion Guide2005-08-08T10:07:03Z<p>Wstomv: /* Major unit differences between Lazarus and Delphi */</p>
<hr />
<div>Delphi to Lazarus Code Conversion Guide<br />
<br />
== About ==<br />
<br />
This page is about how to convert existing code to work with the [[Free Pascal]] Compiler and Lazarus IDE. While Lazarus and the Free Pascal Compiler have aspects in common with Delphi and Kylix, they are not clones. There are a number of library call and convention differences... and in some areas, FPC is enhanced and can be more demanding about correct syntax. Please see the [[Lazarus For Delphi Users]] guide for a description of some of the functional differences. <br />
<br />
The purpose of this guide is to document some of the specific differences that are frequently encountered during the code conversion process when translating existing code from Delphi to Lazarus.<br />
<br />
This document was placed into the wiki knowledge-base area so it could be easily extended by anyone who had encountered a unique problem and would like to post it for others to be aware of.<br />
<br />
== Selecting a component or library for conversion ==<br />
<br />
=== Where to find code to convert ===<br />
<br />
There is a LOT of code available on the net that can be converted for use with FPC and Lazarus. Here is a [PageOfCodeSites|] that is just a start. Please add to it if you know of any other good locations. Turbo-Power Software has recently released their entire commercial offering under the MPL. A list of available packages can be found [http://sourceforge.net/users/tpsfadmin/|here].<br />
<br />
To avoid duplicating effort, packages that have already been converted are listed on the [CodeAndComponents|] page. If you've converted a package or are working on one, please add a note on the [CurrentProjects|] page.<br />
<br />
=== Licensing ===<br />
<br />
Licenses for existing code range from freeware/public domain to restrictive versions that prohibit modification, re-distribution and commercial use. Before converting any package, it's a good idea to examine its licensing and make sure it's going to be compatible with Lazarus and the Free Pascal Compiler. License selection is especially important with components since dropping one on a form can impose an unwanted or incompatible license on an entire application.<br />
<br />
When converting components, please respect the wishes of the original author and retain all copyright and licensing headers along with email addresses and url's. It's courteous and often useful to inform the author that their component is being converted... especially if the component is under a restrictive license. New interest in an old or forgotten component can sometimes inspire authors to revise their original and overly restrictive licensing.<br />
<br />
In general, Public Domain (freeware), and the LGPL/MPL are the the most flexible for distributing components. For more information, the [http://www.opensource.org/docs/definition.php Open Source Definition] is a good place to start. There are also several comparisons available to help clarify how the various types of licenses work and what impact they'll have on code they're linked to. Search for "open source license comparison"<br />
<br />
=== Dependencies ===<br />
<br />
Another step before starting to work on a conversion is to verify that the code doesn't have deep dependancies on other packages that might not be available or represent a considerable conversion challenge. Some freeware offerings are bound to or extend proprietary packages that are frequently no longer available or come with inappropriate licenses.<br />
<br />
=== Compiler Issues ===<br />
<br />
Currently the stable 1.0.x version of the Free Pascal Compiler doesn't support interfaces, threads or Variant records. If the code you're converting needs these constructs, you'll have to use the 1.1 development branch of the compiler... which isn't always guaranteed to work with Lazarus.<br />
<br />
=== Platform and OS Issues ===<br />
<br />
Lazarus and the Free Pascal Compiler are cross-platform and cross-architecture development tools. In contrast, most existing Delphi code was specifically designed to run on an Intel processor under Win32. If your candidate component has a lot of Win32 specific code, it might be wise to try and find a less platform dependant alternative. But don't let this stop you... it's genuinely amazing what the LCL supports!<br />
<br />
== Doing the conversion ==<br />
<br />
=== Setting up the Lazarus environment for a conversion project ===<br />
<br />
====Create a test project====<br />
* Place code to be converted into a subdirectory (ie: convertdir)<br />
* Bring up Lazarus<br />
* File->Save All to the convertdir subdirectory. Meaningful names for the Project and default unit are optional.<br />
* Open the "main" unit to be converted in convertdir<br />
* Add it to the project: Project->Add Active Unit to Project<br />
* Run Tools->Quick Syntax Check or Run Build All to get started.<br />
====Initial items to watch out for====<br />
* Filenames are case sensitive with the 1.0.x series compilers. If you're working with this version, make all your filenames lower case. You'll get "File not found" errors if you don't.<br />
====Delphi VCL, Kylix CLX Sources in Lazarus====<br />
<br />
When converting Delphi/Kylix sources, it is often useful to do a find declaration to see, what a specific function is doing. The Lazarus IDE can parse the Delphi/Kylix sources. To do this it needs some searchpaths and compiler settings. You can easily setup this in<br />
Environment->CodeTools Defines Editor->Insert Template<br />
<br />
=== Conversion problems and solutions ===<br />
<br />
==== Delphi / Kylix file equivalents in Lazarus ====<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi / Kylix || class="header" | Lazarus || class="header" | Description<br />
|- class="code"<br />
| class="code" |.pas<br />
.dfm / .xfm<br />
.dcu / .dpu<br />
.dpr<br />
.res<br />
.dof / .kof<br />
---<br />
---<br />
---<br />
| class="code" |.pas, .pp<br />
.lfm<br />
.o<br />
.lpr<br />
---<br />
---<br />
.lrs<br />
.lpi<br />
.ppu<br />
| class="code" |Pascal unit file<br />
Form data file<br />
Compiled unit file<br />
Project file<br />
Resource file<br />
Project options file<br />
Lazarus resource file<br />
Lazarus project information file<br />
FPC unit description file<br />
|}<br />
<br />
==== Converting Delphi projects/forms/units to Lazarus ====<br />
<br />
Rename or copy the .dpr file to a .lpr file. Comment out or remove the <div class="dir">{$R *.res}</div> directive and add a <div class="dir">{$mode delphi}{$H+}</div> or <div class="dir">{$mode objfpc}{$H+}</div> directive to the .lpr file. The Lazarus IDE can assist in this conversion through the Tools menu item "Convert Delphi Project to Lazarus Project". It asks for a .dpr (Delphi Project) file and converts it to .lpr; furthermore, it creates the .lpi file.<br />
<br />
Many existing Delphi forms can be converted to work with Lazarus by using the IDE's built in .dfm to .lfm form converter. It can be found under the Tools menu item as "Convert DFM file to LFM". Bring up the file dialog, select the dfm and the converter will do the rest.<br />
<br />
If you need to convert the whole unit (with or without a form), Lazarus also includes a built in "Convert Delphi unit to Lazarus unit" which will do the following for you -<br />
<br />
# renames the .pas and .dfm file to lowercase.<br />
# converts .dfm file to .lfm file (currently without content check, just format)<br />
# creates an empty .lrs file (the content will be created later)<br />
# adds <div class="dir">{$mode delphi}</div> directive<br />
# replaces windows unit with LCLIntf<br />
# adds LResources unit if needed<br />
# removes variants unit<br />
# removes <div class="dir">{$R *.dfm}</div> directive<br />
# adds initialization section and <div class="dir">{$i unit.lrs}</div> directive<br />
<br />
This allows quick and easy conversion of most units from Delphi format to Lazarus format. It does not do any validity check, or automatic syntax changes, so any syntax changes you need to make, additional unit/unit name changes, or dfm/pas changes for control/component differences you must still do manually, though in time some wizards to help facilitate some of this, especially the repairing of converted forms(lfm), may become available.<br />
<br />
==== Selecting the right compiler mode ====<br />
<br />
The [[Free Pascal]] Compiler supports 5 different pascal modes. For example TP for turbo pascal, lets you compile turbo pascal units. There is also a DELPHI compatibility mode that can be set to make existing code easier to convert. Lazarus prefers the OBJFPC mode, which almost equals the DELPHI mode, but is less ambigious than the Delphi syntax. Here are the important points:<br />
<br />
The mode can be selected at command line or at the start of the source. Using the command line has the advantage, that you don't need to change the source, but the disadvantage, that others must be told.<br />
<br />
Most Delphi units can be compiled by the [[Free Pascal]] compiler by adding <br />
{$IFDEF FPC}<br />
{$MODE DELPHI}<br />
{$ENDIF}<br />
right after the unit name.<br />
<br />
For more details about [[Free Pascal]] modes see the [http://www.freepascal.org/docs-html/prog/progap4.html#progse62.html Free Pascal Documentation]<br />
<br />
==== Cross-Platform considerations ====<br />
<br />
* Inline assembler is always a problem because it will bind the code to the Intel architecture. Some developers do algorithm prototypes in Pascal and ifdef the their optimized assembler. Fortunately Turbo-Power did this in numerous places with their code. If this is the case with the package you're converting, throw the switch back to Pascal.<br />
* Don't reference specific memory location like the BIOS data area. Find out what the code needs and try to find a cross platform alternative.<br />
* Don't do processor specific tricks (like using the Intel TSC) without enclosing your code in an ifdef for the platform the code needs... and providing an alternative for environments that don't have the hardware capability.<br />
* If you need some OS specific code, then you can use IFDEFs. See below for a list of macros.<br />
<br />
==== Useful compiler variables ====<br />
<br />
To write code, that behaves on different systems differently, you can use the <div class="dir">{$IFDEF Name}</div> directives.<br />
<br />
* <div class="dir">{$IfDef LCL}</div><br />
This variable is defined, when using the LCL package. Useful to write code, that works with the LCL and Delphi.<br />
* <div class="dir">{$IfDef FPC}</div><br />
This variable is defined, when using the FPC compiler. Useful to write code, that works with FPC and Delphi.<br />
* <div class="dir">{$IfDef Unix}</div>, <div class="dir">{$IfDef Win32}</div>, ...<br />
Defined by FPC for the current Target OS. Delphi defines "Linux", "Win32" and "MSWindows". [[Free Pascal]] runs on much more platforms and so it is recommended to use the more general items. For example "Unix" is defined for Linux, FreeBSD, NetBSD and OpenBSD, where Lazarus already runs.<br />
Use<br />
{$IfDef Linux}<br />
{$Define Unix}<br />
{$EndIf}<br />
to work around this for Kylix.<br />
<br />
For more details see the [http://www.freepascal.org/docs-html/prog/prog.html#QQ2-23-21 Free Pascal Documentation].<br />
<br />
==== Finding a missing identifier ====<br />
<br />
There are differences in how the LCL is organized when compared to the Delphi VCL. If you get a "not found" compiler error about a major class or identifier, the chances are good that it's in a different unit. A complete cross reference can be found by grep'ing lazarus/docs/xml or the lcl subdirectory.<br />
<br />
For example the commonly used tbutton typically throws an error in Delphi code because it's located in a unit named buttons.pp. The following command finds the correct unit very quickly (in the lazarus source directory):<br />
<br />
grep -in ' tbutton =' lcl/*<br />
<br />
<br />
==== Major unit differences between Lazarus and Delphi ====<br />
<br />
** Please add to this topic! **<br />
<br />
* Windows->LCLIntf, LCLType, LCLProc, VCLGlobals, ...)<br />
<br />
As the LCL is not windows specific, the code that is in the Delphi Windows unit for directly accessing the Win32 API is abstracted into seperate interfaces, which can be accessed from the LCLIntf unit. Keep in mind, that Lazarus does not emulate win32, so many functions are missing and some do not work as their win32 counterparts. These functions only exist for Delphi compatibility and should only be used for quick & dirty porting. LCL also breaks out many of the types, so often LCLType, and sometimes VCLGlobals are required. LCLProc also contains a few functions which can be useful for lower level handling such as "FreeThenNil" as is in Delphi 5 and higher, "DeleteAmpersands" to remove additional ampersands from a string for controls(& vs && etc).<br />
<br />
* Messages->LMessages<br />
<br />
TControl Messages for win32 event callbacks of the format WM_CALLBACK and the structs associated with them are often found in the Messages unit in Delphi. In the LCL these types of messages and there structs are usually found in LMessages, usually with name changes of WM to LM, so for instance WM_MOUSEENTER becomes LM_MOUSEENTER, and TWMMouse becomes TLMMouse.<br />
<br />
* Graphics, Controls->GraphTypes, GraphMath, Graphics, Controls<br />
<br />
To simplify some things and break complexity of circles between units, a few types have been abstracted into a shared unit called GraphType, which includes things, which in Delphi are located in Graphics or Controls, for instance the bvNone etc of panels. So sometimes you have to include it. Also a unit which, although incompatible with Delphi, adds other useful functionality is GraphMath, which adds a TFloatPoint for precision, misc routines for dealing with beziers, lines, and arcs, as well as some operator overloading for use with TPoints and TRect, such as for instance Point1 := Point2 + Point3, and comparing two rects like if (rect1 = rect2) then ...<br />
<br />
* Mask->MaskEdit<br />
<br />
For more intelligent naming considerations, the unit for TMaskEdit is called [MaskEdit|] instead of the slightly more nebulous Mask as in many versions of Delphi.<br />
<br />
* StdCtrls->StdCtrls,Buttons<br />
<br />
In many version of Delphi TButton is located in StdCtrls, while TSpeedButton and TBitBtn are in Buttons. For consistency and simplicity the LCL puts all button types in Buttons, which can occasionally break code conversion, so it is always a good idea to include.<br />
<br />
==== Property and method differences Delphi -> FPC/LCL ====<br />
* TBitmap contains a canvas in the LCL<br />
==== Syntax differences ====<br />
<br />
'''Please add to this topic!'''<br />
<br />
Because of the inherent strictness in FPC, some syntax changes are necessary, even though !!;dir {$Mode Delphi}!!;! does allow more lazyness like Delphi does. For this reason complying as much with the syntax rules of !!;dir {$Mode ObjFPC}!!;! as possible is highly recommended, even when the codebase is still going to be shared between Delphi and the LCL. Some of these are simply better coding practises, and sometimes because occasionally Delphi mode is not entirely accurate, or in a few instances Delphi acceptible code does not function as expected with FPC, even though it might compile. To that end even though not all such are strictly required, the following list of changes should be considered mandatory :<br />
<br />
;Variables initialization in FPC 1.0.x<br />
<br />
With Delphi it is possible (and quite common) to initialize a variable in its declaration, however this is not possible in FPC 1.0.x, const must be used instead, or prefereably in many situations, initialized elsewhere at some point before the variable is used (like unit initialization). <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">var</div><br />
MyObject: TSomeObject= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
| class="code" | <div class="key">var</div><br />
MyObject<div class="symbol">:</div> TSomeObject;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
MyObject:= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
;When assigning an event handling entry point, prefix it with an "@"<br />
<br />
For instance, you might assign a button callback manually <br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">begin</div> <br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= SomeFunction; <div class="cmt">//@ not required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">begin</div><br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= @SomeFunction; <div class="cmt">//@ IS required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When calling a procedure variable use this syntax: theprocname()<br />
<br />
In Delphi there is no difference between a procedure and a procedure variable, however there is in FPC, so to call a procedure, even if it has no paramaters, you must append parenthesis. For Example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div> <br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div> <br />
OnMyCallback; <div class="cmt">//parenthesis not required</div> <br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div><br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div><br />
OnMyCallback(); <div class="cmt">//parenthesis required</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When accessing values in a pointer to a record you must dereference first<br />
<br />
In Delphi it is not required to dereference a pointer to a record to acces values within it, it can in fact be treated just like the record itself, or any other object. In FPC it must be first dereferenced. As an example,<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord^.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>; <br />
|}<br />
<br />
;When accessing chars of an indexed string Property of an object, it must be enclosed in parenthesis<br />
<br />
With Delphi it is possible to treat a Property exactly like some other const or var, even to accessing for instance individual chars of a string directly, while this is not always possible in FPC, specifically for indexed properties. Instead it must be enclosed in parenthesis, to make distinct. While this may not always hold true it is probably a good practice to consider anyway. For example<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//no parenthesis needed</div><br />
MyChar:= MyString[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//parenthesis sometimes needed</div><br />
MyChar:= (MyString)[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
<br />
;You must typecast pointers to actual type when using with var or function of that type<br />
<br />
Sometimes in Delphi you will have a null pointer variable representing an object. While it might seem a complex situation, it is oddly quite common especially in large component packs as a method of preventing too many circular includes between objects in different units. In Delphi it is then possible to send this null pointer to a function expecting that object, without bothering to typecast to actual type, in fpc you must typecast. <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div><br />
<div class="symbol">Application</div><br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> GetSomeObject;<br />
<div class="cmt">//More code...</div><br />
DoSomething(MyComponent.SomeObject)<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="symbol">Application</div> <br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> Pointer(GetSomeObject);<br />
<div class="cmt">//More code...</div><br />
DoSomething(TSomeObject(MyComponent.SomeObject))<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Resources ====<br />
<br />
Delphi resource files are win32 specific and not compatible with Lazarus, so you'll have to recreate and compile them using the lazres. Lazres can be found in the lazarus/tools subdirectory. If you've downloaded the Lazarus sources, you'll need to compile it first.<br />
* cd lazarus/tools<br />
* make install<br />
To add a resource to your application:<br />
* lazres myresource.lrs mypix.xpm anotherpix.xpm<br />
* Add the LResources unit to your Uses clause<br />
* Include the .lrs file you created under the initialization block<br />
Example:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> TForm1.LoadGlyph(<div class="key">const</div> GlyphName: <div class="key">String</div>): TBitMap;<br />
<div class="key">begin</div><br />
Result:= TPixmap.Create<div class="symbol">;</div><br />
Result.LoadFromLazarusResource(GlyphName)<div class="symbol">;</div><br />
<div class="key">end</div>; <br />
<div class="cmt">//More code...</div><br />
<div class="key">begin</div><br />
Speedbutton1.glyph:= LoadGlyph('mypix')<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
<div></div> <br />
<div class="key">initialization</div><br />
<div class="dir">{$I unit1.lrs}</div><br />
<div class="dir">{$I myresource.lrs}</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
== Getting Help ==<br />
<br />
If you encounter a problem during conversion that you just can't solve, there are a wide variety of places to get help. For pure Object Pascal and FPC issues, the best place to start is the Free Pascal [http://www.freepascal.org/docs-html/ Documentation] by Michaël Van Canneyt and Florian Klämpfl. For more Lazarus oriented problems, the Lazarus Project Documentation in the Lazarus-CCR Knowledgebase [Main Page] is the next place to look. Finally you can post a question on any of the [http://www.freepascal.org/maillist.html mailing lists for the Free Pascal Compiler] or the [http://community.freepascal.org:10000/bboard/ FPC forums] where a lot of experts are subscribed.<br />
<br />
There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems. Tamarack Associates operates a fast [http://www.tamaracka.com/search.htm search] engine specifically for the Borland usenet archives. Mer Systems Inc. provides a similar search [http://www.mers.com/searchsite.html engine]. Another outstanding source of information along with a sitewide [http://www.efg2.com/Lab/search.htm search] capability is Earl F. Glynn's Computer Lab and Reference [http://www.efg2.com/ Library].<br />
<br />
== Packaging and Releasing your component ==<br />
<br />
=== Creating a Lazarus package for your component(s) ===<br />
<br />
Creating a package makes installing the code you've converted a much easier process... especially if you're providing more then one component. Mattias Gärtner has written an overview of [[Lazarus Packages]] that should be read before beginning this process.<br />
<br />
=== Documentation ===<br />
<br />
The purpose of this site and the wiki format is to make the generation of professional documentation an easy and quick process. The wiki also makes it possible to see the results of your posting immediately and make any changes you'd like in real time.<br />
<br />
Using the Lazarus-CCR wiki to create nice looking documentation is very easy. If you've never used wiki markup before, you can get familiar with it in the [[Sand Box]] practice area.<br />
<br />
=== Creating a Code Release Page ===<br />
<br />
The Code Release Page contains vital information about your component that a potential downloader will need to know, such as license, intended platform, status (alpha, beta, stable...), where to download it, who wrote it, is support available... etc.<br />
<br />
The following procedure will let you create a Code Release Page with your browser: <br />
<br />
* Edit the [[Code And Components]] page and add a project name wiki link entry for your component in the "Released Components" section. Save the modified page.<br />
<br />
* Go to the [[Component Release Template]], select all and copy. Hit the back button on your browser to return to the [[Code And Components]] page.<br />
* Click on your new wiki component name entry and paste the release template into the blank edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your document looks the way you want it to.<br />
<br />
=== Creating a Comment Page for your component ===<br />
<br />
When your component is posted to the Sourceforge File Release System, the Lazarus-CCR admins will lock your code release page to prevent the unlikely event of someone changing your license, name or other release info.<br />
<br />
While you're building your code release page, you have the option to create another wiki link to a "news and comments" page for your component that will always be writable. This is called a ComponentCommentTemplate. The link to it should be added to the bottom of the code release template where there's a topic heading and a brief howto. The wiki name link should be your wiki component name with a Comments suffix like [[EpikTimer Comments]] or [[JpegLazarus Comments]] . The comments page will remain writable to collect feedback from users and for you to post updated information.<br />
<br />
A comment page can be added like this:<br />
<br />
* Edit your component release page and add the wiki comment link (in the format described above). Save the modified page.<br />
* Go to the [[Component Comment Template]] , select all and copy. Hit the back button on your browser to return to your component release page.<br />
* Click on the comment entry entry you created and paste the comment template into the edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your comment page looks the way you want it to.<br />
<br />
While the Lazarus-CCR admins initially lock code release pages, any member of the project can use their shell acount to unlock, edit and re-lock their pages.<br />
<br />
=== Submitting the component ===<br />
<br />
If you're a release technician on the project, upload your component to the SourceForge File Release System and add it to the list of release packages. Otherwise send it to one of the project administrators and we'll add it to the repository. We'll also put it into CVS so you'll continue to have access to it.<br />
<br />
== Contributors and Changes ==<br />
<br />
This page has been converted from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=CodeConversionGuide version].<br />
* Initial version by Tom Lisjac and Mattias Gärtner - 9/22/2003 [[User:Tom | VlxAdmin]]<br />
* Moved Getting help from the main page. T. Lisjac - 9/24/2003 [[User:Tom | VlxAdmin]]<br />
* Added documentation templates, procedure and links. 9/25/2003 [[User:Tom | VlxAdmin]]<br />
* LCLLinux was renamed to LCLIntf, [[User:Jesusrmx | Jesus Reyes]], 9/27/2003<br />
* added more information on Unit changes, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Updated Syntax differences, including some examples, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* FPC 1.0.x doesn't support interfaces, [[User:Vincent | Vincent Snijders]] 9/28/2003<br />
* Fixed some of the examples per new WikiWord definition, 9/28/2003 [[User:Tom | VlxAdmin]]<br />
* Made code more consistant to remove last accidental Pascal WikiWord definitions, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/17/2003<br />
* Use pascal stylesheet to make example code more readable, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/18/2003</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Code_Conversion_Guide&diff=2424Code Conversion Guide2005-08-08T10:04:32Z<p>Wstomv: /* Major unit differences between Lazarus and Delphi */</p>
<hr />
<div>Delphi to Lazarus Code Conversion Guide<br />
<br />
== About ==<br />
<br />
This page is about how to convert existing code to work with the [[Free Pascal]] Compiler and Lazarus IDE. While Lazarus and the Free Pascal Compiler have aspects in common with Delphi and Kylix, they are not clones. There are a number of library call and convention differences... and in some areas, FPC is enhanced and can be more demanding about correct syntax. Please see the [[Lazarus For Delphi Users]] guide for a description of some of the functional differences. <br />
<br />
The purpose of this guide is to document some of the specific differences that are frequently encountered during the code conversion process when translating existing code from Delphi to Lazarus.<br />
<br />
This document was placed into the wiki knowledge-base area so it could be easily extended by anyone who had encountered a unique problem and would like to post it for others to be aware of.<br />
<br />
== Selecting a component or library for conversion ==<br />
<br />
=== Where to find code to convert ===<br />
<br />
There is a LOT of code available on the net that can be converted for use with FPC and Lazarus. Here is a [PageOfCodeSites|] that is just a start. Please add to it if you know of any other good locations. Turbo-Power Software has recently released their entire commercial offering under the MPL. A list of available packages can be found [http://sourceforge.net/users/tpsfadmin/|here].<br />
<br />
To avoid duplicating effort, packages that have already been converted are listed on the [CodeAndComponents|] page. If you've converted a package or are working on one, please add a note on the [CurrentProjects|] page.<br />
<br />
=== Licensing ===<br />
<br />
Licenses for existing code range from freeware/public domain to restrictive versions that prohibit modification, re-distribution and commercial use. Before converting any package, it's a good idea to examine its licensing and make sure it's going to be compatible with Lazarus and the Free Pascal Compiler. License selection is especially important with components since dropping one on a form can impose an unwanted or incompatible license on an entire application.<br />
<br />
When converting components, please respect the wishes of the original author and retain all copyright and licensing headers along with email addresses and url's. It's courteous and often useful to inform the author that their component is being converted... especially if the component is under a restrictive license. New interest in an old or forgotten component can sometimes inspire authors to revise their original and overly restrictive licensing.<br />
<br />
In general, Public Domain (freeware), and the LGPL/MPL are the the most flexible for distributing components. For more information, the [http://www.opensource.org/docs/definition.php Open Source Definition] is a good place to start. There are also several comparisons available to help clarify how the various types of licenses work and what impact they'll have on code they're linked to. Search for "open source license comparison"<br />
<br />
=== Dependencies ===<br />
<br />
Another step before starting to work on a conversion is to verify that the code doesn't have deep dependancies on other packages that might not be available or represent a considerable conversion challenge. Some freeware offerings are bound to or extend proprietary packages that are frequently no longer available or come with inappropriate licenses.<br />
<br />
=== Compiler Issues ===<br />
<br />
Currently the stable 1.0.x version of the Free Pascal Compiler doesn't support interfaces, threads or Variant records. If the code you're converting needs these constructs, you'll have to use the 1.1 development branch of the compiler... which isn't always guaranteed to work with Lazarus.<br />
<br />
=== Platform and OS Issues ===<br />
<br />
Lazarus and the Free Pascal Compiler are cross-platform and cross-architecture development tools. In contrast, most existing Delphi code was specifically designed to run on an Intel processor under Win32. If your candidate component has a lot of Win32 specific code, it might be wise to try and find a less platform dependant alternative. But don't let this stop you... it's genuinely amazing what the LCL supports!<br />
<br />
== Doing the conversion ==<br />
<br />
=== Setting up the Lazarus environment for a conversion project ===<br />
<br />
====Create a test project====<br />
* Place code to be converted into a subdirectory (ie: convertdir)<br />
* Bring up Lazarus<br />
* File->Save All to the convertdir subdirectory. Meaningful names for the Project and default unit are optional.<br />
* Open the "main" unit to be converted in convertdir<br />
* Add it to the project: Project->Add Active Unit to Project<br />
* Run Tools->Quick Syntax Check or Run Build All to get started.<br />
====Initial items to watch out for====<br />
* Filenames are case sensitive with the 1.0.x series compilers. If you're working with this version, make all your filenames lower case. You'll get "File not found" errors if you don't.<br />
====Delphi VCL, Kylix CLX Sources in Lazarus====<br />
<br />
When converting Delphi/Kylix sources, it is often useful to do a find declaration to see, what a specific function is doing. The Lazarus IDE can parse the Delphi/Kylix sources. To do this it needs some searchpaths and compiler settings. You can easily setup this in<br />
Environment->CodeTools Defines Editor->Insert Template<br />
<br />
=== Conversion problems and solutions ===<br />
<br />
==== Delphi / Kylix file equivalents in Lazarus ====<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi / Kylix || class="header" | Lazarus || class="header" | Description<br />
|- class="code"<br />
| class="code" |.pas<br />
.dfm / .xfm<br />
.dcu / .dpu<br />
.dpr<br />
.res<br />
.dof / .kof<br />
---<br />
---<br />
---<br />
| class="code" |.pas, .pp<br />
.lfm<br />
.o<br />
.lpr<br />
---<br />
---<br />
.lrs<br />
.lpi<br />
.ppu<br />
| class="code" |Pascal unit file<br />
Form data file<br />
Compiled unit file<br />
Project file<br />
Resource file<br />
Project options file<br />
Lazarus resource file<br />
Lazarus project information file<br />
FPC unit description file<br />
|}<br />
<br />
==== Converting Delphi projects/forms/units to Lazarus ====<br />
<br />
Rename or copy the .dpr file to a .lpr file. Comment out or remove the <div class="dir">{$R *.res}</div> directive and add a <div class="dir">{$mode delphi}{$H+}</div> or <div class="dir">{$mode objfpc}{$H+}</div> directive to the .lpr file. The Lazarus IDE can assist in this conversion through the Tools menu item "Convert Delphi Project to Lazarus Project". It asks for a .dpr (Delphi Project) file and converts it to .lpr; furthermore, it creates the .lpi file.<br />
<br />
Many existing Delphi forms can be converted to work with Lazarus by using the IDE's built in .dfm to .lfm form converter. It can be found under the Tools menu item as "Convert DFM file to LFM". Bring up the file dialog, select the dfm and the converter will do the rest.<br />
<br />
If you need to convert the whole unit (with or without a form), Lazarus also includes a built in "Convert Delphi unit to Lazarus unit" which will do the following for you -<br />
<br />
# renames the .pas and .dfm file to lowercase.<br />
# converts .dfm file to .lfm file (currently without content check, just format)<br />
# creates an empty .lrs file (the content will be created later)<br />
# adds <div class="dir">{$mode delphi}</div> directive<br />
# replaces windows unit with LCLIntf<br />
# adds LResources unit if needed<br />
# removes variants unit<br />
# removes <div class="dir">{$R *.dfm}</div> directive<br />
# adds initialization section and <div class="dir">{$i unit.lrs}</div> directive<br />
<br />
This allows quick and easy conversion of most units from Delphi format to Lazarus format. It does not do any validity check, or automatic syntax changes, so any syntax changes you need to make, additional unit/unit name changes, or dfm/pas changes for control/component differences you must still do manually, though in time some wizards to help facilitate some of this, especially the repairing of converted forms(lfm), may become available.<br />
<br />
==== Selecting the right compiler mode ====<br />
<br />
The [[Free Pascal]] Compiler supports 5 different pascal modes. For example TP for turbo pascal, lets you compile turbo pascal units. There is also a DELPHI compatibility mode that can be set to make existing code easier to convert. Lazarus prefers the OBJFPC mode, which almost equals the DELPHI mode, but is less ambigious than the Delphi syntax. Here are the important points:<br />
<br />
The mode can be selected at command line or at the start of the source. Using the command line has the advantage, that you don't need to change the source, but the disadvantage, that others must be told.<br />
<br />
Most Delphi units can be compiled by the [[Free Pascal]] compiler by adding <br />
{$IFDEF FPC}<br />
{$MODE DELPHI}<br />
{$ENDIF}<br />
right after the unit name.<br />
<br />
For more details about [[Free Pascal]] modes see the [http://www.freepascal.org/docs-html/prog/progap4.html#progse62.html Free Pascal Documentation]<br />
<br />
==== Cross-Platform considerations ====<br />
<br />
* Inline assembler is always a problem because it will bind the code to the Intel architecture. Some developers do algorithm prototypes in Pascal and ifdef the their optimized assembler. Fortunately Turbo-Power did this in numerous places with their code. If this is the case with the package you're converting, throw the switch back to Pascal.<br />
* Don't reference specific memory location like the BIOS data area. Find out what the code needs and try to find a cross platform alternative.<br />
* Don't do processor specific tricks (like using the Intel TSC) without enclosing your code in an ifdef for the platform the code needs... and providing an alternative for environments that don't have the hardware capability.<br />
* If you need some OS specific code, then you can use IFDEFs. See below for a list of macros.<br />
<br />
==== Useful compiler variables ====<br />
<br />
To write code, that behaves on different systems differently, you can use the <div class="dir">{$IFDEF Name}</div> directives.<br />
<br />
* <div class="dir">{$IfDef LCL}</div><br />
This variable is defined, when using the LCL package. Useful to write code, that works with the LCL and Delphi.<br />
* <div class="dir">{$IfDef FPC}</div><br />
This variable is defined, when using the FPC compiler. Useful to write code, that works with FPC and Delphi.<br />
* <div class="dir">{$IfDef Unix}</div>, <div class="dir">{$IfDef Win32}</div>, ...<br />
Defined by FPC for the current Target OS. Delphi defines "Linux", "Win32" and "MSWindows". [[Free Pascal]] runs on much more platforms and so it is recommended to use the more general items. For example "Unix" is defined for Linux, FreeBSD, NetBSD and OpenBSD, where Lazarus already runs.<br />
Use<br />
{$IfDef Linux}<br />
{$Define Unix}<br />
{$EndIf}<br />
to work around this for Kylix.<br />
<br />
For more details see the [http://www.freepascal.org/docs-html/prog/prog.html#QQ2-23-21 Free Pascal Documentation].<br />
<br />
==== Finding a missing identifier ====<br />
<br />
There are differences in how the LCL is organized when compared to the Delphi VCL. If you get a "not found" compiler error about a major class or identifier, the chances are good that it's in a different unit. A complete cross reference can be found by grep'ing lazarus/docs/xml or the lcl subdirectory.<br />
<br />
For example the commonly used tbutton typically throws an error in Delphi code because it's located in a unit named buttons.pp. The following command finds the correct unit very quickly (in the lazarus source directory):<br />
<br />
grep -in ' tbutton =' lcl/*<br />
<br />
<br />
==== Major unit differences between Lazarus and Delphi ====<br />
<br />
** Please add to this topic! **<br />
<br />
* Windows->LCLIntf, LCLType, LCLProc, VCLGlobals, ...)<br />
<br />
As the LCL is not windows specific, the code that is in the Delphi Windows unit for directly accessing the Win32 API is abstracted into seperate interfaces, which can be accessed from the LCLIntf unit. Keep in mind, that Lazarus does not emulate win32, so many functions are missing and some do not work as their win32 counterparts. These functions only exist for Delphi compatibility and should only be used for quick & dirty porting. LCL also breaks out many of the types, so often LCLType, and sometimes VCLGlobals are required. LCLProc also contains a few functions which can be useful for lower level handling such as "FreeThenNil" as is in Delphi 5 and higher, "DeleteAmpersands" to remove additional ampersands from a string for controls(& vs && etc).<br />
<br />
* Messages->LMessages<br />
<br />
TControl Messages for win32 event callbacks of the format WM_CALLBACK and the structs associated with them are often found in the Messages unit in Delphi. In the LCL these types of messages and there structs are usually found in LMessages, usually with name changes of WM to LM, so for instance WM_MOUSEENTER becomes LM_MOUSEENTER, and TWMMouse becomes TLMMouse.<br />
<br />
* Graphics, Controls->GraphTypes, GraphMath, Graphics, Controls<br />
<br />
To simplify some things and break complexity of circles between units, a few types have been abstracted into a shared unit called GraphType, which includes things, which in Delphi are located in Graphics or Controls, for instance the bvNone etc of panels. So sometimes you have to include it. Also a unit which, although incompatible with Delphi, adds other usefull functionality is GraphMath, which adds a TFloatPoint for precision, misc routines for dealing with beziers, lines, and arcs, as well as some operator overloading for use with TPoints and TRect, such as for instance Point1 := Point2 + Point3, and comparing two rects like if (rect1 = rect2) then ...<br />
<br />
* Mask->MaskEdit<br />
<br />
For more intelligent naming considerations, the unit for TMaskEdit is called [MaskEdit|] instead of the slightly more nebulous Mask as in many versions of Delphi.<br />
<br />
* StdCtrls->StdCtrls,Buttons<br />
<br />
In many version of Delphi TButton is located in StdCtrls, while TSpeedButton and TBitBtn are in Buttons. For consistency and simplicity the LCL puts all button types in Buttons, which can occasionally break code conversion, so it is always a good idea to include.<br />
<br />
==== Property and method differences Delphi -> FPC/LCL ====<br />
* TBitmap contains a canvas in the LCL<br />
==== Syntax differences ====<br />
<br />
'''Please add to this topic!'''<br />
<br />
Because of the inherent strictness in FPC, some syntax changes are necessary, even though !!;dir {$Mode Delphi}!!;! does allow more lazyness like Delphi does. For this reason complying as much with the syntax rules of !!;dir {$Mode ObjFPC}!!;! as possible is highly recommended, even when the codebase is still going to be shared between Delphi and the LCL. Some of these are simply better coding practises, and sometimes because occasionally Delphi mode is not entirely accurate, or in a few instances Delphi acceptible code does not function as expected with FPC, even though it might compile. To that end even though not all such are strictly required, the following list of changes should be considered mandatory :<br />
<br />
;Variables initialization in FPC 1.0.x<br />
<br />
With Delphi it is possible (and quite common) to initialize a variable in its declaration, however this is not possible in FPC 1.0.x, const must be used instead, or prefereably in many situations, initialized elsewhere at some point before the variable is used (like unit initialization). <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">var</div><br />
MyObject: TSomeObject= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
| class="code" | <div class="key">var</div><br />
MyObject<div class="symbol">:</div> TSomeObject;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
MyObject:= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
;When assigning an event handling entry point, prefix it with an "@"<br />
<br />
For instance, you might assign a button callback manually <br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">begin</div> <br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= SomeFunction; <div class="cmt">//@ not required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">begin</div><br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= @SomeFunction; <div class="cmt">//@ IS required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When calling a procedure variable use this syntax: theprocname()<br />
<br />
In Delphi there is no difference between a procedure and a procedure variable, however there is in FPC, so to call a procedure, even if it has no paramaters, you must append parenthesis. For Example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div> <br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div> <br />
OnMyCallback; <div class="cmt">//parenthesis not required</div> <br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div><br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div><br />
OnMyCallback(); <div class="cmt">//parenthesis required</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When accessing values in a pointer to a record you must dereference first<br />
<br />
In Delphi it is not required to dereference a pointer to a record to acces values within it, it can in fact be treated just like the record itself, or any other object. In FPC it must be first dereferenced. As an example,<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord^.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>; <br />
|}<br />
<br />
;When accessing chars of an indexed string Property of an object, it must be enclosed in parenthesis<br />
<br />
With Delphi it is possible to treat a Property exactly like some other const or var, even to accessing for instance individual chars of a string directly, while this is not always possible in FPC, specifically for indexed properties. Instead it must be enclosed in parenthesis, to make distinct. While this may not always hold true it is probably a good practice to consider anyway. For example<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//no parenthesis needed</div><br />
MyChar:= MyString[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//parenthesis sometimes needed</div><br />
MyChar:= (MyString)[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
<br />
;You must typecast pointers to actual type when using with var or function of that type<br />
<br />
Sometimes in Delphi you will have a null pointer variable representing an object. While it might seem a complex situation, it is oddly quite common especially in large component packs as a method of preventing too many circular includes between objects in different units. In Delphi it is then possible to send this null pointer to a function expecting that object, without bothering to typecast to actual type, in fpc you must typecast. <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div><br />
<div class="symbol">Application</div><br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> GetSomeObject;<br />
<div class="cmt">//More code...</div><br />
DoSomething(MyComponent.SomeObject)<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="symbol">Application</div> <br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> Pointer(GetSomeObject);<br />
<div class="cmt">//More code...</div><br />
DoSomething(TSomeObject(MyComponent.SomeObject))<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Resources ====<br />
<br />
Delphi resource files are win32 specific and not compatible with Lazarus, so you'll have to recreate and compile them using the lazres. Lazres can be found in the lazarus/tools subdirectory. If you've downloaded the Lazarus sources, you'll need to compile it first.<br />
* cd lazarus/tools<br />
* make install<br />
To add a resource to your application:<br />
* lazres myresource.lrs mypix.xpm anotherpix.xpm<br />
* Add the LResources unit to your Uses clause<br />
* Include the .lrs file you created under the initialization block<br />
Example:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> TForm1.LoadGlyph(<div class="key">const</div> GlyphName: <div class="key">String</div>): TBitMap;<br />
<div class="key">begin</div><br />
Result:= TPixmap.Create<div class="symbol">;</div><br />
Result.LoadFromLazarusResource(GlyphName)<div class="symbol">;</div><br />
<div class="key">end</div>; <br />
<div class="cmt">//More code...</div><br />
<div class="key">begin</div><br />
Speedbutton1.glyph:= LoadGlyph('mypix')<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
<div></div> <br />
<div class="key">initialization</div><br />
<div class="dir">{$I unit1.lrs}</div><br />
<div class="dir">{$I myresource.lrs}</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
== Getting Help ==<br />
<br />
If you encounter a problem during conversion that you just can't solve, there are a wide variety of places to get help. For pure Object Pascal and FPC issues, the best place to start is the Free Pascal [http://www.freepascal.org/docs-html/ Documentation] by Michaël Van Canneyt and Florian Klämpfl. For more Lazarus oriented problems, the Lazarus Project Documentation in the Lazarus-CCR Knowledgebase [Main Page] is the next place to look. Finally you can post a question on any of the [http://www.freepascal.org/maillist.html mailing lists for the Free Pascal Compiler] or the [http://community.freepascal.org:10000/bboard/ FPC forums] where a lot of experts are subscribed.<br />
<br />
There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems. Tamarack Associates operates a fast [http://www.tamaracka.com/search.htm search] engine specifically for the Borland usenet archives. Mer Systems Inc. provides a similar search [http://www.mers.com/searchsite.html engine]. Another outstanding source of information along with a sitewide [http://www.efg2.com/Lab/search.htm search] capability is Earl F. Glynn's Computer Lab and Reference [http://www.efg2.com/ Library].<br />
<br />
== Packaging and Releasing your component ==<br />
<br />
=== Creating a Lazarus package for your component(s) ===<br />
<br />
Creating a package makes installing the code you've converted a much easier process... especially if you're providing more then one component. Mattias Gärtner has written an overview of [[Lazarus Packages]] that should be read before beginning this process.<br />
<br />
=== Documentation ===<br />
<br />
The purpose of this site and the wiki format is to make the generation of professional documentation an easy and quick process. The wiki also makes it possible to see the results of your posting immediately and make any changes you'd like in real time.<br />
<br />
Using the Lazarus-CCR wiki to create nice looking documentation is very easy. If you've never used wiki markup before, you can get familiar with it in the [[Sand Box]] practice area.<br />
<br />
=== Creating a Code Release Page ===<br />
<br />
The Code Release Page contains vital information about your component that a potential downloader will need to know, such as license, intended platform, status (alpha, beta, stable...), where to download it, who wrote it, is support available... etc.<br />
<br />
The following procedure will let you create a Code Release Page with your browser: <br />
<br />
* Edit the [[Code And Components]] page and add a project name wiki link entry for your component in the "Released Components" section. Save the modified page.<br />
<br />
* Go to the [[Component Release Template]], select all and copy. Hit the back button on your browser to return to the [[Code And Components]] page.<br />
* Click on your new wiki component name entry and paste the release template into the blank edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your document looks the way you want it to.<br />
<br />
=== Creating a Comment Page for your component ===<br />
<br />
When your component is posted to the Sourceforge File Release System, the Lazarus-CCR admins will lock your code release page to prevent the unlikely event of someone changing your license, name or other release info.<br />
<br />
While you're building your code release page, you have the option to create another wiki link to a "news and comments" page for your component that will always be writable. This is called a ComponentCommentTemplate. The link to it should be added to the bottom of the code release template where there's a topic heading and a brief howto. The wiki name link should be your wiki component name with a Comments suffix like [[EpikTimer Comments]] or [[JpegLazarus Comments]] . The comments page will remain writable to collect feedback from users and for you to post updated information.<br />
<br />
A comment page can be added like this:<br />
<br />
* Edit your component release page and add the wiki comment link (in the format described above). Save the modified page.<br />
* Go to the [[Component Comment Template]] , select all and copy. Hit the back button on your browser to return to your component release page.<br />
* Click on the comment entry entry you created and paste the comment template into the edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your comment page looks the way you want it to.<br />
<br />
While the Lazarus-CCR admins initially lock code release pages, any member of the project can use their shell acount to unlock, edit and re-lock their pages.<br />
<br />
=== Submitting the component ===<br />
<br />
If you're a release technician on the project, upload your component to the SourceForge File Release System and add it to the list of release packages. Otherwise send it to one of the project administrators and we'll add it to the repository. We'll also put it into CVS so you'll continue to have access to it.<br />
<br />
== Contributors and Changes ==<br />
<br />
This page has been converted from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=CodeConversionGuide version].<br />
* Initial version by Tom Lisjac and Mattias Gärtner - 9/22/2003 [[User:Tom | VlxAdmin]]<br />
* Moved Getting help from the main page. T. Lisjac - 9/24/2003 [[User:Tom | VlxAdmin]]<br />
* Added documentation templates, procedure and links. 9/25/2003 [[User:Tom | VlxAdmin]]<br />
* LCLLinux was renamed to LCLIntf, [[User:Jesusrmx | Jesus Reyes]], 9/27/2003<br />
* added more information on Unit changes, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Updated Syntax differences, including some examples, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* FPC 1.0.x doesn't support interfaces, [[User:Vincent | Vincent Snijders]] 9/28/2003<br />
* Fixed some of the examples per new WikiWord definition, 9/28/2003 [[User:Tom | VlxAdmin]]<br />
* Made code more consistant to remove last accidental Pascal WikiWord definitions, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/17/2003<br />
* Use pascal stylesheet to make example code more readable, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/18/2003</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Code_Conversion_Guide&diff=2423Code Conversion Guide2005-08-07T20:10:57Z<p>Wstomv: /* Converting Delphi projects/forms/units to Lazarus */</p>
<hr />
<div>Delphi to Lazarus Code Conversion Guide<br />
<br />
== About ==<br />
<br />
This page is about how to convert existing code to work with the [[Free Pascal]] Compiler and Lazarus IDE. While Lazarus and the Free Pascal Compiler have aspects in common with Delphi and Kylix, they are not clones. There are a number of library call and convention differences... and in some areas, FPC is enhanced and can be more demanding about correct syntax. Please see the [[Lazarus For Delphi Users]] guide for a description of some of the functional differences. <br />
<br />
The purpose of this guide is to document some of the specific differences that are frequently encountered during the code conversion process when translating existing code from Delphi to Lazarus.<br />
<br />
This document was placed into the wiki knowledge-base area so it could be easily extended by anyone who had encountered a unique problem and would like to post it for others to be aware of.<br />
<br />
== Selecting a component or library for conversion ==<br />
<br />
=== Where to find code to convert ===<br />
<br />
There is a LOT of code available on the net that can be converted for use with FPC and Lazarus. Here is a [PageOfCodeSites|] that is just a start. Please add to it if you know of any other good locations. Turbo-Power Software has recently released their entire commercial offering under the MPL. A list of available packages can be found [http://sourceforge.net/users/tpsfadmin/|here].<br />
<br />
To avoid duplicating effort, packages that have already been converted are listed on the [CodeAndComponents|] page. If you've converted a package or are working on one, please add a note on the [CurrentProjects|] page.<br />
<br />
=== Licensing ===<br />
<br />
Licenses for existing code range from freeware/public domain to restrictive versions that prohibit modification, re-distribution and commercial use. Before converting any package, it's a good idea to examine its licensing and make sure it's going to be compatible with Lazarus and the Free Pascal Compiler. License selection is especially important with components since dropping one on a form can impose an unwanted or incompatible license on an entire application.<br />
<br />
When converting components, please respect the wishes of the original author and retain all copyright and licensing headers along with email addresses and url's. It's courteous and often useful to inform the author that their component is being converted... especially if the component is under a restrictive license. New interest in an old or forgotten component can sometimes inspire authors to revise their original and overly restrictive licensing.<br />
<br />
In general, Public Domain (freeware), and the LGPL/MPL are the the most flexible for distributing components. For more information, the [http://www.opensource.org/docs/definition.php Open Source Definition] is a good place to start. There are also several comparisons available to help clarify how the various types of licenses work and what impact they'll have on code they're linked to. Search for "open source license comparison"<br />
<br />
=== Dependencies ===<br />
<br />
Another step before starting to work on a conversion is to verify that the code doesn't have deep dependancies on other packages that might not be available or represent a considerable conversion challenge. Some freeware offerings are bound to or extend proprietary packages that are frequently no longer available or come with inappropriate licenses.<br />
<br />
=== Compiler Issues ===<br />
<br />
Currently the stable 1.0.x version of the Free Pascal Compiler doesn't support interfaces, threads or Variant records. If the code you're converting needs these constructs, you'll have to use the 1.1 development branch of the compiler... which isn't always guaranteed to work with Lazarus.<br />
<br />
=== Platform and OS Issues ===<br />
<br />
Lazarus and the Free Pascal Compiler are cross-platform and cross-architecture development tools. In contrast, most existing Delphi code was specifically designed to run on an Intel processor under Win32. If your candidate component has a lot of Win32 specific code, it might be wise to try and find a less platform dependant alternative. But don't let this stop you... it's genuinely amazing what the LCL supports!<br />
<br />
== Doing the conversion ==<br />
<br />
=== Setting up the Lazarus environment for a conversion project ===<br />
<br />
====Create a test project====<br />
* Place code to be converted into a subdirectory (ie: convertdir)<br />
* Bring up Lazarus<br />
* File->Save All to the convertdir subdirectory. Meaningful names for the Project and default unit are optional.<br />
* Open the "main" unit to be converted in convertdir<br />
* Add it to the project: Project->Add Active Unit to Project<br />
* Run Tools->Quick Syntax Check or Run Build All to get started.<br />
====Initial items to watch out for====<br />
* Filenames are case sensitive with the 1.0.x series compilers. If you're working with this version, make all your filenames lower case. You'll get "File not found" errors if you don't.<br />
====Delphi VCL, Kylix CLX Sources in Lazarus====<br />
<br />
When converting Delphi/Kylix sources, it is often useful to do a find declaration to see, what a specific function is doing. The Lazarus IDE can parse the Delphi/Kylix sources. To do this it needs some searchpaths and compiler settings. You can easily setup this in<br />
Environment->CodeTools Defines Editor->Insert Template<br />
<br />
=== Conversion problems and solutions ===<br />
<br />
==== Delphi / Kylix file equivalents in Lazarus ====<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi / Kylix || class="header" | Lazarus || class="header" | Description<br />
|- class="code"<br />
| class="code" |.pas<br />
.dfm / .xfm<br />
.dcu / .dpu<br />
.dpr<br />
.res<br />
.dof / .kof<br />
---<br />
---<br />
---<br />
| class="code" |.pas, .pp<br />
.lfm<br />
.o<br />
.lpr<br />
---<br />
---<br />
.lrs<br />
.lpi<br />
.ppu<br />
| class="code" |Pascal unit file<br />
Form data file<br />
Compiled unit file<br />
Project file<br />
Resource file<br />
Project options file<br />
Lazarus resource file<br />
Lazarus project information file<br />
FPC unit description file<br />
|}<br />
<br />
==== Converting Delphi projects/forms/units to Lazarus ====<br />
<br />
Rename or copy the .dpr file to a .lpr file. Comment out or remove the <div class="dir">{$R *.res}</div> directive and add a <div class="dir">{$mode delphi}{$H+}</div> or <div class="dir">{$mode objfpc}{$H+}</div> directive to the .lpr file. The Lazarus IDE can assist in this conversion through the Tools menu item "Convert Delphi Project to Lazarus Project". It asks for a .dpr (Delphi Project) file and converts it to .lpr; furthermore, it creates the .lpi file.<br />
<br />
Many existing Delphi forms can be converted to work with Lazarus by using the IDE's built in .dfm to .lfm form converter. It can be found under the Tools menu item as "Convert DFM file to LFM". Bring up the file dialog, select the dfm and the converter will do the rest.<br />
<br />
If you need to convert the whole unit (with or without a form), Lazarus also includes a built in "Convert Delphi unit to Lazarus unit" which will do the following for you -<br />
<br />
# renames the .pas and .dfm file to lowercase.<br />
# converts .dfm file to .lfm file (currently without content check, just format)<br />
# creates an empty .lrs file (the content will be created later)<br />
# adds <div class="dir">{$mode delphi}</div> directive<br />
# replaces windows unit with LCLIntf<br />
# adds LResources unit if needed<br />
# removes variants unit<br />
# removes <div class="dir">{$R *.dfm}</div> directive<br />
# adds initialization section and <div class="dir">{$i unit.lrs}</div> directive<br />
<br />
This allows quick and easy conversion of most units from Delphi format to Lazarus format. It does not do any validity check, or automatic syntax changes, so any syntax changes you need to make, additional unit/unit name changes, or dfm/pas changes for control/component differences you must still do manually, though in time some wizards to help facilitate some of this, especially the repairing of converted forms(lfm), may become available.<br />
<br />
==== Selecting the right compiler mode ====<br />
<br />
The [[Free Pascal]] Compiler supports 5 different pascal modes. For example TP for turbo pascal, lets you compile turbo pascal units. There is also a DELPHI compatibility mode that can be set to make existing code easier to convert. Lazarus prefers the OBJFPC mode, which almost equals the DELPHI mode, but is less ambigious than the Delphi syntax. Here are the important points:<br />
<br />
The mode can be selected at command line or at the start of the source. Using the command line has the advantage, that you don't need to change the source, but the disadvantage, that others must be told.<br />
<br />
Most Delphi units can be compiled by the [[Free Pascal]] compiler by adding <br />
{$IFDEF FPC}<br />
{$MODE DELPHI}<br />
{$ENDIF}<br />
right after the unit name.<br />
<br />
For more details about [[Free Pascal]] modes see the [http://www.freepascal.org/docs-html/prog/progap4.html#progse62.html Free Pascal Documentation]<br />
<br />
==== Cross-Platform considerations ====<br />
<br />
* Inline assembler is always a problem because it will bind the code to the Intel architecture. Some developers do algorithm prototypes in Pascal and ifdef the their optimized assembler. Fortunately Turbo-Power did this in numerous places with their code. If this is the case with the package you're converting, throw the switch back to Pascal.<br />
* Don't reference specific memory location like the BIOS data area. Find out what the code needs and try to find a cross platform alternative.<br />
* Don't do processor specific tricks (like using the Intel TSC) without enclosing your code in an ifdef for the platform the code needs... and providing an alternative for environments that don't have the hardware capability.<br />
* If you need some OS specific code, then you can use IFDEFs. See below for a list of macros.<br />
<br />
==== Useful compiler variables ====<br />
<br />
To write code, that behaves on different systems differently, you can use the <div class="dir">{$IFDEF Name}</div> directives.<br />
<br />
* <div class="dir">{$IfDef LCL}</div><br />
This variable is defined, when using the LCL package. Useful to write code, that works with the LCL and Delphi.<br />
* <div class="dir">{$IfDef FPC}</div><br />
This variable is defined, when using the FPC compiler. Useful to write code, that works with FPC and Delphi.<br />
* <div class="dir">{$IfDef Unix}</div>, <div class="dir">{$IfDef Win32}</div>, ...<br />
Defined by FPC for the current Target OS. Delphi defines "Linux", "Win32" and "MSWindows". [[Free Pascal]] runs on much more platforms and so it is recommended to use the more general items. For example "Unix" is defined for Linux, FreeBSD, NetBSD and OpenBSD, where Lazarus already runs.<br />
Use<br />
{$IfDef Linux}<br />
{$Define Unix}<br />
{$EndIf}<br />
to work around this for Kylix.<br />
<br />
For more details see the [http://www.freepascal.org/docs-html/prog/prog.html#QQ2-23-21 Free Pascal Documentation].<br />
<br />
==== Finding a missing identifier ====<br />
<br />
There are differences in how the LCL is organized when compared to the Delphi VCL. If you get a "not found" compiler error about a major class or identifier, the chances are good that it's in a different unit. A complete cross reference can be found by grep'ing lazarus/docs/xml or the lcl subdirectory.<br />
<br />
For example the commonly used tbutton typically throws an error in Delphi code because it's located in a unit named buttons.pp. The following command finds the correct unit very quickly (in the lazarus source directory):<br />
<br />
grep -in ' tbutton =' lcl/*<br />
<br />
<br />
==== Major unit differences between Lazarus and Delphi ====<br />
<br />
** Please add to this topic! **<br />
<br />
* Windows->LCLIntf, LCLType, LCLProc, VCLGlobals, ...)<br />
<br />
As the LCL is not windows specific, the code that is in the Delphi Windows unit for directly accessing the Win32 API is abstracted into seperate interfaces, which can be accessed from the LCLIntf unit. Keep in mind, that Lazarus does not emulate win32, so many functions are missing and some do not work as their win32 counterparts. These functions only exist for Delphi compatibility and should only be used for quick & dirty porting. LCL also breaks out many of the types, so often LCLType, and sometimes VCLGlobals are required. LCLProc also contains a few functions which can be usefull for lower level handling such as "FreeThenNil" as is in Delphi 5 and higher, "DeleteAmpersands" to remove additional ampersands from a string for controls(& vs && etc).<br />
<br />
* Messages->LMessages<br />
<br />
TControl Messages for win32 event callbacks of the format WM_CALLBACK and the structs associated with them are often found in the Messages unit in Delphi. In the LCL these types of messages and there structs are usually found in LMessages, usually with name changes of WM to LM, so for instance WM_MOUSEENTER becomes LM_MOUSEENTER, and TWMMouse becomes TLMMouse.<br />
<br />
* Graphics, Controls->GraphTypes, GraphMath, Graphics, Controls<br />
<br />
To simplify some things and break complexity of circles between units, a few types have been abstracted into a shared unit called GraphType, which includes things, which in Delphi are located in Graphics or Controls, for instance the bvNone etc of panels. So sometimes you have to include it. Also a unit which, although incompatible with Delphi, adds other usefull functionality is GraphMath, which adds a TFloatPoint for precision, misc routines for dealing with beziers, lines, and arcs, as well as some operator overloading for use with TPoints and TRect, such as for instance Point1 := Point2 + Point3, and comparing two rects like if (rect1 = rect2) then ...<br />
<br />
* Mask->MaskEdit<br />
<br />
For more intelligent naming considerations, the unit for TMaskEdit is called [MaskEdit|] instead of the slightly more nebulous Mask as in many versions of Delphi.<br />
<br />
* StdCtrls->StdCtrls,Buttons<br />
<br />
In many version of Delphi TButton is located in StdCtrls, while TSpeedButton and TBitBtn are in Buttons. For consistency and simplicity the LCL puts all button types in Buttons, which can occasionally break code conversion, so it is always a good idea to include.<br />
<br />
<br />
==== Property and method differences Delphi -> FPC/LCL ====<br />
* TBitmap contains a canvas in the LCL<br />
==== Syntax differences ====<br />
<br />
'''Please add to this topic!'''<br />
<br />
Because of the inherent strictness in FPC, some syntax changes are necessary, even though !!;dir {$Mode Delphi}!!;! does allow more lazyness like Delphi does. For this reason complying as much with the syntax rules of !!;dir {$Mode ObjFPC}!!;! as possible is highly recommended, even when the codebase is still going to be shared between Delphi and the LCL. Some of these are simply better coding practises, and sometimes because occasionally Delphi mode is not entirely accurate, or in a few instances Delphi acceptible code does not function as expected with FPC, even though it might compile. To that end even though not all such are strictly required, the following list of changes should be considered mandatory :<br />
<br />
;Variables initialization in FPC 1.0.x<br />
<br />
With Delphi it is possible (and quite common) to initialize a variable in its declaration, however this is not possible in FPC 1.0.x, const must be used instead, or prefereably in many situations, initialized elsewhere at some point before the variable is used (like unit initialization). <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">var</div><br />
MyObject: TSomeObject= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
| class="code" | <div class="key">var</div><br />
MyObject<div class="symbol">:</div> TSomeObject;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
MyObject:= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
;When assigning an event handling entry point, prefix it with an "@"<br />
<br />
For instance, you might assign a button callback manually <br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">begin</div> <br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= SomeFunction; <div class="cmt">//@ not required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">begin</div><br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= @SomeFunction; <div class="cmt">//@ IS required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When calling a procedure variable use this syntax: theprocname()<br />
<br />
In Delphi there is no difference between a procedure and a procedure variable, however there is in FPC, so to call a procedure, even if it has no paramaters, you must append parenthesis. For Example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div> <br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div> <br />
OnMyCallback; <div class="cmt">//parenthesis not required</div> <br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div><br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div><br />
OnMyCallback(); <div class="cmt">//parenthesis required</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When accessing values in a pointer to a record you must dereference first<br />
<br />
In Delphi it is not required to dereference a pointer to a record to acces values within it, it can in fact be treated just like the record itself, or any other object. In FPC it must be first dereferenced. As an example,<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord^.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>; <br />
|}<br />
<br />
;When accessing chars of an indexed string Property of an object, it must be enclosed in parenthesis<br />
<br />
With Delphi it is possible to treat a Property exactly like some other const or var, even to accessing for instance individual chars of a string directly, while this is not always possible in FPC, specifically for indexed properties. Instead it must be enclosed in parenthesis, to make distinct. While this may not always hold true it is probably a good practice to consider anyway. For example<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//no parenthesis needed</div><br />
MyChar:= MyString[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//parenthesis sometimes needed</div><br />
MyChar:= (MyString)[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
<br />
;You must typecast pointers to actual type when using with var or function of that type<br />
<br />
Sometimes in Delphi you will have a null pointer variable representing an object. While it might seem a complex situation, it is oddly quite common especially in large component packs as a method of preventing too many circular includes between objects in different units. In Delphi it is then possible to send this null pointer to a function expecting that object, without bothering to typecast to actual type, in fpc you must typecast. <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div><br />
<div class="symbol">Application</div><br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> GetSomeObject;<br />
<div class="cmt">//More code...</div><br />
DoSomething(MyComponent.SomeObject)<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="symbol">Application</div> <br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> Pointer(GetSomeObject);<br />
<div class="cmt">//More code...</div><br />
DoSomething(TSomeObject(MyComponent.SomeObject))<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Resources ====<br />
<br />
Delphi resource files are win32 specific and not compatible with Lazarus, so you'll have to recreate and compile them using the lazres. Lazres can be found in the lazarus/tools subdirectory. If you've downloaded the Lazarus sources, you'll need to compile it first.<br />
* cd lazarus/tools<br />
* make install<br />
To add a resource to your application:<br />
* lazres myresource.lrs mypix.xpm anotherpix.xpm<br />
* Add the LResources unit to your Uses clause<br />
* Include the .lrs file you created under the initialization block<br />
Example:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> TForm1.LoadGlyph(<div class="key">const</div> GlyphName: <div class="key">String</div>): TBitMap;<br />
<div class="key">begin</div><br />
Result:= TPixmap.Create<div class="symbol">;</div><br />
Result.LoadFromLazarusResource(GlyphName)<div class="symbol">;</div><br />
<div class="key">end</div>; <br />
<div class="cmt">//More code...</div><br />
<div class="key">begin</div><br />
Speedbutton1.glyph:= LoadGlyph('mypix')<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
<div></div> <br />
<div class="key">initialization</div><br />
<div class="dir">{$I unit1.lrs}</div><br />
<div class="dir">{$I myresource.lrs}</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
== Getting Help ==<br />
<br />
If you encounter a problem during conversion that you just can't solve, there are a wide variety of places to get help. For pure Object Pascal and FPC issues, the best place to start is the Free Pascal [http://www.freepascal.org/docs-html/ Documentation] by Michaël Van Canneyt and Florian Klämpfl. For more Lazarus oriented problems, the Lazarus Project Documentation in the Lazarus-CCR Knowledgebase [Main Page] is the next place to look. Finally you can post a question on any of the [http://www.freepascal.org/maillist.html mailing lists for the Free Pascal Compiler] or the [http://community.freepascal.org:10000/bboard/ FPC forums] where a lot of experts are subscribed.<br />
<br />
There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems. Tamarack Associates operates a fast [http://www.tamaracka.com/search.htm search] engine specifically for the Borland usenet archives. Mer Systems Inc. provides a similar search [http://www.mers.com/searchsite.html engine]. Another outstanding source of information along with a sitewide [http://www.efg2.com/Lab/search.htm search] capability is Earl F. Glynn's Computer Lab and Reference [http://www.efg2.com/ Library].<br />
<br />
== Packaging and Releasing your component ==<br />
<br />
=== Creating a Lazarus package for your component(s) ===<br />
<br />
Creating a package makes installing the code you've converted a much easier process... especially if you're providing more then one component. Mattias Gärtner has written an overview of [[Lazarus Packages]] that should be read before beginning this process.<br />
<br />
=== Documentation ===<br />
<br />
The purpose of this site and the wiki format is to make the generation of professional documentation an easy and quick process. The wiki also makes it possible to see the results of your posting immediately and make any changes you'd like in real time.<br />
<br />
Using the Lazarus-CCR wiki to create nice looking documentation is very easy. If you've never used wiki markup before, you can get familiar with it in the [[Sand Box]] practice area.<br />
<br />
=== Creating a Code Release Page ===<br />
<br />
The Code Release Page contains vital information about your component that a potential downloader will need to know, such as license, intended platform, status (alpha, beta, stable...), where to download it, who wrote it, is support available... etc.<br />
<br />
The following procedure will let you create a Code Release Page with your browser: <br />
<br />
* Edit the [[Code And Components]] page and add a project name wiki link entry for your component in the "Released Components" section. Save the modified page.<br />
<br />
* Go to the [[Component Release Template]], select all and copy. Hit the back button on your browser to return to the [[Code And Components]] page.<br />
* Click on your new wiki component name entry and paste the release template into the blank edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your document looks the way you want it to.<br />
<br />
=== Creating a Comment Page for your component ===<br />
<br />
When your component is posted to the Sourceforge File Release System, the Lazarus-CCR admins will lock your code release page to prevent the unlikely event of someone changing your license, name or other release info.<br />
<br />
While you're building your code release page, you have the option to create another wiki link to a "news and comments" page for your component that will always be writable. This is called a ComponentCommentTemplate. The link to it should be added to the bottom of the code release template where there's a topic heading and a brief howto. The wiki name link should be your wiki component name with a Comments suffix like [[EpikTimer Comments]] or [[JpegLazarus Comments]] . The comments page will remain writable to collect feedback from users and for you to post updated information.<br />
<br />
A comment page can be added like this:<br />
<br />
* Edit your component release page and add the wiki comment link (in the format described above). Save the modified page.<br />
* Go to the [[Component Comment Template]] , select all and copy. Hit the back button on your browser to return to your component release page.<br />
* Click on the comment entry entry you created and paste the comment template into the edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your comment page looks the way you want it to.<br />
<br />
While the Lazarus-CCR admins initially lock code release pages, any member of the project can use their shell acount to unlock, edit and re-lock their pages.<br />
<br />
=== Submitting the component ===<br />
<br />
If you're a release technician on the project, upload your component to the SourceForge File Release System and add it to the list of release packages. Otherwise send it to one of the project administrators and we'll add it to the repository. We'll also put it into CVS so you'll continue to have access to it.<br />
<br />
== Contributors and Changes ==<br />
<br />
This page has been converted from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=CodeConversionGuide version].<br />
* Initial version by Tom Lisjac and Mattias Gärtner - 9/22/2003 [[User:Tom | VlxAdmin]]<br />
* Moved Getting help from the main page. T. Lisjac - 9/24/2003 [[User:Tom | VlxAdmin]]<br />
* Added documentation templates, procedure and links. 9/25/2003 [[User:Tom | VlxAdmin]]<br />
* LCLLinux was renamed to LCLIntf, [[User:Jesusrmx | Jesus Reyes]], 9/27/2003<br />
* added more information on Unit changes, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Updated Syntax differences, including some examples, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* FPC 1.0.x doesn't support interfaces, [[User:Vincent | Vincent Snijders]] 9/28/2003<br />
* Fixed some of the examples per new WikiWord definition, 9/28/2003 [[User:Tom | VlxAdmin]]<br />
* Made code more consistant to remove last accidental Pascal WikiWord definitions, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/17/2003<br />
* Use pascal stylesheet to make example code more readable, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/18/2003</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Code_Conversion_Guide&diff=2422Code Conversion Guide2005-08-07T19:33:49Z<p>Wstomv: /* Cross-Platform considerations */</p>
<hr />
<div>Delphi to Lazarus Code Conversion Guide<br />
<br />
== About ==<br />
<br />
This page is about how to convert existing code to work with the [[Free Pascal]] Compiler and Lazarus IDE. While Lazarus and the Free Pascal Compiler have aspects in common with Delphi and Kylix, they are not clones. There are a number of library call and convention differences... and in some areas, FPC is enhanced and can be more demanding about correct syntax. Please see the [[Lazarus For Delphi Users]] guide for a description of some of the functional differences. <br />
<br />
The purpose of this guide is to document some of the specific differences that are frequently encountered during the code conversion process when translating existing code from Delphi to Lazarus.<br />
<br />
This document was placed into the wiki knowledge-base area so it could be easily extended by anyone who had encountered a unique problem and would like to post it for others to be aware of.<br />
<br />
== Selecting a component or library for conversion ==<br />
<br />
=== Where to find code to convert ===<br />
<br />
There is a LOT of code available on the net that can be converted for use with FPC and Lazarus. Here is a [PageOfCodeSites|] that is just a start. Please add to it if you know of any other good locations. Turbo-Power Software has recently released their entire commercial offering under the MPL. A list of available packages can be found [http://sourceforge.net/users/tpsfadmin/|here].<br />
<br />
To avoid duplicating effort, packages that have already been converted are listed on the [CodeAndComponents|] page. If you've converted a package or are working on one, please add a note on the [CurrentProjects|] page.<br />
<br />
=== Licensing ===<br />
<br />
Licenses for existing code range from freeware/public domain to restrictive versions that prohibit modification, re-distribution and commercial use. Before converting any package, it's a good idea to examine its licensing and make sure it's going to be compatible with Lazarus and the Free Pascal Compiler. License selection is especially important with components since dropping one on a form can impose an unwanted or incompatible license on an entire application.<br />
<br />
When converting components, please respect the wishes of the original author and retain all copyright and licensing headers along with email addresses and url's. It's courteous and often useful to inform the author that their component is being converted... especially if the component is under a restrictive license. New interest in an old or forgotten component can sometimes inspire authors to revise their original and overly restrictive licensing.<br />
<br />
In general, Public Domain (freeware), and the LGPL/MPL are the the most flexible for distributing components. For more information, the [http://www.opensource.org/docs/definition.php Open Source Definition] is a good place to start. There are also several comparisons available to help clarify how the various types of licenses work and what impact they'll have on code they're linked to. Search for "open source license comparison"<br />
<br />
=== Dependencies ===<br />
<br />
Another step before starting to work on a conversion is to verify that the code doesn't have deep dependancies on other packages that might not be available or represent a considerable conversion challenge. Some freeware offerings are bound to or extend proprietary packages that are frequently no longer available or come with inappropriate licenses.<br />
<br />
=== Compiler Issues ===<br />
<br />
Currently the stable 1.0.x version of the Free Pascal Compiler doesn't support interfaces, threads or Variant records. If the code you're converting needs these constructs, you'll have to use the 1.1 development branch of the compiler... which isn't always guaranteed to work with Lazarus.<br />
<br />
=== Platform and OS Issues ===<br />
<br />
Lazarus and the Free Pascal Compiler are cross-platform and cross-architecture development tools. In contrast, most existing Delphi code was specifically designed to run on an Intel processor under Win32. If your candidate component has a lot of Win32 specific code, it might be wise to try and find a less platform dependant alternative. But don't let this stop you... it's genuinely amazing what the LCL supports!<br />
<br />
== Doing the conversion ==<br />
<br />
=== Setting up the Lazarus environment for a conversion project ===<br />
<br />
====Create a test project====<br />
* Place code to be converted into a subdirectory (ie: convertdir)<br />
* Bring up Lazarus<br />
* File->Save All to the convertdir subdirectory. Meaningful names for the Project and default unit are optional.<br />
* Open the "main" unit to be converted in convertdir<br />
* Add it to the project: Project->Add Active Unit to Project<br />
* Run Tools->Quick Syntax Check or Run Build All to get started.<br />
====Initial items to watch out for====<br />
* Filenames are case sensitive with the 1.0.x series compilers. If you're working with this version, make all your filenames lower case. You'll get "File not found" errors if you don't.<br />
====Delphi VCL, Kylix CLX Sources in Lazarus====<br />
<br />
When converting Delphi/Kylix sources, it is often useful to do a find declaration to see, what a specific function is doing. The Lazarus IDE can parse the Delphi/Kylix sources. To do this it needs some searchpaths and compiler settings. You can easily setup this in<br />
Environment->CodeTools Defines Editor->Insert Template<br />
<br />
=== Conversion problems and solutions ===<br />
<br />
==== Delphi / Kylix file equivalents in Lazarus ====<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi / Kylix || class="header" | Lazarus || class="header" | Description<br />
|- class="code"<br />
| class="code" |.pas<br />
.dfm / .xfm<br />
.dcu / .dpu<br />
.dpr<br />
.res<br />
.dof / .kof<br />
---<br />
---<br />
---<br />
| class="code" |.pas, .pp<br />
.lfm<br />
.o<br />
.lpr<br />
---<br />
---<br />
.lrs<br />
.lpi<br />
.ppu<br />
| class="code" |Pascal unit file<br />
Form data file<br />
Compiled unit file<br />
Project file<br />
Resource file<br />
Project options file<br />
Lazarus resource file<br />
Lazarus project information file<br />
FPC unit description file<br />
|}<br />
<br />
==== Converting Delphi projects/forms/units to Lazarus ====<br />
<br />
Rename or copy the .dpr file to a .lpr file. Comment out or remove the <div class="dir">{$R *.res}</div> directive and add a <div class="dir">{$mode delphi}{$H+}</div> or <div class="dir">{$mode objfpc}{$H+}</div> directive to the .lpr file. Many existing Delphi forms can be converted to work with Lazarus by using the IDE's built in .dfm to .lfm form converter. It can be found under the Tools menu item as "Convert DFM file to LFM". Bring up the file dialog, select the dfm and the converter will do the rest.<br />
<br />
If you need to convert the whole unit (with or without a form), Lazarus also includes a built in "Convert Delphi unit to Lazarus unit" which will do the following for you -<br />
<br />
# renames the .pas and .dfm file to lowercase.<br />
# converts .dfm file to .lfm file (currently without content check, just format)<br />
# creates an empty .lrs file (the content will be created later)<br />
# adds <div class="dir">{$mode delphi}</div> directive<br />
# replaces windows unit with LCLIntf<br />
# adds LResources unit if needed<br />
# removes variants unit<br />
# removes <div class="dir">{$R *.dfm}</div> directive<br />
# adds initialization section and <div class="dir">{$i unit.lrs}</div> directive<br />
<br />
This allows quick and easy conversion of most units from Delphi format to Lazarus format. It does not do any validity check, or automatic syntax changes, so any syntax changes you need to make, additional unit/unit name changes, or dfm/pas changes for control/component differences you must still do manually, though in time some wizards to help facilitate some of this, especially the repairing of converted forms(lfm), may become available.<br />
<br />
==== Selecting the right compiler mode ====<br />
<br />
The [[Free Pascal]] Compiler supports 5 different pascal modes. For example TP for turbo pascal, lets you compile turbo pascal units. There is also a DELPHI compatibility mode that can be set to make existing code easier to convert. Lazarus prefers the OBJFPC mode, which almost equals the DELPHI mode, but is less ambigious than the Delphi syntax. Here are the important points:<br />
<br />
The mode can be selected at command line or at the start of the source. Using the command line has the advantage, that you don't need to change the source, but the disadvantage, that others must be told.<br />
<br />
Most Delphi units can be compiled by the [[Free Pascal]] compiler by adding <br />
{$IFDEF FPC}<br />
{$MODE DELPHI}<br />
{$ENDIF}<br />
right after the unit name.<br />
<br />
For more details about [[Free Pascal]] modes see the [http://www.freepascal.org/docs-html/prog/progap4.html#progse62.html Free Pascal Documentation]<br />
<br />
==== Cross-Platform considerations ====<br />
<br />
* Inline assembler is always a problem because it will bind the code to the Intel architecture. Some developers do algorithm prototypes in Pascal and ifdef the their optimized assembler. Fortunately Turbo-Power did this in numerous places with their code. If this is the case with the package you're converting, throw the switch back to Pascal.<br />
* Don't reference specific memory location like the BIOS data area. Find out what the code needs and try to find a cross platform alternative.<br />
* Don't do processor specific tricks (like using the Intel TSC) without enclosing your code in an ifdef for the platform the code needs... and providing an alternative for environments that don't have the hardware capability.<br />
* If you need some OS specific code, then you can use IFDEFs. See below for a list of macros.<br />
<br />
==== Useful compiler variables ====<br />
<br />
To write code, that behaves on different systems differently, you can use the <div class="dir">{$IFDEF Name}</div> directives.<br />
<br />
* <div class="dir">{$IfDef LCL}</div><br />
This variable is defined, when using the LCL package. Useful to write code, that works with the LCL and Delphi.<br />
* <div class="dir">{$IfDef FPC}</div><br />
This variable is defined, when using the FPC compiler. Useful to write code, that works with FPC and Delphi.<br />
* <div class="dir">{$IfDef Unix}</div>, <div class="dir">{$IfDef Win32}</div>, ...<br />
Defined by FPC for the current Target OS. Delphi defines "Linux", "Win32" and "MSWindows". [[Free Pascal]] runs on much more platforms and so it is recommended to use the more general items. For example "Unix" is defined for Linux, FreeBSD, NetBSD and OpenBSD, where Lazarus already runs.<br />
Use<br />
{$IfDef Linux}<br />
{$Define Unix}<br />
{$EndIf}<br />
to work around this for Kylix.<br />
<br />
For more details see the [http://www.freepascal.org/docs-html/prog/prog.html#QQ2-23-21 Free Pascal Documentation].<br />
<br />
==== Finding a missing identifier ====<br />
<br />
There are differences in how the LCL is organized when compared to the Delphi VCL. If you get a "not found" compiler error about a major class or identifier, the chances are good that it's in a different unit. A complete cross reference can be found by grep'ing lazarus/docs/xml or the lcl subdirectory.<br />
<br />
For example the commonly used tbutton typically throws an error in Delphi code because it's located in a unit named buttons.pp. The following command finds the correct unit very quickly (in the lazarus source directory):<br />
<br />
grep -in ' tbutton =' lcl/*<br />
<br />
<br />
==== Major unit differences between Lazarus and Delphi ====<br />
<br />
** Please add to this topic! **<br />
<br />
* Windows->LCLIntf, LCLType, LCLProc, VCLGlobals, ...)<br />
<br />
As the LCL is not windows specific, the code that is in the Delphi Windows unit for directly accessing the Win32 API is abstracted into seperate interfaces, which can be accessed from the LCLIntf unit. Keep in mind, that Lazarus does not emulate win32, so many functions are missing and some do not work as their win32 counterparts. These functions only exist for Delphi compatibility and should only be used for quick & dirty porting. LCL also breaks out many of the types, so often LCLType, and sometimes VCLGlobals are required. LCLProc also contains a few functions which can be usefull for lower level handling such as "FreeThenNil" as is in Delphi 5 and higher, "DeleteAmpersands" to remove additional ampersands from a string for controls(& vs && etc).<br />
<br />
* Messages->LMessages<br />
<br />
TControl Messages for win32 event callbacks of the format WM_CALLBACK and the structs associated with them are often found in the Messages unit in Delphi. In the LCL these types of messages and there structs are usually found in LMessages, usually with name changes of WM to LM, so for instance WM_MOUSEENTER becomes LM_MOUSEENTER, and TWMMouse becomes TLMMouse.<br />
<br />
* Graphics, Controls->GraphTypes, GraphMath, Graphics, Controls<br />
<br />
To simplify some things and break complexity of circles between units, a few types have been abstracted into a shared unit called GraphType, which includes things, which in Delphi are located in Graphics or Controls, for instance the bvNone etc of panels. So sometimes you have to include it. Also a unit which, although incompatible with Delphi, adds other usefull functionality is GraphMath, which adds a TFloatPoint for precision, misc routines for dealing with beziers, lines, and arcs, as well as some operator overloading for use with TPoints and TRect, such as for instance Point1 := Point2 + Point3, and comparing two rects like if (rect1 = rect2) then ...<br />
<br />
* Mask->MaskEdit<br />
<br />
For more intelligent naming considerations, the unit for TMaskEdit is called [MaskEdit|] instead of the slightly more nebulous Mask as in many versions of Delphi.<br />
<br />
* StdCtrls->StdCtrls,Buttons<br />
<br />
In many version of Delphi TButton is located in StdCtrls, while TSpeedButton and TBitBtn are in Buttons. For consistency and simplicity the LCL puts all button types in Buttons, which can occasionally break code conversion, so it is always a good idea to include.<br />
<br />
<br />
==== Property and method differences Delphi -> FPC/LCL ====<br />
* TBitmap contains a canvas in the LCL<br />
==== Syntax differences ====<br />
<br />
'''Please add to this topic!'''<br />
<br />
Because of the inherent strictness in FPC, some syntax changes are necessary, even though !!;dir {$Mode Delphi}!!;! does allow more lazyness like Delphi does. For this reason complying as much with the syntax rules of !!;dir {$Mode ObjFPC}!!;! as possible is highly recommended, even when the codebase is still going to be shared between Delphi and the LCL. Some of these are simply better coding practises, and sometimes because occasionally Delphi mode is not entirely accurate, or in a few instances Delphi acceptible code does not function as expected with FPC, even though it might compile. To that end even though not all such are strictly required, the following list of changes should be considered mandatory :<br />
<br />
;Variables initialization in FPC 1.0.x<br />
<br />
With Delphi it is possible (and quite common) to initialize a variable in its declaration, however this is not possible in FPC 1.0.x, const must be used instead, or prefereably in many situations, initialized elsewhere at some point before the variable is used (like unit initialization). <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">var</div><br />
MyObject: TSomeObject= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
| class="code" | <div class="key">var</div><br />
MyObject<div class="symbol">:</div> TSomeObject;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
MyObject:= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
;When assigning an event handling entry point, prefix it with an "@"<br />
<br />
For instance, you might assign a button callback manually <br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">begin</div> <br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= SomeFunction; <div class="cmt">//@ not required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">begin</div><br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= @SomeFunction; <div class="cmt">//@ IS required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When calling a procedure variable use this syntax: theprocname()<br />
<br />
In Delphi there is no difference between a procedure and a procedure variable, however there is in FPC, so to call a procedure, even if it has no paramaters, you must append parenthesis. For Example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div> <br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div> <br />
OnMyCallback; <div class="cmt">//parenthesis not required</div> <br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div><br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div><br />
OnMyCallback(); <div class="cmt">//parenthesis required</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When accessing values in a pointer to a record you must dereference first<br />
<br />
In Delphi it is not required to dereference a pointer to a record to acces values within it, it can in fact be treated just like the record itself, or any other object. In FPC it must be first dereferenced. As an example,<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord^.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>; <br />
|}<br />
<br />
;When accessing chars of an indexed string Property of an object, it must be enclosed in parenthesis<br />
<br />
With Delphi it is possible to treat a Property exactly like some other const or var, even to accessing for instance individual chars of a string directly, while this is not always possible in FPC, specifically for indexed properties. Instead it must be enclosed in parenthesis, to make distinct. While this may not always hold true it is probably a good practice to consider anyway. For example<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//no parenthesis needed</div><br />
MyChar:= MyString[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//parenthesis sometimes needed</div><br />
MyChar:= (MyString)[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
<br />
;You must typecast pointers to actual type when using with var or function of that type<br />
<br />
Sometimes in Delphi you will have a null pointer variable representing an object. While it might seem a complex situation, it is oddly quite common especially in large component packs as a method of preventing too many circular includes between objects in different units. In Delphi it is then possible to send this null pointer to a function expecting that object, without bothering to typecast to actual type, in fpc you must typecast. <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div><br />
<div class="symbol">Application</div><br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> GetSomeObject;<br />
<div class="cmt">//More code...</div><br />
DoSomething(MyComponent.SomeObject)<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="symbol">Application</div> <br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> Pointer(GetSomeObject);<br />
<div class="cmt">//More code...</div><br />
DoSomething(TSomeObject(MyComponent.SomeObject))<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Resources ====<br />
<br />
Delphi resource files are win32 specific and not compatible with Lazarus, so you'll have to recreate and compile them using the lazres. Lazres can be found in the lazarus/tools subdirectory. If you've downloaded the Lazarus sources, you'll need to compile it first.<br />
* cd lazarus/tools<br />
* make install<br />
To add a resource to your application:<br />
* lazres myresource.lrs mypix.xpm anotherpix.xpm<br />
* Add the LResources unit to your Uses clause<br />
* Include the .lrs file you created under the initialization block<br />
Example:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> TForm1.LoadGlyph(<div class="key">const</div> GlyphName: <div class="key">String</div>): TBitMap;<br />
<div class="key">begin</div><br />
Result:= TPixmap.Create<div class="symbol">;</div><br />
Result.LoadFromLazarusResource(GlyphName)<div class="symbol">;</div><br />
<div class="key">end</div>; <br />
<div class="cmt">//More code...</div><br />
<div class="key">begin</div><br />
Speedbutton1.glyph:= LoadGlyph('mypix')<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
<div></div> <br />
<div class="key">initialization</div><br />
<div class="dir">{$I unit1.lrs}</div><br />
<div class="dir">{$I myresource.lrs}</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
== Getting Help ==<br />
<br />
If you encounter a problem during conversion that you just can't solve, there are a wide variety of places to get help. For pure Object Pascal and FPC issues, the best place to start is the Free Pascal [http://www.freepascal.org/docs-html/ Documentation] by Michaël Van Canneyt and Florian Klämpfl. For more Lazarus oriented problems, the Lazarus Project Documentation in the Lazarus-CCR Knowledgebase [Main Page] is the next place to look. Finally you can post a question on any of the [http://www.freepascal.org/maillist.html mailing lists for the Free Pascal Compiler] or the [http://community.freepascal.org:10000/bboard/ FPC forums] where a lot of experts are subscribed.<br />
<br />
There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems. Tamarack Associates operates a fast [http://www.tamaracka.com/search.htm search] engine specifically for the Borland usenet archives. Mer Systems Inc. provides a similar search [http://www.mers.com/searchsite.html engine]. Another outstanding source of information along with a sitewide [http://www.efg2.com/Lab/search.htm search] capability is Earl F. Glynn's Computer Lab and Reference [http://www.efg2.com/ Library].<br />
<br />
== Packaging and Releasing your component ==<br />
<br />
=== Creating a Lazarus package for your component(s) ===<br />
<br />
Creating a package makes installing the code you've converted a much easier process... especially if you're providing more then one component. Mattias Gärtner has written an overview of [[Lazarus Packages]] that should be read before beginning this process.<br />
<br />
=== Documentation ===<br />
<br />
The purpose of this site and the wiki format is to make the generation of professional documentation an easy and quick process. The wiki also makes it possible to see the results of your posting immediately and make any changes you'd like in real time.<br />
<br />
Using the Lazarus-CCR wiki to create nice looking documentation is very easy. If you've never used wiki markup before, you can get familiar with it in the [[Sand Box]] practice area.<br />
<br />
=== Creating a Code Release Page ===<br />
<br />
The Code Release Page contains vital information about your component that a potential downloader will need to know, such as license, intended platform, status (alpha, beta, stable...), where to download it, who wrote it, is support available... etc.<br />
<br />
The following procedure will let you create a Code Release Page with your browser: <br />
<br />
* Edit the [[Code And Components]] page and add a project name wiki link entry for your component in the "Released Components" section. Save the modified page.<br />
<br />
* Go to the [[Component Release Template]], select all and copy. Hit the back button on your browser to return to the [[Code And Components]] page.<br />
* Click on your new wiki component name entry and paste the release template into the blank edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your document looks the way you want it to.<br />
<br />
=== Creating a Comment Page for your component ===<br />
<br />
When your component is posted to the Sourceforge File Release System, the Lazarus-CCR admins will lock your code release page to prevent the unlikely event of someone changing your license, name or other release info.<br />
<br />
While you're building your code release page, you have the option to create another wiki link to a "news and comments" page for your component that will always be writable. This is called a ComponentCommentTemplate. The link to it should be added to the bottom of the code release template where there's a topic heading and a brief howto. The wiki name link should be your wiki component name with a Comments suffix like [[EpikTimer Comments]] or [[JpegLazarus Comments]] . The comments page will remain writable to collect feedback from users and for you to post updated information.<br />
<br />
A comment page can be added like this:<br />
<br />
* Edit your component release page and add the wiki comment link (in the format described above). Save the modified page.<br />
* Go to the [[Component Comment Template]] , select all and copy. Hit the back button on your browser to return to your component release page.<br />
* Click on the comment entry entry you created and paste the comment template into the edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your comment page looks the way you want it to.<br />
<br />
While the Lazarus-CCR admins initially lock code release pages, any member of the project can use their shell acount to unlock, edit and re-lock their pages.<br />
<br />
=== Submitting the component ===<br />
<br />
If you're a release technician on the project, upload your component to the SourceForge File Release System and add it to the list of release packages. Otherwise send it to one of the project administrators and we'll add it to the repository. We'll also put it into CVS so you'll continue to have access to it.<br />
<br />
== Contributors and Changes ==<br />
<br />
This page has been converted from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=CodeConversionGuide version].<br />
* Initial version by Tom Lisjac and Mattias Gärtner - 9/22/2003 [[User:Tom | VlxAdmin]]<br />
* Moved Getting help from the main page. T. Lisjac - 9/24/2003 [[User:Tom | VlxAdmin]]<br />
* Added documentation templates, procedure and links. 9/25/2003 [[User:Tom | VlxAdmin]]<br />
* LCLLinux was renamed to LCLIntf, [[User:Jesusrmx | Jesus Reyes]], 9/27/2003<br />
* added more information on Unit changes, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Updated Syntax differences, including some examples, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* FPC 1.0.x doesn't support interfaces, [[User:Vincent | Vincent Snijders]] 9/28/2003<br />
* Fixed some of the examples per new WikiWord definition, 9/28/2003 [[User:Tom | VlxAdmin]]<br />
* Made code more consistant to remove last accidental Pascal WikiWord definitions, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/17/2003<br />
* Use pascal stylesheet to make example code more readable, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/18/2003</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Code_Conversion_Guide&diff=2421Code Conversion Guide2005-08-07T19:29:27Z<p>Wstomv: /* Selecting the right compiler mode */</p>
<hr />
<div>Delphi to Lazarus Code Conversion Guide<br />
<br />
== About ==<br />
<br />
This page is about how to convert existing code to work with the [[Free Pascal]] Compiler and Lazarus IDE. While Lazarus and the Free Pascal Compiler have aspects in common with Delphi and Kylix, they are not clones. There are a number of library call and convention differences... and in some areas, FPC is enhanced and can be more demanding about correct syntax. Please see the [[Lazarus For Delphi Users]] guide for a description of some of the functional differences. <br />
<br />
The purpose of this guide is to document some of the specific differences that are frequently encountered during the code conversion process when translating existing code from Delphi to Lazarus.<br />
<br />
This document was placed into the wiki knowledge-base area so it could be easily extended by anyone who had encountered a unique problem and would like to post it for others to be aware of.<br />
<br />
== Selecting a component or library for conversion ==<br />
<br />
=== Where to find code to convert ===<br />
<br />
There is a LOT of code available on the net that can be converted for use with FPC and Lazarus. Here is a [PageOfCodeSites|] that is just a start. Please add to it if you know of any other good locations. Turbo-Power Software has recently released their entire commercial offering under the MPL. A list of available packages can be found [http://sourceforge.net/users/tpsfadmin/|here].<br />
<br />
To avoid duplicating effort, packages that have already been converted are listed on the [CodeAndComponents|] page. If you've converted a package or are working on one, please add a note on the [CurrentProjects|] page.<br />
<br />
=== Licensing ===<br />
<br />
Licenses for existing code range from freeware/public domain to restrictive versions that prohibit modification, re-distribution and commercial use. Before converting any package, it's a good idea to examine its licensing and make sure it's going to be compatible with Lazarus and the Free Pascal Compiler. License selection is especially important with components since dropping one on a form can impose an unwanted or incompatible license on an entire application.<br />
<br />
When converting components, please respect the wishes of the original author and retain all copyright and licensing headers along with email addresses and url's. It's courteous and often useful to inform the author that their component is being converted... especially if the component is under a restrictive license. New interest in an old or forgotten component can sometimes inspire authors to revise their original and overly restrictive licensing.<br />
<br />
In general, Public Domain (freeware), and the LGPL/MPL are the the most flexible for distributing components. For more information, the [http://www.opensource.org/docs/definition.php Open Source Definition] is a good place to start. There are also several comparisons available to help clarify how the various types of licenses work and what impact they'll have on code they're linked to. Search for "open source license comparison"<br />
<br />
=== Dependencies ===<br />
<br />
Another step before starting to work on a conversion is to verify that the code doesn't have deep dependancies on other packages that might not be available or represent a considerable conversion challenge. Some freeware offerings are bound to or extend proprietary packages that are frequently no longer available or come with inappropriate licenses.<br />
<br />
=== Compiler Issues ===<br />
<br />
Currently the stable 1.0.x version of the Free Pascal Compiler doesn't support interfaces, threads or Variant records. If the code you're converting needs these constructs, you'll have to use the 1.1 development branch of the compiler... which isn't always guaranteed to work with Lazarus.<br />
<br />
=== Platform and OS Issues ===<br />
<br />
Lazarus and the Free Pascal Compiler are cross-platform and cross-architecture development tools. In contrast, most existing Delphi code was specifically designed to run on an Intel processor under Win32. If your candidate component has a lot of Win32 specific code, it might be wise to try and find a less platform dependant alternative. But don't let this stop you... it's genuinely amazing what the LCL supports!<br />
<br />
== Doing the conversion ==<br />
<br />
=== Setting up the Lazarus environment for a conversion project ===<br />
<br />
====Create a test project====<br />
* Place code to be converted into a subdirectory (ie: convertdir)<br />
* Bring up Lazarus<br />
* File->Save All to the convertdir subdirectory. Meaningful names for the Project and default unit are optional.<br />
* Open the "main" unit to be converted in convertdir<br />
* Add it to the project: Project->Add Active Unit to Project<br />
* Run Tools->Quick Syntax Check or Run Build All to get started.<br />
====Initial items to watch out for====<br />
* Filenames are case sensitive with the 1.0.x series compilers. If you're working with this version, make all your filenames lower case. You'll get "File not found" errors if you don't.<br />
====Delphi VCL, Kylix CLX Sources in Lazarus====<br />
<br />
When converting Delphi/Kylix sources, it is often useful to do a find declaration to see, what a specific function is doing. The Lazarus IDE can parse the Delphi/Kylix sources. To do this it needs some searchpaths and compiler settings. You can easily setup this in<br />
Environment->CodeTools Defines Editor->Insert Template<br />
<br />
=== Conversion problems and solutions ===<br />
<br />
==== Delphi / Kylix file equivalents in Lazarus ====<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi / Kylix || class="header" | Lazarus || class="header" | Description<br />
|- class="code"<br />
| class="code" |.pas<br />
.dfm / .xfm<br />
.dcu / .dpu<br />
.dpr<br />
.res<br />
.dof / .kof<br />
---<br />
---<br />
---<br />
| class="code" |.pas, .pp<br />
.lfm<br />
.o<br />
.lpr<br />
---<br />
---<br />
.lrs<br />
.lpi<br />
.ppu<br />
| class="code" |Pascal unit file<br />
Form data file<br />
Compiled unit file<br />
Project file<br />
Resource file<br />
Project options file<br />
Lazarus resource file<br />
Lazarus project information file<br />
FPC unit description file<br />
|}<br />
<br />
==== Converting Delphi projects/forms/units to Lazarus ====<br />
<br />
Rename or copy the .dpr file to a .lpr file. Comment out or remove the <div class="dir">{$R *.res}</div> directive and add a <div class="dir">{$mode delphi}{$H+}</div> or <div class="dir">{$mode objfpc}{$H+}</div> directive to the .lpr file. Many existing Delphi forms can be converted to work with Lazarus by using the IDE's built in .dfm to .lfm form converter. It can be found under the Tools menu item as "Convert DFM file to LFM". Bring up the file dialog, select the dfm and the converter will do the rest.<br />
<br />
If you need to convert the whole unit (with or without a form), Lazarus also includes a built in "Convert Delphi unit to Lazarus unit" which will do the following for you -<br />
<br />
# renames the .pas and .dfm file to lowercase.<br />
# converts .dfm file to .lfm file (currently without content check, just format)<br />
# creates an empty .lrs file (the content will be created later)<br />
# adds <div class="dir">{$mode delphi}</div> directive<br />
# replaces windows unit with LCLIntf<br />
# adds LResources unit if needed<br />
# removes variants unit<br />
# removes <div class="dir">{$R *.dfm}</div> directive<br />
# adds initialization section and <div class="dir">{$i unit.lrs}</div> directive<br />
<br />
This allows quick and easy conversion of most units from Delphi format to Lazarus format. It does not do any validity check, or automatic syntax changes, so any syntax changes you need to make, additional unit/unit name changes, or dfm/pas changes for control/component differences you must still do manually, though in time some wizards to help facilitate some of this, especially the repairing of converted forms(lfm), may become available.<br />
<br />
==== Selecting the right compiler mode ====<br />
<br />
The [[Free Pascal]] Compiler supports 5 different pascal modes. For example TP for turbo pascal, lets you compile turbo pascal units. There is also a DELPHI compatibility mode that can be set to make existing code easier to convert. Lazarus prefers the OBJFPC mode, which almost equals the DELPHI mode, but is less ambigious than the Delphi syntax. Here are the important points:<br />
<br />
The mode can be selected at command line or at the start of the source. Using the command line has the advantage, that you don't need to change the source, but the disadvantage, that others must be told.<br />
<br />
Most Delphi units can be compiled by the [[Free Pascal]] compiler by adding <br />
{$IFDEF FPC}<br />
{$MODE DELPHI}<br />
{$ENDIF}<br />
right after the unit name.<br />
<br />
For more details about [[Free Pascal]] modes see the [http://www.freepascal.org/docs-html/prog/progap4.html#progse62.html Free Pascal Documentation]<br />
<br />
==== Cross-Platform considerations ====<br />
<br />
* Inline assembler is always a problem because it will bind the code to the Intel architecture. Some developers do algorithm prototypes in Pascal and ifdef the their optimized assembler. Fortunately Turbo-Power did this in numerous places with their code. If this is the case with the package you're converting, throw the switch back to Pascal.<br />
* Don't reference specific memory location like the BIOS data area. Find out what the code needs and try to find a cross platform alternative.<br />
* Don't do processor specific tricks (like using the Intel TSC) without enclosing your code in an ifdef for the platform the code needs... and providing an alternative for environments that don't have the hardware capability.<br />
* If you need some OS specific code, than you can use IFDEFs. See below for a list of macros.<br />
<br />
==== Useful compiler variables ====<br />
<br />
To write code, that behaves on different systems differently, you can use the <div class="dir">{$IFDEF Name}</div> directives.<br />
<br />
* <div class="dir">{$IfDef LCL}</div><br />
This variable is defined, when using the LCL package. Useful to write code, that works with the LCL and Delphi.<br />
* <div class="dir">{$IfDef FPC}</div><br />
This variable is defined, when using the FPC compiler. Useful to write code, that works with FPC and Delphi.<br />
* <div class="dir">{$IfDef Unix}</div>, <div class="dir">{$IfDef Win32}</div>, ...<br />
Defined by FPC for the current Target OS. Delphi defines "Linux", "Win32" and "MSWindows". [[Free Pascal]] runs on much more platforms and so it is recommended to use the more general items. For example "Unix" is defined for Linux, FreeBSD, NetBSD and OpenBSD, where Lazarus already runs.<br />
Use<br />
{$IfDef Linux}<br />
{$Define Unix}<br />
{$EndIf}<br />
to work around this for Kylix.<br />
<br />
For more details see the [http://www.freepascal.org/docs-html/prog/prog.html#QQ2-23-21 Free Pascal Documentation].<br />
<br />
==== Finding a missing identifier ====<br />
<br />
There are differences in how the LCL is organized when compared to the Delphi VCL. If you get a "not found" compiler error about a major class or identifier, the chances are good that it's in a different unit. A complete cross reference can be found by grep'ing lazarus/docs/xml or the lcl subdirectory.<br />
<br />
For example the commonly used tbutton typically throws an error in Delphi code because it's located in a unit named buttons.pp. The following command finds the correct unit very quickly (in the lazarus source directory):<br />
<br />
grep -in ' tbutton =' lcl/*<br />
<br />
<br />
==== Major unit differences between Lazarus and Delphi ====<br />
<br />
** Please add to this topic! **<br />
<br />
* Windows->LCLIntf, LCLType, LCLProc, VCLGlobals, ...)<br />
<br />
As the LCL is not windows specific, the code that is in the Delphi Windows unit for directly accessing the Win32 API is abstracted into seperate interfaces, which can be accessed from the LCLIntf unit. Keep in mind, that Lazarus does not emulate win32, so many functions are missing and some do not work as their win32 counterparts. These functions only exist for Delphi compatibility and should only be used for quick & dirty porting. LCL also breaks out many of the types, so often LCLType, and sometimes VCLGlobals are required. LCLProc also contains a few functions which can be usefull for lower level handling such as "FreeThenNil" as is in Delphi 5 and higher, "DeleteAmpersands" to remove additional ampersands from a string for controls(& vs && etc).<br />
<br />
* Messages->LMessages<br />
<br />
TControl Messages for win32 event callbacks of the format WM_CALLBACK and the structs associated with them are often found in the Messages unit in Delphi. In the LCL these types of messages and there structs are usually found in LMessages, usually with name changes of WM to LM, so for instance WM_MOUSEENTER becomes LM_MOUSEENTER, and TWMMouse becomes TLMMouse.<br />
<br />
* Graphics, Controls->GraphTypes, GraphMath, Graphics, Controls<br />
<br />
To simplify some things and break complexity of circles between units, a few types have been abstracted into a shared unit called GraphType, which includes things, which in Delphi are located in Graphics or Controls, for instance the bvNone etc of panels. So sometimes you have to include it. Also a unit which, although incompatible with Delphi, adds other usefull functionality is GraphMath, which adds a TFloatPoint for precision, misc routines for dealing with beziers, lines, and arcs, as well as some operator overloading for use with TPoints and TRect, such as for instance Point1 := Point2 + Point3, and comparing two rects like if (rect1 = rect2) then ...<br />
<br />
* Mask->MaskEdit<br />
<br />
For more intelligent naming considerations, the unit for TMaskEdit is called [MaskEdit|] instead of the slightly more nebulous Mask as in many versions of Delphi.<br />
<br />
* StdCtrls->StdCtrls,Buttons<br />
<br />
In many version of Delphi TButton is located in StdCtrls, while TSpeedButton and TBitBtn are in Buttons. For consistency and simplicity the LCL puts all button types in Buttons, which can occasionally break code conversion, so it is always a good idea to include.<br />
<br />
<br />
==== Property and method differences Delphi -> FPC/LCL ====<br />
* TBitmap contains a canvas in the LCL<br />
==== Syntax differences ====<br />
<br />
'''Please add to this topic!'''<br />
<br />
Because of the inherent strictness in FPC, some syntax changes are necessary, even though !!;dir {$Mode Delphi}!!;! does allow more lazyness like Delphi does. For this reason complying as much with the syntax rules of !!;dir {$Mode ObjFPC}!!;! as possible is highly recommended, even when the codebase is still going to be shared between Delphi and the LCL. Some of these are simply better coding practises, and sometimes because occasionally Delphi mode is not entirely accurate, or in a few instances Delphi acceptible code does not function as expected with FPC, even though it might compile. To that end even though not all such are strictly required, the following list of changes should be considered mandatory :<br />
<br />
;Variables initialization in FPC 1.0.x<br />
<br />
With Delphi it is possible (and quite common) to initialize a variable in its declaration, however this is not possible in FPC 1.0.x, const must be used instead, or prefereably in many situations, initialized elsewhere at some point before the variable is used (like unit initialization). <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">var</div><br />
MyObject: TSomeObject= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
| class="code" | <div class="key">var</div><br />
MyObject<div class="symbol">:</div> TSomeObject;<br />
<div class="cmt">//More code...</div><br />
<div class="key">implementation</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">initialization</div><br />
MyObject:= <div class="key">nil</div>;<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
;When assigning an event handling entry point, prefix it with an "@"<br />
<br />
For instance, you might assign a button callback manually <br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">begin</div> <br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= SomeFunction; <div class="cmt">//@ not required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">begin</div><br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= @SomeFunction; <div class="cmt">//@ IS required</div><br />
<div class="cmt">//more code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When calling a procedure variable use this syntax: theprocname()<br />
<br />
In Delphi there is no difference between a procedure and a procedure variable, however there is in FPC, so to call a procedure, even if it has no paramaters, you must append parenthesis. For Example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div> <br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div> <br />
OnMyCallback; <div class="cmt">//parenthesis not required</div> <br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div><br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div><br />
OnMyCallback(); <div class="cmt">//parenthesis required</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
;When accessing values in a pointer to a record you must dereference first<br />
<br />
In Delphi it is not required to dereference a pointer to a record to acces values within it, it can in fact be treated just like the record itself, or any other object. In FPC it must be first dereferenced. As an example,<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord^.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>; <br />
|}<br />
<br />
;When accessing chars of an indexed string Property of an object, it must be enclosed in parenthesis<br />
<br />
With Delphi it is possible to treat a Property exactly like some other const or var, even to accessing for instance individual chars of a string directly, while this is not always possible in FPC, specifically for indexed properties. Instead it must be enclosed in parenthesis, to make distinct. While this may not always hold true it is probably a good practice to consider anyway. For example<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//no parenthesis needed</div><br />
MyChar:= MyString[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//parenthesis sometimes needed</div><br />
MyChar:= (MyString)[<div class="int">3</div>];<br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
<br />
;You must typecast pointers to actual type when using with var or function of that type<br />
<br />
Sometimes in Delphi you will have a null pointer variable representing an object. While it might seem a complex situation, it is oddly quite common especially in large component packs as a method of preventing too many circular includes between objects in different units. In Delphi it is then possible to send this null pointer to a function expecting that object, without bothering to typecast to actual type, in fpc you must typecast. <br />
<br />
For example -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div><br />
<div class="symbol">Application</div><br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> GetSomeObject;<br />
<div class="cmt">//More code...</div><br />
DoSomething(MyComponent.SomeObject)<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//More code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="symbol">Application</div> <br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> Pointer(GetSomeObject);<br />
<div class="cmt">//More code...</div><br />
DoSomething(TSomeObject(MyComponent.SomeObject))<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Resources ====<br />
<br />
Delphi resource files are win32 specific and not compatible with Lazarus, so you'll have to recreate and compile them using the lazres. Lazres can be found in the lazarus/tools subdirectory. If you've downloaded the Lazarus sources, you'll need to compile it first.<br />
* cd lazarus/tools<br />
* make install<br />
To add a resource to your application:<br />
* lazres myresource.lrs mypix.xpm anotherpix.xpm<br />
* Add the LResources unit to your Uses clause<br />
* Include the .lrs file you created under the initialization block<br />
Example:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> TForm1.LoadGlyph(<div class="key">const</div> GlyphName: <div class="key">String</div>): TBitMap;<br />
<div class="key">begin</div><br />
Result:= TPixmap.Create<div class="symbol">;</div><br />
Result.LoadFromLazarusResource(GlyphName)<div class="symbol">;</div><br />
<div class="key">end</div>; <br />
<div class="cmt">//More code...</div><br />
<div class="key">begin</div><br />
Speedbutton1.glyph:= LoadGlyph('mypix')<div class="symbol">;</div><br />
<div class="cmt">//More code...</div><br />
<div class="key">end</div>;<br />
<div></div> <br />
<div class="key">initialization</div><br />
<div class="dir">{$I unit1.lrs}</div><br />
<div class="dir">{$I myresource.lrs}</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
== Getting Help ==<br />
<br />
If you encounter a problem during conversion that you just can't solve, there are a wide variety of places to get help. For pure Object Pascal and FPC issues, the best place to start is the Free Pascal [http://www.freepascal.org/docs-html/ Documentation] by Michaël Van Canneyt and Florian Klämpfl. For more Lazarus oriented problems, the Lazarus Project Documentation in the Lazarus-CCR Knowledgebase [Main Page] is the next place to look. Finally you can post a question on any of the [http://www.freepascal.org/maillist.html mailing lists for the Free Pascal Compiler] or the [http://community.freepascal.org:10000/bboard/ FPC forums] where a lot of experts are subscribed.<br />
<br />
There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems. Tamarack Associates operates a fast [http://www.tamaracka.com/search.htm search] engine specifically for the Borland usenet archives. Mer Systems Inc. provides a similar search [http://www.mers.com/searchsite.html engine]. Another outstanding source of information along with a sitewide [http://www.efg2.com/Lab/search.htm search] capability is Earl F. Glynn's Computer Lab and Reference [http://www.efg2.com/ Library].<br />
<br />
== Packaging and Releasing your component ==<br />
<br />
=== Creating a Lazarus package for your component(s) ===<br />
<br />
Creating a package makes installing the code you've converted a much easier process... especially if you're providing more then one component. Mattias Gärtner has written an overview of [[Lazarus Packages]] that should be read before beginning this process.<br />
<br />
=== Documentation ===<br />
<br />
The purpose of this site and the wiki format is to make the generation of professional documentation an easy and quick process. The wiki also makes it possible to see the results of your posting immediately and make any changes you'd like in real time.<br />
<br />
Using the Lazarus-CCR wiki to create nice looking documentation is very easy. If you've never used wiki markup before, you can get familiar with it in the [[Sand Box]] practice area.<br />
<br />
=== Creating a Code Release Page ===<br />
<br />
The Code Release Page contains vital information about your component that a potential downloader will need to know, such as license, intended platform, status (alpha, beta, stable...), where to download it, who wrote it, is support available... etc.<br />
<br />
The following procedure will let you create a Code Release Page with your browser: <br />
<br />
* Edit the [[Code And Components]] page and add a project name wiki link entry for your component in the "Released Components" section. Save the modified page.<br />
<br />
* Go to the [[Component Release Template]], select all and copy. Hit the back button on your browser to return to the [[Code And Components]] page.<br />
* Click on your new wiki component name entry and paste the release template into the blank edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your document looks the way you want it to.<br />
<br />
=== Creating a Comment Page for your component ===<br />
<br />
When your component is posted to the Sourceforge File Release System, the Lazarus-CCR admins will lock your code release page to prevent the unlikely event of someone changing your license, name or other release info.<br />
<br />
While you're building your code release page, you have the option to create another wiki link to a "news and comments" page for your component that will always be writable. This is called a ComponentCommentTemplate. The link to it should be added to the bottom of the code release template where there's a topic heading and a brief howto. The wiki name link should be your wiki component name with a Comments suffix like [[EpikTimer Comments]] or [[JpegLazarus Comments]] . The comments page will remain writable to collect feedback from users and for you to post updated information.<br />
<br />
A comment page can be added like this:<br />
<br />
* Edit your component release page and add the wiki comment link (in the format described above). Save the modified page.<br />
* Go to the [[Component Comment Template]] , select all and copy. Hit the back button on your browser to return to your component release page.<br />
* Click on the comment entry entry you created and paste the comment template into the edit box.<br />
* Edit the template accordingly and hit save.<br />
* Do edit-saves until your comment page looks the way you want it to.<br />
<br />
While the Lazarus-CCR admins initially lock code release pages, any member of the project can use their shell acount to unlock, edit and re-lock their pages.<br />
<br />
=== Submitting the component ===<br />
<br />
If you're a release technician on the project, upload your component to the SourceForge File Release System and add it to the list of release packages. Otherwise send it to one of the project administrators and we'll add it to the repository. We'll also put it into CVS so you'll continue to have access to it.<br />
<br />
== Contributors and Changes ==<br />
<br />
This page has been converted from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=CodeConversionGuide version].<br />
* Initial version by Tom Lisjac and Mattias Gärtner - 9/22/2003 [[User:Tom | VlxAdmin]]<br />
* Moved Getting help from the main page. T. Lisjac - 9/24/2003 [[User:Tom | VlxAdmin]]<br />
* Added documentation templates, procedure and links. 9/25/2003 [[User:Tom | VlxAdmin]]<br />
* LCLLinux was renamed to LCLIntf, [[User:Jesusrmx | Jesus Reyes]], 9/27/2003<br />
* added more information on Unit changes, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Updated Syntax differences, including some examples, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* FPC 1.0.x doesn't support interfaces, [[User:Vincent | Vincent Snijders]] 9/28/2003<br />
* Fixed some of the examples per new WikiWord definition, 9/28/2003 [[User:Tom | VlxAdmin]]<br />
* Made code more consistant to remove last accidental Pascal WikiWord definitions, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/17/2003<br />
* Use pascal stylesheet to make example code more readable, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/18/2003</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Improving_language_shootout_results&diff=14476Improving language shootout results2005-08-04T10:30:51Z<p>Wstomv: /* Shootout criticism */</p>
<hr />
<div>==About==<br />
<br />
The computer language shootout (http://shootout.alioth.debian.org/benchmark.php) is a realisticly flawed<br />
benchmarking system which compares many languages on illogical basis. See their homepage for more info.<br />
<br />
==Goals==<br />
<br />
Our goals are to be on the highest possible positions. The requirements to reach them can be categorized<br />
into two.<br />
<br />
1: Optimizations on the assembler level. (core devel work)<br />
<br />
2: Optimizations of the benchmarks. (junior devel work)<br />
<br />
==Way to go==<br />
<br />
It was decided that to keep memory requirements low it's best to use val() and str() and never<br />
include SysUtils unless really required. 32 bit integers should be used when possible to increase<br />
speed as the benchmarking machine is x86(athlon 1Gb, 256Mb ram).<br />
Use of inline and records instead of classes can also improve performance considerably, but<br />
additional testing and comparing with C and other languages should be the main factor.<br />
Special note: inlining of recursive functions is possible and sometimes increases speed.<br />
<br />
==Shootout criticism==<br />
<br />
Any page about benchmarking should discuss the use of the benchmarks. FPC does relatively well overall,<br />
but is relatively weak in its category. <br />
<br />
Criticising the shooutout is not difficult, I mention a few points below.<br />
<br />
* The main problem is that the applications are relatively short and highly computational. This has a lot of consequences:<br />
** they favour lower level languages, well, that is not in Pascal's advantage.<br />
** these benchmarks also favour compilers that aggressively optimize tight heavy calculating loops. FPC is not in that league, but, like Delphi, more geared to overall application performance, and not numeric or visual work with lots of tight loops. This is also why frameworks like Java and .NET don't score _that_ bad. Simply because the JIT can do good work for these tight loops.<br />
** Some benchmarks obviously target certain very specific optimizations like tail recursion optimization.<br />
* Language usability and overall speed of the development process is not measured at all.<br />
** Systems with a heavy RTL are punished. Both in size and startup time. However for actually getting work done, as long as it is not extreme, a full RTL is nice.<br />
** Languages that have a lower and higher level mode (e.g. FPC with its Pascal and Delphi levels) typically choose the lowest possible version, even if that is not the one typically used.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Improving_language_shootout_results&diff=14475Improving language shootout results2005-08-04T10:28:19Z<p>Wstomv: /* Goals */</p>
<hr />
<div>==About==<br />
<br />
The computer language shootout (http://shootout.alioth.debian.org/benchmark.php) is a realisticly flawed<br />
benchmarking system which compares many languages on illogical basis. See their homepage for more info.<br />
<br />
==Goals==<br />
<br />
Our goals are to be on the highest possible positions. The requirements to reach them can be categorized<br />
into two.<br />
<br />
1: Optimizations on the assembler level. (core devel work)<br />
<br />
2: Optimizations of the benchmarks. (junior devel work)<br />
<br />
==Way to go==<br />
<br />
It was decided that to keep memory requirements low it's best to use val() and str() and never<br />
include SysUtils unless really required. 32 bit integers should be used when possible to increase<br />
speed as the benchmarking machine is x86(athlon 1Gb, 256Mb ram).<br />
Use of inline and records instead of classes can also improve performance considerably, but<br />
additional testing and comparing with C and other languages should be the main factor.<br />
Special note: inlining of recursive functions is possible and sometimes increases speed.<br />
<br />
==Shootout criticism==<br />
<br />
Any page about benchmarking should discuss the use of the benchmarks. FPC does relatively well overall,<br />
but is relatively weak in its category. <br />
<br />
Criticising the shooutout is not difficult, I mention a few points below.<br />
<br />
* The main problem is that the applications are relatively short and highly computational. This has a lot of consequences:<br />
** they favour lower level languages, well, that is not in Pascal's disadvantage.<br />
** these benchmarks also favour compilers that aggressively optimize tight heavy calculating loops. FPC is not in that league, but, like Delphi more geared to overall application performance, and not numeric or visual work with lots of tight loops. This is also why frameworks like Java and .NET don't score _that_ bad. Simply because the JIT can do good work for these tight loops.<br />
** Some benchmark obviously target certain very specific optimizations like tail recursion optimization.<br />
* Language usability and overall speed of the development process is not measured at all.<br />
** Systems with a heavy RTL are punished. Both in size and startup time. However for actually getting work done, as long as it is not extreme, a full RTL is nice.<br />
** Languages that have a lower and higher level mode (e.g. FPC with its Pascal and Delphi levels) typically choose the lowest possible version, even if that is not the one typically used.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=How_To_Help_Developing_Lazarus&diff=2402How To Help Developing Lazarus2005-06-29T18:19:25Z<p>Wstomv: /* Where to begin? */</p>
<hr />
<div>== So you want to help make Lazarus a world class IDE. Well you've come to the right place.==<br />
<br />
This Is A Work In Progress. If you have useful information to add to this, or see mistakes please feel free to fix or add to this page.<br />
<br />
== Prerequisites to developing Lazarus ==<br />
# Lazarus will no longer compile with FPC version 1.0.10. You should have the latest release of FreePascal(currently 2.0.0, or a recent CVS version is recommended).<br />
# You MUST have the very latest Lazarus from CVS. [[Getting_Lazarus#Via_CVS|Getting Lazarus Via CVS]]<br />
<br />
== Where to begin? ==<br />
So now you have the latest version of Lazarus and wish to start improving Lazarus, but "where do I begin?" <br />
<br />
Well, that depends. If you don't have any particular woes about Lazarus but just want to help, then I would recommend looking at the bug list [http://www.lazarus.freepascal.org/mantis/main_page.php Bug Tracker] find a bug that you think you can fix, and start hacking. <br />
<br />
Lazarus needs more documentation! If you don't want to fix a bug you can help by writing documentation. Look at [[Lazarus Documentation Editor]] and [[LCL Documentation Roadmap]] for some help on how to and a list of units to be documented.<br />
<br />
Also see these links: [[Extending the IDE]], [[Lazarus IDE ToDo List]]<br />
<br />
== Now I've fixed lazarus or added documentation. How do I submit my changes? ==<br />
You will need to make a "patch" ([[Creating A Patch]]) and send it to the mailing list (maximum size 40kB) or the mailbox for patches [mailto:patch@lazarus.dommelstein.net patch@lazarus.dommelstein.net].<br />
<br />
If you need help doing any of these things, you can always ask on the Lazarus mailing list or ask in #lazarus-ide on irc.freenode.net.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=Lazarus_Documentation_Editor&diff=2484Lazarus Documentation Editor2005-06-29T18:06:04Z<p>Wstomv: /* The addition of new units */</p>
<hr />
<div>== Introduction ==<br />
<br />
An important part of Lazarus still missing is the documentation. To aid in the making of this documentation a tool has been developed. This page will describe the workings of this tool.<br />
To denote the Lazarus base directory in this document I use [$LazDir]. So when you read this replace this with the directory Lazarus is installed in.<br />
<br />
== The Why ==<br />
The first goal of this project is to be make an online help-file available. To make the help-file platform independent we have started to create XML-files for each unit used in Lazarus. So far only dialogs.pp and buttons.pp have been started.<br />
<br />
These XML-files will then be used to create HTML-pages which can be accessed through the Internet on http://lazarus-ccr.sourceforge.net/docs/lcl/ . Then at a later stage an integrated help will be developed again using these same XML-files.<br />
<br />
== The Start ==<br />
As mentioned before, to keep the documentation platform independent XML is used. The current documentation can be found in [$LazDir]/docs/xml/. So far there are mostly skeleton files in the lcl directory. The XML files you find in this directory are auto generated and need to be adapted to be usable.<br />
So now we know where to find the files, lets look at the tool to create / adapt them.<br />
<br />
=== The Tool ===<br />
"lazde" is a tool to edit the xml files, but can also be used to generate the basic files from source files and by means of an external tool to generate a HTML version of the documentation. An example of the results of the last tool can be seen [http://lazarus-ccr.sourceforge.net/docs/lcl/index.html here], a part of the documentation sofar.<br />
As there is no compiled version of lazde, you have to make one yourself. The sources for "lazde" can be found in [$LazDir]/doceditor/.<br />
When you run this program and you have opened [$LazDir]/docs/xml/lcl/dialogs.xml you will be presented with this screen<br />
<center>[[Image:Lazdemain.png]]</center><br />
<br />
=== The Work ===<br />
<div class="floatleft"> http://lazarus-ccr.sourceforge.net/kb/images/9/90/Lazdeelements.png </div><div><br />
Opening the node "Packages" will show the "LCL" node which contains a "Dialogs" node. Selecting this last node will fill the lower treeview with elements. These elements depict Constants, Types and Classes defined in the Dialogs.pp unit. Used units are added as well as nodes. <br />
Other nodes are added for the properies of a class, the parameters for a function and so on.<br />
<br />
Selecting a node in the lower left treeview will make the content of that node displayed on the right side of the window.<br />
<br />
When you look at [http://lazarus-ccr.sourceforge.net/docs/lcl/dialogs/index-4.html this page] you will see an overview of classes defined in the "dialogs" unit. After each class you see a line of text. This text comes from the "short" editbox from lazde.<br />
<br />
Below the "short" editbox, there is a memofield where you can enter a more elaborate description of the component or the property.<br />
Note: If you want to insert a line break use <nowiki><br/></nowiki><br />
<br />
Next are "Errors", "See also" and "Example code File".<br />
<br />
"Errors" can be used to tell about errors raised by a function if parameters have values that are out of range. For an example see [http://lazarus-ccr.sourceforge.net/docs/rtl/dateutils/recodeyear.html this page].<br />
<br />
Just above "See also" and "Example code File" you see three buttons. These buttons enable you to add and remove links to other pages or code examples respectively.<br />
</div><br />
<br />
== The Outcome ==<br />
Have a look at the description of [http://lazarus-ccr.sourceforge.net/docs/lcl/dialogs/inputquery.html InputQuery].<br />
On the top of the page we see what the page is about, in this case the InputQuery function form the dialogs.pp. The first line of text is what is entered in the "Short" editbox in lazde.<br />
<br />
Next is the declaration of this function in the sources. The declaration part is created by the html-builder and is taken from the sources. Because there are two versions of this function the source position says 0. <br />
<br />
Then the arguments are given. When you open the InputQuery node in lazde you will see all arguments mentioned as child nodes. The text shown after the arguments is what has been entered in the "Short" editbox when the respective child nodes are selected.<br />
<br />
As a fourth paragraph the Function result is shown. The text shown here has been entered in the same way as the arguments.<br />
<br />
Finally the description is shown. This is the text entered in the description box of lazde.<br />
<br />
== The addition of new units ==<br />
<br />
There are of course other units that need to be documented. If it is for instance a unit for some package, chances are there is no xml file to start with. You have to start from scratch then, but lazde has a function to get you off to a flying start. Just go to File -> New and the following screen will appear:<br />
<center>[[Image:Lazdenewdocfromfile.png]]</center><br />
You start by giving the package a name. All units you want to add to this package should have the same package name. Afterwards you enter the source file to use; you can browse to this file as well. Then enter a name for the output file. (Do not forget the xml extension!) And press OK.<br />
<br />
lazde will then generate the basics for the documentation. The generated file will be opened and the treeview will be populated by all units, classes, types, functions and so on from your source file. Now you are ready to start documenting a new part of Lazarus.<br />
<br />
Have a look at [[LCL Documentation Roadmap]] to see which units still need to be documented.<br />
<br />
== The Final result ==<br />
<br />
What I experienced during the use of the program is that I would like to see how the information is shown in its final stage (as a browsable document). For this purpose lazde makes use of a utility to build all necessary HTML-files.<br />
<br />
This utility can be started from the menu Extra -> Build. The following screen will be shown:<br />
<center>[[Image:Lazdebuild1.png]]</center><br />
"Package" should be the same as the name you gave when you created the xml files. For "Format" choose HTML. At "Output" you enter the path where the resulting files should be placed.<br />
Press "Add all" and all documents your were working on will be added to the project. Then go to the next to tab<br />
<center>[[Image:Lazdebuild2.png]]</center><br />
and enter the paths to the source files.<br />
After you have pressed build your HD will start to rattle and finally the following output will be shown on the "Build output" tab.<br />
Building docs using command: fpdoc --package="LCL"<br />
--output="/home/matthijs/documentatie/LCL" --format=html --content <br />
--descr="/home/matthijs/Projecten/Lazarus/doceditor/buttons.xml"<br />
--descr="/home/matthijs/Projecten/Lazarus/doceditor/comctrls.xml"<br />
--descr="/home/matthijs/Projecten/Lazarus/doceditor/dialogs.xml"<br />
--descr="/home/matthijs/Projecten/Lazarus/doceditor/controls.xml"<br />
--input="/home/matthijs/cvsroot/lazarus/lcl/buttons.pp"<br />
--input="/home/matthijs/cvsroot/lazarus/lcl/comctrls.pp"<br />
--input="/home/matthijs/cvsroot/lazarus/lcl/dialogs.pp"<br />
--input="/home/matthijs/cvsroot/lazarus/lcl/controls.pp" <br />
<br />
FPDoc - Free Pascal Documentation Tool<br />
(c) 2000 - 2003 Areca Systems GmbH / Sebastian Guenther, sg@freepascal.org<br />
<br />
Writing 2788 pages...<br />
Done.<br />
Documentation successfully built.<br />
<br />
When you go to the directory you entered at "Output" you will see a index.html file and (in this case 4) sub directories. Open index.html in your favorit browser and see the result of all your hard work on the documentation. You will be able to follow the links and read it all.<br />
<br />
When you plan to continue working on this package of documentation, press "Save" and save the build options. You will be asked to provide a name for the file and the options will be saved. Next time you want to build the HTML-files you can just "load" them again.<br />
<br />
== The Submission ==<br />
When you are satisfied with your work you certainly want to share it with the Lazarus community. All you have to do is make a [[Creating A Patch|patch]], zip this and send it in.<br />
<br />
== A small note ==<br />
Note the following: The lazde is work in progress. It is workable, but not completely finished yet. So there can be some bugs in it, but feel free to fix them.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=User:Wstomv&diff=15928User:Wstomv2005-06-04T20:56:15Z<p>Wstomv: </p>
<hr />
<div>===Tom Verhoeff===<br />
I teach (among other things) programming courses at the [http://www.tue.nl/ Technische Universiteit Eindhoven], some of them in (Object) Pascal.<br />
We developed [http://peach.win.tue.nl/ PEACH] (Programming Education And Contest Hosting verification system), which uses FPC for evaluating Pascal programs.<br />
I am also involved in the [http://olympiads.win.tue.nl/nio/ Dutch National Olympiad in Informatics] (NIO) and the [http://olympiads.win.tue.nl/ioi/ International Olympiad in Informatics] (IOI),<br />
both of which use FPC as Pascal compiler.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FCL&diff=13257FCL2005-06-03T21:08:40Z<p>Wstomv: /* Usage */</p>
<hr />
<div>The ''Free Component Library'' (FCL) consists of a collection of units, providing components (mostly classes) for common tasks.<br />
It intends to be compatible with Delphi's ''Visual Component Library'' (VCL), but the FCL is restricted to non-visual components.<br />
On the other hand, the FCL also goes beyond the VCL.<br />
<br />
See [http://www.freepascal.org/fcl/fcl.html Free Component Library] for the current development status and an overview of the available components.<br />
You can also check the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
Note that there are also some platform specific files in the FCL, which you can find under trunk/fcl/<platform>/.<br />
<br />
=== Usage ===<br />
<br />
To use an FCL component you need to include its name in a '''uses''' clause of your program or unit (see example below).<br />
The default compiler configuration is set up to search the fcl directory for such units.<br />
You can also set the appropriate search path with a command-line compiler option of the form -Fu<path-to-fcl-units>.<br />
<br />
=== Documentation ===<br />
<br />
Currently, the FCL is not documented (feel free to contribute).<br />
For Delphi compatible units, you could consult the Delphi documentation.<br />
You can always take a look at the source files in the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
<br />
=== Example ===<br />
<br />
The following program illustrates the use of the class TObjectList in the FCL unit Contnrs (providing various containers, including lists, stacks, and queues):<br />
<br />
program TObjectListExample;<br />
<br />
uses<br />
Classes, { from RTL for TObject }<br />
Contnrs; { from FCL for TObjectList }<br />
<br />
type<br />
TMyObject = class(TObject) { just some application-specific class }<br />
private<br />
FName: String; { with a string field }<br />
public<br />
constructor Create(AName: String); { and a constructor to create it with a given name }<br />
property Name: String read FName; { and a property to read the name }<br />
end;<br />
<br />
constructor TMyObject.Create(AName: String);<br />
begin<br />
inherited Create;<br />
FName := AName;<br />
end;<br />
<br />
var<br />
VObjectList: TObjectList; { for a list of objects; it is a reference to such a list! }<br />
<br />
begin<br />
VObjectList := TObjectList.Create { create an empty list }<br />
with VObjectList do<br />
begin<br />
Add(TMyObject.Create('Thing One'));<br />
Writeln((Last as TMyObject).Name);<br />
Add(TMyObject.Create('Thing Two'));<br />
Writeln((Last as TMyObject).Name);<br />
end;<br />
end.<br />
<br />
This program must be compiled in an object-oriented mode, such as -Mobjfpc or -Mdelphi.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FCL&diff=13256FCL2005-06-03T21:07:31Z<p>Wstomv: </p>
<hr />
<div>The ''Free Component Library'' (FCL) consists of a collection of units, providing components (mostly classes) for common tasks.<br />
It intends to be compatible with Delphi's ''Visual Component Library'' (VCL), but the FCL is restricted to non-visual components.<br />
On the other hand, the FCL also goes beyond the VCL.<br />
<br />
See [http://www.freepascal.org/fcl/fcl.html Free Component Library] for the current development status and an overview of the available components.<br />
You can also check the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
Note that there are also some platform specific files in the FCL, which you can find under trunk/fcl/<platform>/.<br />
<br />
=== Usage ===<br />
<br />
To use an FCL component you need to include its name in a '''uses''' clause of your program or unit (see example below).<br />
The default compiler configuration is set up to search the fcl directory for such units.<br />
You can also set it with a command-line compiler option of the form -Fu<path-to-fcl-units>.<br />
<br />
=== Documentation ===<br />
<br />
Currently, the FCL is not documented (feel free to contribute).<br />
For Delphi compatible units, you could consult the Delphi documentation.<br />
You can always take a look at the source files in the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
<br />
=== Example ===<br />
<br />
The following program illustrates the use of the class TObjectList in the FCL unit Contnrs (providing various containers, including lists, stacks, and queues):<br />
<br />
program TObjectListExample;<br />
<br />
uses<br />
Classes, { from RTL for TObject }<br />
Contnrs; { from FCL for TObjectList }<br />
<br />
type<br />
TMyObject = class(TObject) { just some application-specific class }<br />
private<br />
FName: String; { with a string field }<br />
public<br />
constructor Create(AName: String); { and a constructor to create it with a given name }<br />
property Name: String read FName; { and a property to read the name }<br />
end;<br />
<br />
constructor TMyObject.Create(AName: String);<br />
begin<br />
inherited Create;<br />
FName := AName;<br />
end;<br />
<br />
var<br />
VObjectList: TObjectList; { for a list of objects; it is a reference to such a list! }<br />
<br />
begin<br />
VObjectList := TObjectList.Create { create an empty list }<br />
with VObjectList do<br />
begin<br />
Add(TMyObject.Create('Thing One'));<br />
Writeln((Last as TMyObject).Name);<br />
Add(TMyObject.Create('Thing Two'));<br />
Writeln((Last as TMyObject).Name);<br />
end;<br />
end.<br />
<br />
This program must be compiled in an object-oriented mode, such as -Mobjfpc or -Mdelphi.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FCL&diff=13255FCL2005-06-03T21:06:09Z<p>Wstomv: /* Example */</p>
<hr />
<div>The ''FreePascal Component Library'' (FCL) consists of a collection of units, providing components (mostly classes) for common tasks.<br />
It intends to be compatible with Delphi's ''Visual Component Library'' (VCL), but the FCL is restricted to non-visual components.<br />
On the other hand, the FCL also goes beyond the VCL.<br />
<br />
See [http://www.freepascal.org/fcl/fcl.html FreePascal Component Library] for the current development status and an overview of the available components.<br />
You can also check the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
Note that there are also some platform specific files in the FCL, which you can find under trunk/fcl/<platform>/.<br />
<br />
=== Usage ===<br />
<br />
To use an FCL component you need to include its name in a '''uses''' clause of your program or unit (see example below).<br />
The default compiler configuration is set up to search the fcl directory for such units.<br />
You can also set it with a command-line compiler option of the form -Fu<path-to-fcl-units>.<br />
<br />
=== Documentation ===<br />
<br />
Currently, the FCL is not documented (feel free to contribute).<br />
For Delphi compatible units, you could consult the Delphi documentation.<br />
You can always take a look at the source files in the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
<br />
=== Example ===<br />
<br />
The following program illustrates the use of the class TObjectList in the FCL unit Contnrs (providing various containers, including lists, stacks, and queues):<br />
<br />
program TObjectListExample;<br />
<br />
uses<br />
Classes, { from RTL for TObject }<br />
Contnrs; { from FCL for TObjectList }<br />
<br />
type<br />
TMyObject = class(TObject) { just some application-specific class }<br />
private<br />
FName: String; { with a string field }<br />
public<br />
constructor Create(AName: String); { and a constructor to create it with a given name }<br />
property Name: String read FName; { and a property to read the name }<br />
end;<br />
<br />
constructor TMyObject.Create(AName: String);<br />
begin<br />
inherited Create;<br />
FName := AName;<br />
end;<br />
<br />
var<br />
VObjectList: TObjectList; { for a list of objects; it is a reference to such a list! }<br />
<br />
begin<br />
VObjectList := TObjectList.Create { create an empty list }<br />
with VObjectList do<br />
begin<br />
Add(TMyObject.Create('Thing One'));<br />
Writeln((Last as TMyObject).Name);<br />
Add(TMyObject.Create('Thing Two'));<br />
Writeln((Last as TMyObject).Name);<br />
end;<br />
end.<br />
<br />
This program must be compiled in an object-oriented mode, such as -Mobjfpc or -Mdelphi.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FCL&diff=13254FCL2005-06-03T21:05:31Z<p>Wstomv: /* Example */</p>
<hr />
<div>The ''FreePascal Component Library'' (FCL) consists of a collection of units, providing components (mostly classes) for common tasks.<br />
It intends to be compatible with Delphi's ''Visual Component Library'' (VCL), but the FCL is restricted to non-visual components.<br />
On the other hand, the FCL also goes beyond the VCL.<br />
<br />
See [http://www.freepascal.org/fcl/fcl.html FreePascal Component Library] for the current development status and an overview of the available components.<br />
You can also check the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
Note that there are also some platform specific files in the FCL, which you can find under trunk/fcl/<platform>/.<br />
<br />
=== Usage ===<br />
<br />
To use an FCL component you need to include its name in a '''uses''' clause of your program or unit (see example below).<br />
The default compiler configuration is set up to search the fcl directory for such units.<br />
You can also set it with a command-line compiler option of the form -Fu<path-to-fcl-units>.<br />
<br />
=== Documentation ===<br />
<br />
Currently, the FCL is not documented (feel free to contribute).<br />
For Delphi compatible units, you could consult the Delphi documentation.<br />
You can always take a look at the source files in the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
<br />
=== Example ===<br />
<br />
The following program illustrates the use of the class TObjectList in the FCL unit Contnrs (providing various containers, including lists, stacks, and queues):<br />
<br />
program TObjectListExample;<br />
<br />
uses<br />
Classes, { from RTL for TObject }<br />
Contnrs; { from FCL for TObjectList }<br />
<br />
type<br />
TMyObject = class(TObject) { just some application-specific class }<br />
private<br />
FName: String; { with a string field }<br />
public<br />
constructor Create(AName: String); { and a constructor to create it with a given name }<br />
property Name: String read FName; { and a property to read the name }<br />
end;<br />
<br />
constructor TMyObject.Create(AName: String);<br />
begin<br />
inherited Create;<br />
FName := AName;<br />
end;<br />
<br />
var<br />
VObjectList: TObjectList; { for a list of objects; it is a reference to such a list! }<br />
<br />
begin<br />
VObjectList := TObjectList.Create { create an empty list }<br />
with VObjectList do<br />
begin<br />
Add(TMyObject.Create('ThingOne'));<br />
Writeln((Last as TMyObject).Name);<br />
Add(TMyObject.Create('ThingTwo'));<br />
Writeln((Last as TMyObject).Name);<br />
end;<br />
end.<br />
<br />
This program must be compiled in an object-oriented mode, such as -Mobjfpc or -Mdelphi.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FCL&diff=13253FCL2005-06-03T21:02:47Z<p>Wstomv: </p>
<hr />
<div>The ''FreePascal Component Library'' (FCL) consists of a collection of units, providing components (mostly classes) for common tasks.<br />
It intends to be compatible with Delphi's ''Visual Component Library'' (VCL), but the FCL is restricted to non-visual components.<br />
On the other hand, the FCL also goes beyond the VCL.<br />
<br />
See [http://www.freepascal.org/fcl/fcl.html FreePascal Component Library] for the current development status and an overview of the available components.<br />
You can also check the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
Note that there are also some platform specific files in the FCL, which you can find under trunk/fcl/<platform>/.<br />
<br />
=== Usage ===<br />
<br />
To use an FCL component you need to include its name in a '''uses''' clause of your program or unit (see example below).<br />
The default compiler configuration is set up to search the fcl directory for such units.<br />
You can also set it with a command-line compiler option of the form -Fu<path-to-fcl-units>.<br />
<br />
=== Documentation ===<br />
<br />
Currently, the FCL is not documented (feel free to contribute).<br />
For Delphi compatible units, you could consult the Delphi documentation.<br />
You can always take a look at the source files in the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
<br />
=== Example ===<br />
<br />
The following program illustrates the use of the class TObjectList in the FCL unit Contnrs (providing various containers, including lists, stacks, and queues):<br />
<br />
program TObjectListExample;<br />
<br />
uses<br />
Classes, { from RTL for TObject }<br />
Contnrs; { from FCL for TObjectList }<br />
<br />
type<br />
TMyObject = class(TObject) { just some application-specific class }<br />
private<br />
FName: String; { with a string field }<br />
public<br />
constructor Create(AName: String); { and a constructor to create it with a given name }<br />
property Name: String read FName; { and a property to read the name }<br />
end;<br />
<br />
constructor TMyObject.Create(AName: String);<br />
begin<br />
inherited Create;<br />
FName := AName;<br />
end;<br />
<br />
var<br />
VObject1, VObject2: TMyObject; { just some objects }<br />
VObjectList: TObjectList; { for a list of objects; s is a reference to such a list }<br />
<br />
begin<br />
VObject1 := TMyObject.Create('ThingOne');<br />
VObject2 := TMyObject.Create('ThingTwo');<br />
VObjectList := TObjectList.Create { create an empty list }<br />
with VObjectList do<br />
begin<br />
Add(VObject1);<br />
Writeln((Last as TMyObject).Name);<br />
Add(VObject2);<br />
Writeln((Last as TMyObject).Name);<br />
end;<br />
end.<br />
<br />
This program must be compiled in an object-oriented mode, such as -Mobjfpc or -Mdelphi.</div>Wstomvhttps://wiki.freepascal.org/index.php?title=FCL&diff=13252FCL2005-06-03T21:01:02Z<p>Wstomv: </p>
<hr />
<div><br />
The "FreePascal Component Library" (FCL) consists of a collection of units, providing components (mostly classes) for common tasks.<br />
It intends to be compatible with Delphi's "Visual Component Library" (VCL), but the FCL is restricted to non-visual components.<br />
On the other hand, the FCL also goes beyond the VCL.<br />
<br />
See [http://www.freepascal.org/fcl/fcl.html FreePascal Component Library] for the current development status and an overview of the available components.<br />
You can also check the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
Note that there are also some platform specific files in the FCL, which you can find under trunk/fcl/<platform>/.<br />
<br />
=== Usage ===<br />
<br />
To use an FCL component you need to include its name in a '''uses''' clause of your program or unit (see example below).<br />
The default compiler configuration is set up to search the fcl directory for such units.<br />
You can also set it with a command-line compiler option of the form -Fu<path-to-fcl-units>.<br />
<br />
=== Documentation ===<br />
<br />
Currently, the FCL is not documented (feel free to contribute).<br />
For Delphi compatible units, you could consult the Delphi documentation.<br />
You can always take a look at the source files in the [http://www.freepascal.org/cgi-bin/viewcvs.cgi/trunk/fcl/inc/ source repository].<br />
<br />
=== Example ===<br />
<br />
The following program illustrates the use of the class TObjectList in the FCL unit Contnrs (providing various containers, including lists, stacks, and queues):<br />
<br />
program TObjectListExample;<br />
<br />
uses<br />
Classes, { from RTL for TObject }<br />
Contnrs; { from FCL for TObjectList }<br />
<br />
type<br />
TMyObject = class(TObject) { just some application-specific class }<br />
private<br />
FName: String; { with a string field }<br />
public<br />
constructor Create(AName: String); { and a constructor to create it with a given name }<br />
property Name: String read FName; { and a property to read the name }<br />
end;<br />
<br />
constructor TMyObject.Create(AName: String);<br />
begin<br />
inherited Create;<br />
FName := AName;<br />
end;<br />
<br />
var<br />
VObject1, VObject2: TMyObject; { just some objects }<br />
VObjectList: TObjectList; { for a list of objects; s is a reference to such a list }<br />
<br />
begin<br />
VObject1 := TMyObject.Create('ThingOne');<br />
VObject2 := TMyObject.Create('ThingTwo');<br />
VObjectList := TObjectList.Create { create an empty list }<br />
with VObjectList do<br />
begin<br />
Add(VObject1);<br />
Writeln((Last as TMyObject).Name);<br />
Add(VObject2);<br />
Writeln((Last as TMyObject).Name);<br />
end;<br />
end.<br />
<br />
This program must be compiled in an object-oriented mode, such as -Mobjfpc or -Mdelphi.</div>Wstomv