https://wiki.freepascal.org/api.php?action=feedcontributions&user=Dirk+Fellenberg&feedformat=atomLazarus wiki - User contributions [en]2024-03-28T09:43:10ZUser contributionsMediaWiki 1.35.6https://wiki.freepascal.org/index.php?title=Template:Logical_operators&diff=141769Template:Logical operators2020-12-26T17:08:08Z<p>Dirk Fellenberg: Removed unnecessary wiki characters {{</p>
<hr />
<div>==See also==<br />
<br />
* [[Boolean]]<br />
* [https://www.freepascal.org/docs-html/ref/refsu46.html § “boolean operators” in the “Free Pascal Reference Guide”] <br />
* [https://www.freepascal.org/docs-html/ref/refsu47.html § “logical operators” in the “Free Pascal Reference Guide”] <br />
* [[And|{{HL|and}}]] Bitwise and<br />
* [[Or|{{HL|or}}]] Bitwise or<br />
* [[Not|{{HL|not}}]] Bitwise negation (unary)<br />
* [[Shl|{{HL|shl}}]] Bitwise shift to the left<br />
* [[Shr|{{HL|shr}}]] Bitwise shift to the right<br />
* [[Xor|{{HL|xor}}]] Bitwise xor<br />
* [[Odd|{{HL|odd}}]] Determine if number is odd<br />
* << Bitwise shift to the left (same as shl)<br />
* >> Bitwise shift to the right (same as shr)<br />
* [[$Bitpacking]]<br />
* [[Bit manipulation]]<br />
<br />
<noinclude><br />
This template is to be placed at the bottom of all pages dealing with all logical operators: And, Or, etc.<br />
<br />
[[Category:Operators]]<br />
<br />
<noinclude><br />
<br />
[[Category:Information boxes]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Issues_3.2.0&diff=136379Issues 3.2.02020-05-18T18:35:24Z<p>Dirk Fellenberg: Merge request: r44179 Mantis 36603</p>
<hr />
<div>= Issues with 3.2.0 release candidates =<br />
<br />
This page is supposed to contain all issues discovered while testing release candidates and their status. Make sure to include information about the platform where the problem appears (if applicable). Once the issue gets resolved, you should strike it over and add number of SVN revision fixing it. If the revision number refers to a SVN repository different from "fpc" (i.e. "fpcbuild" or "fpcdocs"), include information about the SVN repository too.<br />
<br />
== Issues with 3.2.0-rc1 ==<br />
<br />
=== faq.txt ===<br />
<br />
* [[Testers 3.2.0|Release Testing Procedure]] point 3.2 - no faq.txt file in the macOS disk image.<br />
<br />
=== readme.txt typos ===<br />
<br />
* "Both these adresses are for mailing lists. If you're not subscribed," -- adresses should be addresses.<br />
* "order to make the compiler/rtl & IDE in a resonable time (eg <30 minutes)" -- resonable should be reasonable.<br />
<br />
=== Other documentation issues ===<br />
<br />
* <s>Runtime error 213 trying to use the textmode IDE help index. {{MantisLink|37094}}</s> Fixed in revisions 45406,45407.<br />
* The Language Reference, Programmer's Guide, and User's Guide CHM files have an odd string on their first page: "mei 2019". Additionally the accented letters in author names aren't displayed correctly in those files. The FPDoc CHM has a similar front page, but it does looks correct.<br />
<br />
=== macOS ===<br />
<br />
* The Intel installer currently installs even if the command line utilities are not yet installed. This results in missing parameters in the generated /etc/fpc.cfg (even if they are installed afterwards; you have to reinstall fpc to regenerate fpc.cfg)<br />
<br />
* The Intel installer currently installs the man pages into /usr/local/man/[man1|man5] where they are not found. They should be installed into /usr/local/share/man/[man1|man5]. I reported here for 3.0.4: https://bugs.freepascal.org/view.php?id=35969<br />
** Fixed. [[User:Jonas|Jonas]] ([[User talk:Jonas|talk]])<br />
* A man page is installed for fp (text mode IDE), but there is no fp binary installed. {{MantisLink|36861}}<br />
** Fixed. [[User:Jonas|Jonas]] ([[User talk:Jonas|talk]])<br />
* Test suite (make full TEST_FPC=/usr/local/bin/ppcx64) fails to complete with an error. See https://sentinel.sentry.org/mylog for the log file.<br />
** That's because a merge was missing, fixed. [[User:Jonas|Jonas]] ([[User talk:Jonas|talk]])<br />
<br />
* The file "Getting Started (Intel).rtf": It contains numerous references to very old details, which makes it long and hard to check, what is relevant to recent systems. I would replace most of that by a link to an according wiki page. It also says, that you cannot compile 64 bit GUI programs with Lazarus, without mentioning the cocoa, Qt4 and Qt5 64 bit variants of Lazarus. Please note that this text is also displayed at the start of the installation.<br />
** The details on how to use FPC with older (Mac) OS X/macOS versions will remain there as long as those OSes remain supported by FPC. I will update the Lazarus part. [[User:Jonas|Jonas]] ([[User talk:Jonas|talk]])<br />
*** In order to get rid of the overly dull and outdated impression, I suggest to reorder the points in better clarity with general ones first, followed by system version specific ones, from newest to oldest systems.<br />
<br />
* The file "readme.txt"<br />
** It still has 3.0.0 as version number at several places.<br />
** It mentions the GNU debugger and not lldb<br />
** Many feature are not really relevant for macOS or even not available.<br />
** The QuickStart has some minor outdated stuff.<br />
*** The readme file has not yet been updated for FPC 3.2, and is the same in all platform installers. macOS-specific things are in the Getting Started files. [[User:Jonas|Jonas]] ([[User talk:Jonas|talk]])<br />
<br />
* The file "whatsnew.txt"<br />
** News about 3.2.0 are missing<br />
*** This file has not yet been updated either. [[User:Jonas|Jonas]] ([[User talk:Jonas|talk]])<br />
<br />
* <s>not really a bug of fpc, but still a noteworthy issue: lazarus-cocoa does not build<br />
** fpc 3.2.0 comes with updated cocoa headers, which breaks building lazarus-cocoa. Bugtracker: https://bugs.freepascal.org/view.php?id=36864</s> (resolved with lazarus commits 62885 (trunk) and 62901 (fixies_2_0). Thanks to the Lazarus team.)<br />
*** That was because of a missing merge to 3.2.0. Those changes to Lazarus should be reverted again. [[User:Jonas|Jonas]] ([[User talk:Jonas|talk]])<br />
<br />
=== Linux ===<br />
As tested on Ubuntu20.04 beta but not specific.<br />
<br />
Testing instructions says run every binary. I am not familiar with all of them so I ran some with just '-h' as a parameter. All do have correct binary format but not all will accept that '-h', of those, most examined my '-h' and rejected it as an invalid parameter, thats OK. However -<br />
* <s>unitdiff - does not support -h, crashes with bad input. OK with good input.</s><br />
* mkx86ins - crashes with bad input.<br />
<br />
* The readme.txt, faq.txt and whatsnew.txt all refer to previous version being 3.0.0 not 3.0.4. Maybe this is as intended but, for example, the whatsnew does have specific content for 2.6.0, 2.6.2 and 2.6.4.<br />
<br />
* Ran the full test suite and produced results not dissimilar to those listed on https://www.freepascal.org/testsuite/cgi-bin/testsuite.cgi<br />
<br />
=== Go32v2 ===<br />
<br />
* The Go32v2 textmode IDE has no GDB due to builidng issues, reported by Pierre while uploading. Try to find old known working one?<br />
<br />
=== Win32 and possibly others ===<br />
<br />
* Does not ship pas2js binary, but does ship a pas2js units directory?<br />
* [https://forum.lazarus.freepascal.org/index.php/topic,49110.msg362517.html#msg362517 Forum post] Val procedure (and StrToFloat as well) fails with SIGFPE with Math.MaxDouble.<br />
* <s>$Unitpath directive doesn't work correctly. {{MantisLink|37095}}</s> Fixed in 45410, may or may not actually make it to 3.2.0.<br />
* An initial SetLength on a local managed array variable now causes a warning of uninitialized usage even though managed variables are always automatically initialized. Easy to work around but a nuisance, maybe should be mentioned in release notes if behavior is not changed. {{MantisLink|34169}}<br />
* <s>Can no longer get the address of an index of a function result string, without saving the result string into a variable first. Could be intentional. {{MantisLink|37098}}</s> This should never have worked in the first place, so it's more correct now.<br />
<br />
=== ISO mode ===<br />
* <s>Assigning a character to a file variable leads to a runtimes error 104, whereas trunk works. See https://bugs.freepascal.org/view.php?id=36902. </s> This has been fixed with commit 44301 to trunk and I expect that RC2 will have it.<br />
<br />
== Merge requests ==<br />
<br />
* r44127 needs to be merged to fix a Windows Registry {{MantisLink|36663}}.<br />
* r44179 should be merged: New Property EmptyImputRaisesError to avoid TRegExpr Error "empty input string" {{MantisLink|36603}}<br />
<br />
== Post RC1 merges ==<br />
<br />
<br />
[[Category:FPC Issues]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Packed/de&diff=118671Packed/de2018-08-02T21:43:26Z<p>Dirk Fellenberg: typo/spell fix</p>
<hr />
<div>{{packed}}<br />
<br><br />
Zurück zu den [[Reserved words/de|reservierten Wörtern]].<br><br />
<br><br />
Das reservierte Wort <b>packed</b> weist den Compiler an, für das Objekt sowenig Speicher wie möglich zu verwenden.<br><br />
Das wird dadurch erreicht, das zwischen einzelnen Elementen kein Zwischenraum gelassen wird.<br><br />
D. h. die einzelnen Elemente werden auch an ungeraden Speicheradressen ausgerichtet.<br><br />
<br><br />
Beispiel:<br><br />
<syntaxhighlight><br />
type TPArray = Packed array[...] of ...;<br />
type TPClass = Packed class ... end;<br />
type TPObject = Packed object ... end;<br />
type TPRecord = Packed record ... end;<br />
</syntaxhighlight><br />
<br><br />
<br><br />
<br />
Es ist auch bitweises Packen möglich, dies geschieht mit [[bitpacked]].<br><br />
Das Array '''a0''' ist ein Byte groß.<br><br />
Das normal deklarierte '''a1''' aber 8 Byte.<br />
<syntaxhighlight><br />
var<br />
a0: bitpacked array[0..7] of Boolean; // 1 Byte<br />
a1: array[0..7] of Boolean; // 8 Byte<br />
</syntaxhighlight></div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Case&diff=111901Case2017-09-13T14:25:18Z<p>Dirk Fellenberg: Link fixed</p>
<hr />
<div>{{Case}}<br />
<br />
The reserved word '''Case''' begins a ''case statement''. The case statement compares the value of either an enumerated type, an ordinal expression or a string, to each selector. The selector can be a [[Const|constant]], a subrange, or a list separated by [[Comma|commas]]. The selector field is separated from its related action(s) by a [[Colon]].<br />
<br />
The case statement also includes the [[Reserved word|reserved words]] [[Of]] and [[End]]. [[Else]] can be used when there is the possibility of no matches.<br />
<br />
<br />
<br />
<br />
=== Examples ===<br />
<br />
<syntaxhighlight><br />
case place of<br />
1: ShowMessage('Gold medal');<br />
2: ShowMessage('Silver medal');<br />
3: ShowMessage('Bronze medal'); <br />
else ShowMessage('Better luck next time'); <br />
end;<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight><br />
function WhatIsChar( c:char ):string;<br />
var<br />
s : string;<br />
begin<br />
s := '';<br />
case c of<br />
'0' .. '9' : s := 'digit (0-9)';<br />
'a' .. 'z' : s := 'lowercase letter (a-z)';<br />
'A' .. 'Z' : s := 'uppercase letter (A-Z)';<br />
'+' , '-' : s := 'sign (+ or -)';<br />
end;<br />
result := s;<br />
end;<br />
</syntaxhighlight><br />
<br />
== Case string ==<br />
<br />
The Free Pascal language allows you to "Case of" on a string variable.<br />
<br />
<syntaxhighlight><br />
const<br />
ISO_3166_1_ALPHA_3_ANDORRA = 'AND';<br />
ISO_3166_1_ALPHA_3_AUSTRALIA = 'AUS';<br />
ISO_3166_1_ALPHA_3_AUSTRIA = 'AUT';<br />
ISO_3166_1_ALPHA_3_BELGIUM = 'BEL';<br />
ISO_3166_1_ALPHA_3_BRAZIL = 'BRA';<br />
ISO_3166_1_ALPHA_3_CANADA = 'CAN';<br />
ISO_3166_1_ALPHA_3_CHINA = 'CHN';<br />
ISO_3166_1_ALPHA_3_CZECH_REPUBLIC = 'CZE';<br />
ISO_3166_1_ALPHA_3_CYPRUS = 'CYP';<br />
ISO_3166_1_ALPHA_3_GERMANY = 'DEU';<br />
ISO_3166_1_ALPHA_3_DENMARK = 'DNK';<br />
ISO_3166_1_ALPHA_3_SPAIN = 'ESP';<br />
ISO_3166_1_ALPHA_3_ESTONIA = 'EST';<br />
ISO_3166_1_ALPHA_3_FINLAND = 'FIN';<br />
ISO_3166_1_ALPHA_3_FRANCE = 'FRA';<br />
ISO_3166_1_ALPHA_3_GREECE = 'GRC';<br />
ISO_3166_1_ALPHA_3_INDIA = 'IND';<br />
ISO_3166_1_ALPHA_3_IRELAND = 'IRL';<br />
ISO_3166_1_ALPHA_3_ITALY = 'ITA';<br />
ISO_3166_1_ALPHA_3_JAPAN = 'JPN';<br />
ISO_3166_1_ALPHA_3_LITHUANIA = 'LTU';<br />
ISO_3166_1_ALPHA_3_LATVIA = 'LVA';<br />
ISO_3166_1_ALPHA_3_LUXEMBOURG = 'LUX';<br />
ISO_3166_1_ALPHA_3_MALTA = 'MLT';<br />
ISO_3166_1_ALPHA_3_MEXICO = 'MEX';<br />
ISO_3166_1_ALPHA_3_MONACO = 'MCO';<br />
ISO_3166_1_ALPHA_3_MONTENEGRO = 'MNE';<br />
ISO_3166_1_ALPHA_3_NAURU = 'NRU';<br />
ISO_3166_1_ALPHA_3_NETHERLANDS = 'NLD';<br />
ISO_3166_1_ALPHA_3_NORWAY = 'NOR';<br />
ISO_3166_1_ALPHA_3_POLAND = 'POL';<br />
ISO_3166_1_ALPHA_3_PORTUGAL = 'PRT';<br />
ISO_3166_1_ALPHA_3_REPUBLIC_OF_KOREA = 'KOR';<br />
ISO_3166_1_ALPHA_3_RUSSIAN_FEDERATION = 'RUS';<br />
ISO_3166_1_ALPHA_3_SAN_MARINO = 'SMR';<br />
ISO_3166_1_ALPHA_3_SLOVAKIA = 'SVK';<br />
ISO_3166_1_ALPHA_3_SLOVENIA = 'SVN';<br />
ISO_3166_1_ALPHA_3_SWEDEN = 'SWE' ;<br />
ISO_3166_1_ALPHA_3_SWITZERLAND = 'CHE';<br />
ISO_3166_1_ALPHA_3_UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND = 'GBR';<br />
ISO_3166_1_ALPHA_3_UNITED_STATES_OF_AMERICA = 'USA';<br />
<br />
<br />
ISO_4217_EURO = 'EUR';<br />
ISO_4217_AUSTRALIAN_DOLLAR = 'AUD';<br />
ISO_4217_BRAZILIAN_REAL = 'BRL';<br />
ISO_4217_CANADIAN_DOLLAR = 'CAD';<br />
ISO_4217_CHINESE_YUAN = 'CNY';<br />
ISO_4217_CZECH_KORUNA = 'CZK' ;<br />
ISO_4217_DANISH_KRONE = 'DKK' ;<br />
ISO_4217_INDIAN_RUPEE = 'INR';<br />
ISO_4217_POUND_STERLING = 'GBP' ;<br />
ISO_4217_JAPANESE_YEN = 'JPY';<br />
ISO_4217_MEXICAN_PESO = 'MXN';<br />
ISO_4217_NORWEGIAN_KRONE = 'NOK' ;<br />
ISO_4217_POLISH_ZLOTY = 'PLN' ;<br />
ISO_4217_RUSSIAN_RUBLE = 'RUB' ;<br />
ISO_4217_SOUTH_KOREAN_WON = 'KRW';<br />
ISO_4217_SWEDISH_KRONA = 'SEK' ;<br />
ISO_4217_SWISS_FRANC = 'CHF' ;<br />
ISO_4217_UNITED_STATES_DOLLAR = 'USD' ;<br />
<br />
function ISO_4217_currency_name ( ISO_3166_1_alpha_3_code: string): string;<br />
begin<br />
Case ISO_3166_1_alpha_3_code of<br />
// Eurozone<br />
ISO_3166_1_ALPHA_3_ANDORRA, ISO_3166_1_ALPHA_3_AUSTRIA,<br />
ISO_3166_1_ALPHA_3_BELGIUM,ISO_3166_1_ALPHA_3_CYPRUS,<br />
ISO_3166_1_ALPHA_3_GERMANY, ISO_3166_1_ALPHA_3_SPAIN,<br />
ISO_3166_1_ALPHA_3_ESTONIA, ISO_3166_1_ALPHA_3_FINLAND,<br />
ISO_3166_1_ALPHA_3_FRANCE, ISO_3166_1_ALPHA_3_GREECE,<br />
ISO_3166_1_ALPHA_3_IRELAND, ISO_3166_1_ALPHA_3_ITALY,<br />
ISO_3166_1_ALPHA_3_LITHUANIA, ISO_3166_1_ALPHA_3_LATVIA,<br />
ISO_3166_1_ALPHA_3_LUXEMBOURG, ISO_3166_1_ALPHA_3_MONACO,<br />
ISO_3166_1_ALPHA_3_MALTA, ISO_3166_1_ALPHA_3_MONTENEGRO,<br />
ISO_3166_1_ALPHA_3_NETHERLANDS, ISO_3166_1_ALPHA_3_PORTUGAL,<br />
ISO_3166_1_ALPHA_3_SAN_MARINO, ISO_3166_1_ALPHA_3_SLOVAKIA,<br />
ISO_3166_1_ALPHA_3_SLOVENIA : result := ISO_4217_EURO ;<br />
<br />
ISO_3166_1_ALPHA_3_AUSTRALIA, ISO_3166_1_ALPHA_3_NAURU :<br />
result := ISO_4217_AUSTRALIAN_DOLLAR;<br />
ISO_3166_1_ALPHA_3_BRAZIL : result := ISO_4217_BRAZILIAN_REAL;<br />
ISO_3166_1_ALPHA_3_CANADA : result := ISO_4217_CANADIAN_DOLLAR;<br />
ISO_3166_1_ALPHA_3_CHINA : result := ISO_4217_CHINESE_YUAN;<br />
ISO_3166_1_ALPHA_3_CZECH_REPUBLIC : result := ISO_4217_CZECH_KORUNA ;<br />
ISO_3166_1_ALPHA_3_DENMARK : result := ISO_4217_DANISH_KRONE ;<br />
ISO_3166_1_ALPHA_3_INDIA : result := ISO_4217_INDIAN_RUPEE;<br />
ISO_3166_1_ALPHA_3_JAPAN : result := ISO_4217_JAPANESE_YEN;<br />
ISO_3166_1_ALPHA_3_MEXICO : result := ISO_4217_MEXICAN_PESO;<br />
ISO_3166_1_ALPHA_3_NORWAY : result := ISO_4217_NORWEGIAN_KRONE ;<br />
ISO_3166_1_ALPHA_3_POLAND : result := ISO_4217_POLISH_ZLOTY ;<br />
ISO_3166_1_ALPHA_3_REPUBLIC_OF_KOREA : result := ISO_4217_SOUTH_KOREAN_WON ;<br />
ISO_3166_1_ALPHA_3_RUSSIAN_FEDERATION : result := ISO_4217_RUSSIAN_RUBLE ;<br />
ISO_3166_1_ALPHA_3_SWEDEN : result := ISO_4217_SWEDISH_KRONA ;<br />
ISO_3166_1_ALPHA_3_SWITZERLAND : result := ISO_4217_SWISS_FRANC ;<br />
ISO_3166_1_ALPHA_3_UNITED_KINGDOM_OF_GREAT_BRITAIN_AND_NORTHERN_IRELAND :<br />
result := ISO_4217_POUND_STERLING ;<br />
ISO_3166_1_ALPHA_3_UNITED_STATES_OF_AMERICA :<br />
result := ISO_4217_UNITED_STATES_DOLLAR ;<br />
end;<br />
end; <br />
</syntaxhighlight><br />
<br />
== Case Enumerator ==<br />
<br />
If you want to use enumerators, this example is very clear: <br />
<syntaxhighlight><br />
type<br />
TMedal = (mGold, mSilver, mBronze); // in case you want Gold to Start from 1, put this (Gold=1, ...but<br />
const<br />
MedalNames: array [TMedal] of string[6] = ('Gold', 'Silver', 'Bronze'); // in [TMedal], you have to change it to [Gold..Bronze] ;) suggestions to edgarrod71@gmail.com<br />
{[ ... ]}<br />
var<br />
place: integer; /// place starts from 0;<br />
M: TMedal;<br />
{[ ... ]}<br />
M := TMedal(place);<br />
case M of<br />
mGold: ShowMessage(Medalnames[M] + ' medal');<br />
mSilver: ShowMessage(Medalnames[M] + ' medal');<br />
mBronze: ShowMessage(Medalnames[M] + ' medal');<br />
else<br />
ShowMessage('Better luck next time! :)'); <br />
end;<br />
</syntaxhighlight><br />
<br />
Another example without MedalNames array...<br />
<br />
<syntaxhighlight><br />
type<br />
TMedal = (Gold, Silver, Bronze); // avoid the "m"<br />
{[ ... ]}<br />
var<br />
place: integer; /// place starts from 0;<br />
M: TMedal;<br />
S: string;<br />
{[ ... ]}<br />
M := TMedal(place);<br />
case M of<br />
Gold: writeStr(S, M);<br />
Silver: writeStr(S, M);<br />
Bronze: writeStr(S, M);<br />
else<br />
S := 'Better luck next time! ;)'; <br />
end;<br />
ShowMessage(S);<br />
</syntaxhighlight><br />
<br />
<br />
== Hexadecimal input ==<br />
<br />
If [[Hexadecimal|hexadecimal]] number are used, it is considered that they are unsigned:<br />
<br />
<syntaxhighlight><br />
case place of<br />
$1: ShowMessage('Gold medal');<br />
$2: ShowMessage('Silver medal');<br />
$3: ShowMessage('Bronze medal'); <br />
else ShowMessage('Better luck next time'); <br />
end;<br />
</syntaxhighlight><br />
<br />
<br />
If a hexadecimal is a different kind of a variable, for example Shortint, values shall be cast:<br />
<syntaxhighlight><br />
case place of<br />
Shortint($C3): ShowMessage('Gold medal'); //C3= -61;<br />
Shortint($34): ShowMessage('Silver medal');<br />
Shortint($58): ShowMessage('Bronze medal'); <br />
else ShowMessage('Better luck next time'); <br />
end;<br />
</syntaxhighlight><br />
or another solution can be used:<br />
<syntaxhighlight><br />
var<br />
myplace : ShortInt;<br />
place : Byte absolute myplace;<br />
begin<br />
myplace:=-61;<br />
case place of<br />
$C3: ShowMessage('Gold medal');<br />
$34: ShowMessage('Silver medal');<br />
$58: ShowMessage('Bronze medal');<br />
else ShowMessage('Better luck next time');<br />
end; <br />
</syntaxhighlight><br />
<br />
== Variant Record ==<br />
<br />
Case is used in Variant [[Record]], too. A Variant Record is also called a tagged union.<br />
<br />
<syntaxhighlight><br />
type<br />
<br />
ScaleKelvin = 223 .. 323;<br />
ScaleCelsius = -50 .. 50;<br />
<br />
TemperatureScale = ( celsius, kelvin ) ;<br />
Temperature = record<br />
case scale : TemperatureScale of<br />
celsius : (celsius_value : ScaleCelsius);<br />
kelvin : (kelvin_value : ScaleKelvin);<br />
end;<br />
</syntaxhighlight><br />
<br />
== See also ==<br />
* [http://www.freepascal.org/docs-html/ref/refsu56.html#x162-18400013.2.2 The Case statement]<br />
* [http://www.freepascal.org/docs-html/ref/refsu19.html#x43-500003.3.2 Record types]<br />
* [http://lazarus-ccr.sourceforge.net/pascal/pas3cb.html Tao Yue: Learn Pascal!] Case<br />
* [http://www.youtube.com/watch?v=pMr2xtUu3x0 Video: Free Pascal Tutorial 8 - Case Statements]<br />
* [[Dialog_Examples#ShowMessage|ShowMessage]]<br />
* [[Type]]<br />
<br />
<br />
[[Category:Pascal]]<br />
[[Category:Control Structures]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Streaming_JSON/de&diff=111331Streaming JSON/de2017-08-02T12:12:13Z<p>Dirk Fellenberg: typo fixed</p>
<hr />
<div>{{Streaming JSON}}<br />
<br />
[[JSON]] (JavaScript Object Notation) ist ein textbasiertes, standardisiertes Datenformat. Wie der Name sagt, sind JSON-Dokumente gültiger JavaScript-Code und können dort direkt in Objekte umgesetzt werden. An und für sich kann es aber zum Datenaustausch unabhängig von der verwendeten Programmiersprache verwendet werden.<br />
<br />
In diesem Tutorial wird erklärt, wie man JSON-Daten in ein Free-Pascal-Programm lädt um sie dort zu verarbeiten; Ebenso wird erklärt, wie man die Daten aus dem Programm in JSON konvertiert (um sie dann zum Beispiel an einen Webbrowser zu senden).<br />
<br />
== Allgemeines und Voraussetzungen ==<br />
<br />
Das Laden und Speichern von Objekten erfolgt mit der Unit [[fpjsonrtti]]. Weiterhin ist die Unit Classes sinnvoll (mehr dazu weiter unten im Abschnitt [[#Datenstruktur|Datenstruktur ?]]; Die [[Uses/de|uses]]-Anweisung sollte also mindestens diese beiden Units enthalten:<br />
<syntaxhighlight>uses Classes, fpjsonrtti;</syntaxhighlight><br />
<br />
<br />
Zum derzeitigen Zeitpunkt (Mai 2014) gibt es einige Unterschiede zum [[Streaming components/de|Streaming-Systems]] von Free Pascal:<br />
* JSON-Daten sind abhängig von Groß- und Kleinschreibung (case insensitive).[[#ref1|<sup>1</sup>]] Daraus folgt, dass die Eigenschaften der Free-Pascal-Objekte genau wie die JSON-Eigenschaften geschrieben werden müssen.<br />
* Es können keine Eigenschaften mit DefineProperties definiert werden; es können keine Referenzen auf Methoden (Event-Handler) gespeichert werden.[[#ref2|<sup>2</sup>]]<br />
* [[TCollection]] und [[TStrings]] können als Ersatz für Arrays verwendet werden.<br />
<br />
Mit den Quelltexten des Free-Pascal-Compilers wird im Verzeichnis <tt><fpc-quellen>/packages/fcl-json/examples/demortti.pp</tt> ein Demoprogramm mitgeliefert.<br />
<br />
Als Beispiel wird im Folgenden immer diese JSON-Struktur verwendet.<br />
<syntaxhighlight lang="JavaScript"><br />
{<br />
"id" : 123, // ein Integer<br />
"obj" : { "name": "Hallo Welt!" }, // ein Objekt<br />
"coll" : [ { "name": "Objekt 1" }, { "name": "Object 2" } ], // zwei Objekte in einer TCollection<br />
"strings": [ "Hallo 1", "Hallo 2" ] // eine String-Liste<br />
}<br />
</syntaxhighlight><br />
<br />
Im eigenen Programmquelltext kann sie so definiert werden:<br />
<syntaxhighlight><br />
const JSON_TESTDATA =<br />
'{'+LineEnding+<br />
' "id": 123,'+LineEnding+<br />
' "obj": { "name": "Hallo Welt!" },'+LineEnding+<br />
' "coll": [ { "name": "Objekt 1" }, { "name": "Objekt 2" } ],'+LineEnding+<br />
' "strings": [ "Hallo 1", "Hallo 2" ]'+LineEnding+<br />
'}';<br />
</syntaxhighlight><br />
<br />
== Datenstruktur ==<br />
<br />
Als Basisklasse für die Daten bietet sich [[TPersistent]] aus der Unit Classes an, da für sie und alle Unterklassen [[Runtime Type Information (RTTI)|Laufzeit-Typinformationen]] (<abbr title="Runtime Type Information">RTTI</abbr>) erstellt werden. Diese werden für das Streaming zwingend benötigt. Da sich ''fpjsonrtti'' nicht in das Streaming-System integriert, kann auch jede andere Klasse, die mit dem Compilerschalter <syntaxhighlight enclose="none">{$M+}</syntaxhighlight> übersetzt wurde, verwendet werden.<br />
<br />
Alle zu lesenden Eigenschaften müssen als [[Property/de|property]] im [[Published/de|published]]-Abschnitt der Klasse deklariert werden. In der Regel, kann hier mit read und write direkt auf ein Datenfeld (die Variable) verweisen werden. Wenn man möchte, können natürlich auch Getter- und Setter-Methoden verwendet werden.<br />
<br />
Aus der JSON-Struktur ergibt sich folgende Klassendefinition.<br />
<br />
<syntaxhighlight><br />
type<br />
TNameObject = class(TCollectionItem) // Klasse für die Eigenschaft 'obj' und die TCollection<br />
private<br />
fName: String;<br />
published<br />
property name: String read fName write fName;<br />
end; <br />
<br />
TBaseObject = class(TPersistent) // Klasse für die gesamte JSON-Struktur<br />
private<br />
fid: Integer;<br />
fObj: TNameObject;<br />
fColl: TCollection;<br />
fStrings: TStrings;<br />
public<br />
constructor Create;<br />
destructor Destroy; override;<br />
published // alle Eigenschaften müssen published sein<br />
property id: Integer read fid write fid;<br />
property obj: TNameObject read fObj write fObj;<br />
property coll: TCollection read fColl;<br />
property strings: TStrings read fStrings;<br />
end; <br />
</syntaxhighlight><br />
<br />
Die Klasse <syntaxhighlight enclose="none">TNameObject</syntaxhighlight> wurde von [[TCollectionItem]] abgeleitet. Damit kann sie sowohl für die Eigenschaft ''obj'' als auch in der Collection verwendet werden. Wenn dies nicht gewünscht ist, müssen hier zwei unterschiedliche Klassen definiert werden.<br />
<br />
Im Konstruktor der Klasse TBaseObject müssen die TCollection sowie die String-Liste erstellt und im Destruktor wieder freigegeben werden.<br />
<br />
<syntaxhighlight><br />
constructor TBaseObject.Create;<br />
begin<br />
// Collection und StringList erstellen<br />
fColl := TCollection.Create(TNameObject);<br />
fStrings := TStringList.Create;<br />
fObj := TNameObject.Create(nil);<br />
end;<br />
<br />
destructor TBaseObject.Destroy;<br />
begin<br />
// Collection und StringList wieder freigeben<br />
fColl.Free;<br />
fStrings.Free;<br />
fObj.Free;<br />
inherited Destroy;<br />
end;<br />
</syntaxhighlight><br />
<br />
Sofern Sie keine weitere Funktionalität in den Datenklassen haben möchten, ist ihre Definition bereits fertig.<br />
<br />
== JSON laden ==<br />
<br />
Mit der Methode <syntaxhighlight enclose="none">Procedure JSONToObject(Const JSON : TJSONStringType; AObject : TObject);</syntaxhighlight> der Klasse [[TJSONDeStreamer]] können Sie JSON-Daten direkt an ein ''vorhandenes'' Objekt zuweisen. Bevor Sie die Methode aufrufen, müssen Sie TJSONDeStreamer und das Ziel-Objekt erstellen.<br />
<br />
Die folgende Methode lädt die Daten aus der JSON-Struktur <syntaxhighlight enclose="none">JSON_TESTDATA</syntaxhighlight> in das Objekt o und gibt die aktuellen Werte der Eigenschaften danach auf der Konsole aus.<br />
<br />
<syntaxhighlight><br />
procedure DeStreamTest;<br />
var<br />
DeStreamer: TJSONDeStreamer;<br />
o: TBaseObject;<br />
no: TNameObject;<br />
s: String;<br />
begin<br />
WriteLn('DeStream test');<br />
WriteLn('======================================');<br />
<br />
// DeStreamer-Objekt und Ziel-Objekt erstellen<br />
DeStreamer := TJSONDeStreamer.Create(nil);<br />
o := TBaseObject.Create;<br />
try<br />
// JSON-Daten in das Objekt o laden<br />
DeStreamer.JSONToObject(JSON_TESTDATA, o);<br />
// ID ausgeben<br />
WriteLn(o.id);<br />
// Objekt-Name ausgeben<br />
WriteLn(o.obj.name); <br />
// alle Namen der Objekte ausgeben<br />
for TCollectionItem(no) in o.coll do<br />
Writeln(no.name);<br />
// alle Strings ausgeben<br />
for s in o.strings do<br />
WriteLn(s);<br />
<br />
// aufräumen<br />
finally<br />
o.Destroy;<br />
DeStreamer.Destroy;<br />
end;<br />
end;<br />
</syntaxhighlight><br />
<br />
== JSON speichern ==<br />
<br />
Um ein Objekt in einen JSON-Text zu überführen, wird die Klasse [[TJSONStreamer]] verwendet. Hier wird die Methode <syntaxhighlight enclose="none">Function ObjectToJSONString(AObject : TObject) : TJSONStringType;</syntaxhighlight> verwendet.<br />
<br />
In der folgenden Prozedur wird ein Objekt erstellt, mit den Testdaten befüllt und anschließend nach JSON überführt. Der JSON-Text wird auf der Konsole ausgegeben. Es kann nicht festgelegt werden, in welcher Reihenfolge die Eigenschaften ausgeben werden<br />
<br />
<syntaxhighlight><br />
procedure StreamTest;<br />
var<br />
Streamer: TJSONStreamer;<br />
o: TBaseObject;<br />
JSONString: String;<br />
begin<br />
WriteLn('Stream test');<br />
WriteLn('======================================');<br />
<br />
Streamer := TJSONStreamer.Create(nil);<br />
o := TBaseObject.Create;<br />
try<br />
// Daten festlegen<br />
o.id := 123;<br />
o.obj.name := 'Hallo Welt!';<br />
TNameObject(o.coll.Add).name := 'Objekt 1';<br />
TNameObject(o.coll.Add).name := 'Objekt 2';<br />
o.strings.Add('Hallo 1');<br />
o.strings.Add('Hallo 2');<br />
<br />
Streamer.Options := Streamer.Options + [jsoTStringsAsArray]; // Strings als JSON-Array ausgeben<br />
// nach JSON überführen und ausgeben<br />
JSONString := Streamer.ObjectToJSONString(o);<br />
WriteLn(JSONString);<br />
<br />
// aufräumen<br />
finally<br />
o.Destroy;<br />
Streamer.Destroy;<br />
end;<br />
end;<br />
</syntaxhighlight><br />
<br />
== Ausblick ==<br />
<br />
Mit dem vorgestellten Wissen können einfache und komplexe JSON-Datenstrukturen in Free Pascal geladen werden. Sollte eine Vor- oder Nachbearbeitung der JSON-Daten notwendig sein, können die Textdaten zunächst mit der Klasse [[TJSONParser]] aus der Unit [[jsonparser]] in eine JSON-Datenstruktur geladen werden und dann mit der Unit [[fpJSON]] beliebig manipuliert werden.<br />
<br />
Über die Eigenschaft Options der Klasse TJSONStreamer kann gesteuert werden, wie die Ausgabe die eigenen Datenstrukturen in JSON abgebildet werden.<br />
<br />
== Siehe auch ==<br />
* [[JSON]]<br />
* [[fcl-json]]<br />
* [[Streaming components/de]]<br />
<br />
== Einzelnachweise ==<br />
# <div id="ref1">http://lists.freepascal.org/fpc-pascal/2013-January/036254.html</div><br />
# <div id="ref2>http://lists.lazarus.freepascal.org/pipermail/lazarus/2011-January/058878.html</div><br />
<br />
[[Category:Tutorials/de]]<br />
[[Category:JSON/de]]<br />
[[Category:Deutsch]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=pas2jni&diff=103620pas2jni2016-08-22T13:48:22Z<p>Dirk Fellenberg: typo fixed</p>
<hr />
<div>=Overview=<br />
<br />
The '''pas2jni''' utility generates a JNI (Java Native Interface) bridge for a Pascal code. Then the Pascal code (including classes and other advanced features) can be easily used in Java programs.<br />
<br />
For example you can do the following in Java:<br />
<br />
<code><pre><br />
import pas.classes.*;<br />
<br />
...<br />
<br />
TStringList sl = TStringList.Create();<br />
sl.Add("Hello.");<br />
String s = sl.getStrings(0);<br />
sl.Free();<br />
<br />
...<br />
</pre></code><br />
<br />
The following Pascal features are supported by '''pas2jni''':<br />
<br />
* function/procedure;<br />
* var/out parameters;<br />
* class;<br />
* record;<br />
* property;<br />
* constant;<br />
* enum;<br />
* set;<br />
* TGuid type;<br />
* pointer type;<br />
* string types;<br />
* all numeric types;<br />
* method pointer;<br />
* setters/getters for array elements.<br />
<br />
'''USUPPORTED features:'''<br />
* Full support for arrays;<br />
* procedure pointer (Not possible to implement. To workaround this limitation create a procedure handler in your Pascal code and call a method pointer declared in some global Pascal class. Then you can assign this method pointer from a Java code).<br />
<br />
Shared libraries, generated by pas2jni were tested with Java on Windows and Android. It should work on other systems as well.<br />
<br />
=How to use=<br />
<br />
'''pas2jni''' uses the [[PPUDump]] utility included with Free Pascal Compiler to read unit interfaces. Therefore your Pascal code must be first compiled with FPC.<br />
When your units are compiled, you can run '''pas2jni'''. You need to specify a list of main units and units search path. <br />
When you specify a main unit, all its interface declarations will be available in Java. For linked units only used declarations will be available. You can fine tune included/excluded declaration using <code>-I</code> and <code>-E</code> command line options.<br />
<br />
The basic invocation of '''pas2jni''':<br />
<br />
pas2jni myunit -U/path/to/my/units;/path/to/FPC/units/*<br />
<br />
Here you specify myunit as the main unit and provide path to your compiled units and FPC compiled units. <br />
<br />
After successfull run of '''pas2jni''' you will get the following output files:<br />
* file <code>'''myunitjni.pas'''</code> - a generated library unit to be compiled to a shared library. It will contain all your Pascal code to be used from Java.<br />
* folder <code>'''pas'''</code> - generated Java package <code>'''pas'''</code> to be used in your Java program. Interface to each Pascal unit is placed to a separate Java public class. <br />
<br />
Note: You need to use '''ppudump''' of the same version as the FPC compiler. Use the <code>-D</code> switch to specify correct '''ppudump''' if it is not in <code>PATH</code>.<br />
<br />
=Custom handlers=<br />
<br />
It is possible to define the following custom handlers in your Pascal code.<br />
<br />
<code>'''procedure JNI_OnException;'''</code><br />
* It is called when an unhandled Pascal exception occurs. For example, you can log a stack back trace in this handler.<br />
<br />
Custom handlers must be public and defined in one of the main units specified when calling '''pas2jni'''.<br />
<br />
=Coding tips=<br />
<br />
==Setting handlers (method pointers) in a Java code.==<br />
<br />
For example there is the following event handler in your Pascal code:<br />
<br />
<code><pre><br />
TMyClass = class<br />
...<br />
property OnChange: TNotifyEvent;<br />
...<br />
end;<br />
</pre></code><br />
<br />
In a Java code you get the following <code>TMyClass</code> instance:<br />
<br />
TMyClass myclass = TMyClass.Create();<br />
<br />
Then you add the event handler in a usual Java way:<br />
<br />
<code><pre><br />
...<br />
myclass.setOnChange(<br />
new TNotifyEvent() {<br />
protected void Execute(TObject Sender) {<br />
// The handler code<br />
}<br />
}<br />
);<br />
...<br />
</pre></code><br />
<br />
=Command line options=<br />
<br />
<code><pre><br />
Usage: pas2jni [options] <unit> [<unit2> <unit3> ...]<br />
<br />
Options:<br />
-U<path> - Unit search path, semicolon delimited. Wildcards are allowed.<br />
-L<name> - Set output library name.<br />
-P<name> - Set Java package name.<br />
-O<path> - Set output path for Pascal files.<br />
-J<path> - Set output path for Java files.<br />
-D<prog> - Set full path to the "ppudump" program.<br />
-I<list> - Include the list of specified objects in the output. The list is<br />
semicolon delimited. To read the list from a file use -I@<file><br />
-E<list> - Exclude the list of specified objects from the output. The list is<br />
semicolon delimited. To read the list from a file use -E@<file><br />
-? - Show this help information.<br />
</pre></code><br />
<br />
[[Category:FPC]]<br />
[[Category:Utilities]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=User_Changes_3.0&diff=97964User Changes 3.02015-11-26T08:20:58Z<p>Dirk Fellenberg: FPC version 3.0.0 has been released.</p>
<hr />
<div>{{User Changes 3.0}}<br />
<br />
== About this page==<br />
<br />
Listed below are intentional changes made to the FPC compiler (3.0) since the [[User_Changes_2.6.4|previous release]] that may break existing code. The list includes reasons why these changes have been implemented, and suggestions for how you might adapt your code if you find that previously working code has been adversely affected by these recent changes. <br />
<br />
== All systems ==<br />
<br />
=== Implementation changes ===<br />
<br />
==== Exception type for object reference checking changed ====<br />
* '''Old behaviour''': When object reference checking (''-CR'' or ''{$OBJECTCHECKS ON}'') is enabled and the unit ''SysUtils'' is used then an exception of class ''Exception'' with localizeable message ''Unknown runtime error 210'' is created.<br />
* '''New behaviour''': Now an exception of class ''EObjectCheck'' with localizeable message ''Object reference is Nil'' is created.<br />
* '''Reason''': All other runtime errors in the 2xx range have appropriate exception types, so it is only natural to have an explicit type for runtime error 210 as well.<br />
* '''Remedy''': If your code previously checked an exception for the message ''Unknown runtime error 210'' you should now check for the exception class ''EObjectCheck''.<br />
<br />
==== Literal storage memory has been made read-only ====<br />
<br />
* '''Old behaviour''': read-only data segments were ''de facto'' not supported, and all data could be modified at runtime even if it was not intended for modification (except in some cases on Darwin). This could cause nasty side-effects, e.g the following code:<br />
<br />
<syntaxhighlight><br />
uses sysutils;<br />
var<br />
s: ansistring;<br />
begin<br />
s := 'ansi string';<br />
Writeln(AnsiStrUpper(pchar(s)));<br />
s := 'ansi string';<br />
Writeln(s);<br />
end.<br />
</syntaxhighlight><br />
<br />
would modify the contents of data segment and print<br />
<br />
ANSI STRING<br />
ANSI STRING<br />
<br />
* '''New behaviour''': Data that is not intended to be modified at runtime is put into a read-only segment. This includes literal constants used in expressions and typed constants declared in {$J-} state. Any code which modifies such data (as in the above example) will now crash.<br />
* '''Reason''': This is consistent with the way other compilers (including Delphi) work. Keeping data read-only as much as possible improves a program's loading speed because read-only pages can be mapped directly to the executable file. This also improves program security.<br />
* '''Remedy''': is very code-dependent. In the example above, it is sufficient to call <tt>UniqueString(s)</tt> before <tt>AnsiStrUpper</tt><br />
<br />
==== ''UNICODE'' define depends on default string type instead of on target platform ====<br />
* '''Old behaviour''': The compiler defined the preprocessor symbol ''UNICODE'' when targeting a Windows platforms that only has a unicode OS API (Windows CE and NativeNT).<br />
* '''New behaviour''': The ''UNICODE'' define is now only set if the default string type is ''unicodestring'' (as opposed to ''shortstring'' or ''ansistring''). This happens when the new ''{$mode delphiunicode}'' or ''{$modeswitch unicodestrings}'' are active. The target platform no longer has any influence.<br />
* '''Reason''': In Delphi 2009 and newer the type ''String'' is defined as ''UnicodeString'', and this can be determined by the fact that these Delphi versions also define the ''UNICODE'' symbol.<br />
* '''Remedy''': Use ''{$ifdef FPC_OS_UNICODE}'' instead of ''{$ifdef UNICODE}'' to determine whether or not the OS only supports a unicode (UTF-16) API.<br />
<br />
=== RTTI changes ===<br />
<br />
==== RTTI for Pointers and Class References ====<br />
* '''Old behavior''': Pointers and Class References had tkUnknown RTTI.<br />
* '''New behavior''': Pointers now have RTTI type tkPointer, and class references have the RTTI type tkClassRef. Each now contains a reference to a type they point to.<br />
* '''Reason''': Both user requests and Delphi compatibility.<br />
* '''Remedy''': The TTypeKind enumeration has more members than before. Adjust any code which uses TTypeKind accordingly.<br />
<br />
==== RTTI for AnsiStrings ====<br />
* '''Old behavior''': AnsiString RTTI previously lacked CodePage information.<br />
* '''New behavior''': A new CodePage member has been added for the tkAString type.<br />
* '''Reason''': This is required for serializing/deserializing of published AnsiString properties, and is now compatible with Delphi.<br />
* '''Remedy''': not known<br />
<br />
==== RTTI for Arrays ====<br />
* '''Old behavior''': tkArray had no member in the TTypeData record, although internally the compiler stored these members: first dimension size, first dimension element count and first dimension element type. So for a 2 dimension array element the type was array for the second dimension.<br />
* '''New behavior''': tkArray now has a TArrayTypeData structure in TTypeData. It has the following members: total array size including all dimensions, total element count, last dimension element type, number of dimensions, type information for each dimension range.<br />
* '''Reason''': This provides more comprehensive RTTI, and is compatible with Delphi.<br />
* '''Remedy''': If your code internally used the older RTTI array information you will need to adapt it to take account of the newly provided TArrayTypeData information.<br />
<br />
==== RTTI for Records ====<br />
* '''Old behavior''': Records RTTI stored field Offsets as 32bit integers.<br />
* '''New behavior''': Records RTTI stores field Offsets as platform-dependent integers (the same size as pointers).<br />
* '''Reason''': Internally the compiler stores Offsets as platform-dependent integers. The new behaviour is Delphi-compatibile.<br />
* '''Remedy''': You need to adjust your code if you used field offsets of record RTTI. This is also true if your code processes any vInitTable field within the VMT of a class.<br />
<br />
==== RTTI for Procedural Variables ====<br />
* '''Old behavior''': tkProcVar lacked any member in the TTypeData record and the compiler stored no information about procedural variables.<br />
* '''New behavior''': tkProcVar now has a new TProcedureSignature structure in TTypeData which contains information about the procedure's calling convention, result type and parameters (where applicable).<br />
* '''Reason''': User request. More informative RTTI. Delphi compatibility.<br />
* '''Remedy''': not known<br />
<br />
===== Usage example =====<br />
<syntaxhighlight><br />
program RTTIInfo;<br />
<br />
{$mode objfpc}{$H+}<br />
uses<br />
typinfo;<br />
<br />
type<br />
CP866String = type AnsiString(866);<br />
TProc = procedure(var A: Integer; S: String); stdcall;<br />
TColor = (red, green, blue);<br />
TArr = array[TColor,0..3] of Integer;<br />
PArr = ^TArr;<br />
<br />
procedure DescribeProcedure(Info: PTypeInfo);<br />
const<br />
ParamFlagToStr: array[TParamFlag] of AnsiString = (<br />
'var',<br />
'const',<br />
'array',<br />
'address',<br />
'reference',<br />
'out'<br />
);<br />
CallConvToStr: array[TCallConv] of AnsiString = (<br />
'register',<br />
'cdecl',<br />
'pascal',<br />
'stdcall',<br />
'safecall',<br />
'cppdecl',<br />
'far16',<br />
'oldFPCcall',<br />
'internProc',<br />
'SysCall',<br />
'SoftFloat',<br />
'MWPascal'<br />
);<br />
var<br />
Data: PTypeData;<br />
Param: PProcedureParam;<br />
ParamFlag: TParamFlag;<br />
I: Integer;<br />
Res, S, TypeName: String;<br />
begin<br />
if Info^.Kind <> tkProcedure then<br />
Exit;<br />
Data := GetTypeData(Info);<br />
if Data^.ProcSig.CC <> ccStdCall then<br />
halt(2);<br />
if Data^.ProcSig.ResultType <> nil then<br />
begin<br />
Res := 'function ' + Info^.Name;<br />
TypeName := ': ' + Data^.ProcSig.ResultType^.Name;<br />
end<br />
else<br />
begin<br />
Res := 'procedure ' + Info^.Name;<br />
TypeName := '';<br />
end;<br />
if Data^.ProcSig.ParamCount > 0 then<br />
begin<br />
Res := Res + '(';<br />
for I := 0 to Data^.ProcSig.ParamCount - 1 do<br />
begin<br />
Param := Data^.ProcSig.GetParam(I);<br />
S := '';<br />
for ParamFlag in TParamFlags(Param^.Flags) do<br />
S := S + ParamFlagToStr[ParamFlag] + ' ';<br />
S := S + Param^.Name + ': ' + Param^.ParamType^.Name;<br />
if I > 0 then<br />
Res := Res + '; ';<br />
Res := Res + S;<br />
end;<br />
Res := Res + ')';<br />
end;<br />
Res := Res + TypeName + '; ' + CallConvToStr[Data^.ProcSig.CC] + ';';<br />
WriteLn(Res);<br />
end;<br />
<br />
procedure DescribeAnsiString(Info: PTypeInfo);<br />
var<br />
Data: PTypeData;<br />
begin<br />
if Info^.Kind <> tkAString then<br />
Exit;<br />
Data := GetTypeData(Info);<br />
if Data^.CodePage = 0 then<br />
WriteLn('AnsiString')<br />
else<br />
WriteLn('type AnsiString(',Data^.CodePage,');');<br />
end;<br />
<br />
procedure DescribeArray(Info: PTypeInfo);<br />
var<br />
Data: PTypeData;<br />
Res: String;<br />
I: Integer;<br />
begin<br />
if Info^.Kind <> tkArray then<br />
Exit;<br />
Data := GetTypeData(Info);<br />
Res := 'array[';<br />
for I := 0 to Data^.ArrayData.DimCount - 1 do<br />
begin<br />
if I > 0 then<br />
Res := Res + ', ';<br />
Res := Res + Data^.ArrayData.Dims[I]^.Name;<br />
end;<br />
Res := Res + '] of ' + Data^.ArrayData.ElType^.Name + ';';<br />
WriteLn(Res);<br />
end;<br />
<br />
procedure DescribePointer(Info: PTypeInfo);<br />
var<br />
Data: PTypeData;<br />
begin<br />
if Info^.Kind <> tkPointer then<br />
Exit;<br />
Data := GetTypeData(Info);<br />
if Data^.RefType = nil then<br />
WriteLn('Pointer;')<br />
else<br />
WriteLn('^', Data^.RefType^.Name, ';');<br />
end;<br />
<br />
begin<br />
DescribeProcedure(TypeInfo(TProc));<br />
DescribeAnsiString(TypeInfo(CP866String));<br />
DescribeArray(TypeInfo(TArr));<br />
DescribePointer(TypeInfo(PArr));<br />
DescribePointer(TypeInfo(Pointer));<br />
end.<br />
</syntaxhighlight><br />
<br />
=== Unit changes ===<br />
<br />
==== DB ====<br />
===== TBookmark TBookmarkstr and TDataset.Bookmark change to Delphi2009+ compatible definitions =====<br />
* '''Old behaviour''': TDataset.Bookmark was of type TBookmarkstr, TBookmarkstr=string, Tbookmark=pointer<br />
* '''New behaviour''': TDataset.Bookmark is of type TBookmark, TBookmarkstr=ansistring, TBookmark=TBytes. TBookmarkstr will trigger a deprecated warning.<br />
* '''Reason''': D2009+ compatibility, where probably the fact that string became a 2-byte encoding was the trigger.<br />
* '''Remedy''': Adjust typing in descendents and using code accordingly.<br />
<br />
===== TBufDataset.SaveToFile, SaveToStream: Binary Format (dfBinary) of saved data changes =====<br />
* '''Old behaviour''': Record data was saved to stream just as they exist in the TBufDataset memory record buffer.<br />
* '''New behaviour''': Record data are saved field by field. Each variable length field begins with a 4 byte length indicator followed by data. Fixed length fields are stored without prefixed length indicator. LoadFromFile, LoadFromStream support both formats (OLD and NEW).<br />
* '''Reason''': BLOBs were not saved correctly in the OLD format: instead of BLOB data, a pointer to memory where BLOB data resided was saved.<br />
* '''Remedy''': if you need the OLD behavior in saving, you must register your own DataPacketReader using RegisterDatapacketReader procedure.<br />
<syntaxhighlight><br />
unit OldBinaryDatapacketReader;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
interface<br />
<br />
uses<br />
Classes, SysUtils, BufDataset;<br />
<br />
type<br />
<br />
{ TOldFpcBinaryDatapacketReader }<br />
<br />
TOldFpcBinaryDatapacketReader = class(TFpcBinaryDatapacketReader)<br />
public<br />
constructor Create(AStream : TStream); override;<br />
end;<br />
<br />
implementation<br />
<br />
{ TOldFpcBinaryDatapacketReader }<br />
<br />
constructor TOldFpcBinaryDatapacketReader.Create(AStream: TStream);<br />
begin<br />
inherited;<br />
FVersion := 10;<br />
end;<br />
<br />
initialization<br />
RegisterDatapacketReader(TOldFpcBinaryDatapacketReader, dfBinary);<br />
end.<br />
</syntaxhighlight><br />
<br />
===== TDataPacketReader class structure changes =====<br />
* '''Old behaviour''': <br />
* '''New behaviour''': reference to TCustomBufDataset is passed only once in constructor of TDataPacketReader and stored in instance TDataPacketReader.<br />
* '''Reason''': simplify design and make it more flexible<br />
* '''Remedy''': if you use your own TDataPacketReader descendant update method signatures<br />
<br />
===== TSQLScript supports :, backtick quotes and explicit COMMIT/COMMIT RETAIN =====<br />
* '''Old behaviour''': <br />
** [[TSQLScript]] parsed words starting with : in SQL as if they were sqldb parameters; running the resulting statements would very likely fail, making the class unusable.<br />
** With UseCommit set, once a COMMIT directive was found, CommitRetaining is run instead of Commit. This lead to problems with scripts that need a hard commit (e.g. Firebird DDL followed by DML).<br />
** TSQLScript did not support backtick quotes (`), e.g. for MySQL<br />
* '''New behaviour''': <br />
* Parser improvement: comments starting with -- are detected as comments<br />
** words starting with : are not parsed as sqldb parameters.<br />
** if UseCommit is set, COMMIT WORK or COMMIT leads to Commit; the new directive COMMIT RETAIN (or no directive) leads to CommitRetaining being executed<br />
** TSQLScript supports backtick quotes (`), e.g. for MySQL<br />
* '''Reason''': usability, compatibility with scripts generated by 3rd party packages.<br />
* '''Remedy''': <br />
** if your code depended on : parameter parsing, you could use a TSQLEventScript class and manipulate the SQL. <br />
** commit behaviour: check your scripts for any unexpected COMMIT RETAIN statements.<br />
<br />
===== TMySQLxxConnection (mysqlconn.inc) VARCHAR columns are always mapped to TStringFields =====<br />
* '''Old behaviour''': varchar columns with length > 8192 (dsMaxStringSize) were re-mapped to TMemoFields<br />
* '''New behaviour''': varchar columns are always mapped to TStringFields<br />
* '''Reason''': Honour server definition and map column data types as reported by server<br />
* '''Remedy''': If you use varchar with length > 8192 and you have field definitions stored in lfm, update them.<br />
<br />
===== TSQLite3Connection INTEGER PRIMARY KEY columns are mapped to TAutoIncFields =====<br />
* '''Old behaviour''': INTEGER columns, which are also PRIMARY KEY were mapped to TIntegerField<br />
* '''New behaviour''': INTEGER columns, which are also PRIMARY KEY are now mapped to TAutoIncField<br />
* '''Reason''': Tables with INTEGER columns, which are also PRIMARY KEY are in SQLite alias for ROWID. And ROWID columns have autoincrement capability. For more details see: http://www.sqlite.org/lang_createtable.html#rowid and http://www.sqlite.org/autoinc.html<br />
* '''Remedy''':<br />
<br />
===== TSQLite3Connection: Boolean True values are stored as 1 not as -1 =====<br />
* '''Old behaviour''': Boolean True parameters was bind as integer = -1.<br />
* '''New behaviour''': Boolean True parameters are bind as integer = 1. As expected by SQLite: "SQLite does not have a separate Boolean storage class. Instead, Boolean values are stored as integers 0 (false) and 1 (true)."<br />
* '''Reason''': Align with SQLite specification and also with others DB components (like SQLite3DataSet), which expect True=1<br />
* '''Remedy''': Check your applications and if your tables contain boolean columns which are part of primary key or you use in WHERE clause constructs like "boolean_column=:boolean_param" then you must take attention to fix database or use construct like: "ABS(boolean_column)=:boolean_param"<br />
<br />
==== FileNameCaseSensitive and FileNameCasePreserving in unit System ====<br />
* '''Old behaviour''': There was only one constant (FileNameCaseSensitive) which signalized behaviour of the respective target platform with regard to the case in filenames. This was often set to true also on platforms not really treating filenames in case sensitive manner (e.g. Win32 and Win64).<br />
* '''New behaviour''': FileNameCaseSensitive is set to true only on platforms which really treat filenames in case sensitive manner and FileNameCasePreserving constant is added to unit system of all platforms to signalize whether the case in filenames supplied when creating or renaming them is preserved or not. This might possibly break existing user code relying on the previous (sometimes incorrect) value of FileNameCaseSensitive.<br />
* '''Reason''': In reality, there are two distinct types of behaviour. If a platform is case sensitive, searching for file "a" will never result in finding file "A" whereas case insensitive platform will happily return "A" if such a file is found on the disk. If a platform is case preserving, it will store file "a" as "a" on disk whereas case non-preserving platform may convert the filenames to uppercase before storing them on disk (i.e. file "a" is in reality stored as "A"). Case non-preserving platforms are never case sensitive, but case preserving platforms may or may not be case sensitive at the same time.<br />
* '''Remedy''': Review your existing code using FileNameCaseSensitive, check which of the two properties described above fit the particular purpose in your case and change to FileNameCasePreserving where appropriate.<br />
<br />
==== Some longtime deprecated functions in unit Unix have been removed. ====<br />
* '''Old behaviour''': Unix.(f)statfs, Unix.shell and Unix.fsync symbols existed in unit Unix <br />
* '''New behaviour''': Unix.(f)statfs, Unix.shell and Unix.fsync were removed<br />
* '''Reason''': These were helper functions and leftovers from the 1.0.x->2.0.0 conversion, deprecated since 2007. Shell had non standarized conventions<br />
* '''Remedy''': All but shell: use the same functions with an "fp" prefix. Shell: use fpsystem. If you checked the return value for other values than -1, a modification of the error checking might be necessary. Refer to your *nix documention, or have a look at the transformfpsystemtoshell function in tests/util/redir.pp in the FPC sources to see what a quick fix looks like.<br />
<br />
==== statfs has been renamed to fpstatfs ====<br />
* '''Old behaviour''': One overload of fpstatfs was not renamed from statfs to fpstatfs (around 2.4.0)<br />
* '''New behaviour''': The function has been renamed.<br />
* '''Reason''': Should have been done in 2.4.0 to begin with, but was postponed several times to coincide with a major version change. <br />
* '''Remedy''': Use fpstatfs<br />
<br />
==== RTLeventsync has been removed ====<br />
* '''Old behaviour''': The thread manager record contained an ''rtleventsync'' field, and the RTL had an ''RTLeventsync'' routine. No functionality for this routine was implemented in the FPC-supplied thread manager for any platform.<br />
* '''New behaviour''': The field and routine have been removed.<br />
* '''Reason''': The functionality was not available on any platform by default, and we're not aware of any third party thread manager that implemented them or third party code that relied on it. Additionally, the routine was documented as "Obsolete. Don't use.", without any explanation of what it was supposed to do.<br />
* '''Remedy''': Remove any such calls from your code.<br />
<br />
==== TVersionInfo (fileinfo unit) re-implemented in a platform independent way ====<br />
* '''Old behaviour''': GetVersionSetting method would read file information.<br />
* '''New behaviour''': The ReadFileInfo call will read the information. The global GetProgramVersion call will extract the program major/minor/revision/build version in 1 single call.<br />
* '''Reason''': The unit now uses FPC resources on all platforms, and can now be used to read external resources.<br />
* '''Remedy''': Use the ReadFileInfo call to get the version information. Add relevant units for desired resource support to your uses clause; e.g. if you need to read Windows .exe file info, add winpeimagereader<br />
<br />
==== shlobj symbols removed from unit Windows ==== <br />
* '''Old behaviour''': When unit windows was split between the windows and shlobj units, not all shlobj symbols were removed from Windows. <br />
* '''New behaviour''': shlobj symbols has been removed from the windows unit. Code relying on that will fail to compile if it doesn't import shlobj.<br />
* '''Reason''': shlobj and windows versions were not compatible and lead to errors. <br />
* '''Remedy''': put shlobj in your uses clause, if not there already.<br />
<br />
==== process OnForkEvent implementation ====<br />
* '''Old behaviour''': Signature was a simple procedure. <br />
* '''New behaviour''': TNotifyEvent -compatible signature for the call. <br />
* '''Reason''': It was impossible to know the TProcess instance for which the fork was called, and hence impossible to parametrize the procedure.<br />
* '''Remedy''': Change the signature of your callback to match a TNotifyEvent<br />
<br />
==== Extention -> Extension typo fix ====<br />
* '''Old behaviour''': The incorrect term Extention (typo) was used in the interface of several units: fpimage, sndfile.<br />
* '''New behaviour''': The correct term Extension is now used.<br />
* '''Reason''': Why have code with incorrect English?<br />
* '''Remedy''': Change extention to extension.<br />
<br />
==== SysUtils: File names starting with a period are not considered to be extensions ====<br />
* '''Old behaviour''': File names that start with a period were considered to only have an extension and no base file name by <code>ExtractFileExt()</code> and <code>ChangeFileExt()</code><br />
* '''New behaviour''': By default, the portion of the filename starting with the period up till the next period (if any) or end of the file name is now considered to be the file name, and the rest is considered by the extension. Note that this behaviour is '''not''' Delphi-compatible.<br />
* '''Reason''': Change behaviour to match file system/OS conventions.<br />
* '''Remedy''': There is a new a variable <code>FirstDotAtFileNameStartIsExtension</code>. By default, it is set to ''false'', which corresponds to the new behaviour. If it is set to ''true'', the aforementioned routines revert to the old behaviour.<br />
==== System: Error messages are now written to stderr ====<br />
* '''Old behaviour''': On error, the binaries halted and wrote an error message to standard output. <br />
* '''New behaviour''': On error, the binaries halt and write an error message to standard error . <br />
* '''Reason''': Change behaviour to match OS conventions. Diagnostic output should be written to standard error.<br />
* '''Remedy''': A system unit variable WriteErrorsToStdErr can be set to 'False' and then the output is written to standard output, as it was.<br />
<br />
==== TZipper: writes zip files with zip standard / instead of \ directory separators ====<br />
* '''Old behaviour''': on Windows (only), TZipper would write \ to the zip file when paths were used. This does not conform to the zip standard though many utilities would accept this. However, it is not according to the standard and leads to problems with e.g. LibreOffice reading .xlsx files generated by fpspreadsheet.<br />
* '''New behaviour''': TZipper writes / when paths are used; it still accepts \ for reading on Windows. Note: on Windows, TZipper still accepts / as path separator when reading zip files for compatibility with buggy third party code.<br />
* '''Reason''': standards compliance, interoperability.<br />
* '''Remedy''': if you need to interoperate with 3rd party tools that require zip files with \, please copy all code in \packages\paszlib\src and edit procedures SetArchiveFileName, SetDiskFileName<br />
<br />
=== Language Changes ===<br />
<br />
==== AnsiStrings are now codepage-aware ====<br />
* '''Old behaviour''': The codepage of an ''AnsiString'' was always be assumed to be the default system (single byte) code page. The predefined ''Utf8String'' type was just an alias for ''AnisString'' and did not behave differently in any way.<br />
* '''New behaviour''': Every ''AnsiString'' constant or variable now also has an associated code page, which governs how its data is interpreted. The predefined ''Utf8String'' type is now tagged with the UTF-8 codepage identifier.<br />
* '''Reason''': Delphi 2009+ compatibility.<br />
* '''Remedy''': This new feature generally works transparently, but there are some caveats:<br />
** Avoid using ''AnsiString'' variables to store data not encoded using the ''DefaultSystemCodePage'' encoding without also setting the corresponding code page (such as currently done in Lazarus). For example, assume an ''AnsiString'' with a [[FPC_Unicode_support#Dynamic_code_page|dynamic code page]] different from ''CP_UTF8'' (e.g. [[FPC_Unicode_support#Code_page_identifiers|CP_ACP]]) contains UTF-8 data. If it is then converted to a different code page, e.g. because it's passed to a routine expecting a ''UnicodeString'' or ''Utf8String'' parameter, then the UTF-8 data in the string will be "converted" from CP_ACP to UTF-8, thereby corrupting the string data (if CP_ACP is different from UTF-8).<br />
** Routines that are declared with a plain ''AnsiString'' parameter will cause passed custom code page strings to be converted to ''DefaultSystemCodePage'', possibly resulting in data loss. We have [[FPC_Unicode_support#RTL_changes|a list of RTL routines]] that have been updated to correctly handle strings encoded in any code page.<br />
* '''More information''': [[FPC_Unicode_support|FPC Unicode support]]<br />
<br />
==== Variant overload preference for string types ====<br />
* '''Old behaviour''': Preference for string types was (from better to worse): ShortString, AnsiString, WideString, UnicodeString<br />
* '''New behaviour''': Preference for string types now (from better to worse): WideString, UnicodeString, AnsiString, ShortString<br />
* '''Reason''': Unicode characters and codepage information will not be lost during the conversion; unicode Delphi compatibility.<br />
* '''Remedy''': Use explicit conversion (e.g. ShortString(V)) if it is needed to pass variant to routine with a particular string type argument.<br />
==== Variant conversion preference for widechar ====<br />
* '''Old behaviour''': If a ''widechar'' was passed to a ''variant'' parameter, it would be wrapped as a ''word'' (D7 compatible).<br />
* '''New behaviour''': A ''widechar'' passed to a ''variant'' parameter is now convert it to a unicodestring (D2009+ compatible).<br />
* '''Reason''': Newer Delphi version compatibility.<br />
* '''Remedy''': Use explicit conversion (e.g. integer(V)) if needed. We decided against differentiating this behaviour between ''{$mode delphi}'' and ''{$mode delphiunicode}'' because the compatibility advantage does not outweigh implementation complexity.<br />
<br />
==== Default values in implementation but not in interface/forward declaration ====<br />
* '''Old behaviour''': The implementation of a routine could declare default values even if the interface declaration did not have any.<br />
* '''New behaviour''': Default values, if any, must be specified in the interface. They can be repeated in the implementation, but that is not required (just like it was not in the past).<br />
* '''Reason''': Default parameters specified only in the implementation are not, and cannot, be propagated to the interface since a unit's interface can be used before the implementation has been parsed (see http://bugs.freepascal.org/view.php?id=19434), Delphi compatibility.<br />
* '''Remedy''': Always specify default parameter values (also) in the interface/forward declaration of a routine.<br />
<br />
==== Default values are now properly typechecked ====<br />
* '''Old behaviour''': The compiler did not detect default values for parameters of which the type did not in any way correspond to the parameter type. <br />
* '''New behaviour''': The compiler now properly checks whether the type of the constant matches the parameter's type when parsing default values.<br />
* '''Reason''': Proper type checking is one of the fundamental properties of the Pascal language; Delphi compatibility.<br />
* '''Remedy''': Add a typecast around default values that now result in compiler errors, or correct the type of such parameters.<br />
<br />
==== "''strict protected''" visibility modifier ====<br />
* '''Old behaviour''': ''strict protected'' did not correctly limit the visibility of symbols declared in different units.<br />
* '''New behaviour''': ''strict protected'' symbols can now only be accessed from descendent classes, regardless of where they are defined.<br />
* '''Reason''': Fix behaviour to conform to specification/documentation, Delphi compatibility.<br />
* '''Remedy''': Use ''protected'' or ''public'' if less strict accessibility checks are desired.<br />
<br />
==== Support for type helpers added ====<br />
* '''Old behaviour''': In modes ''ObjFPC'' and ''MacPas'' it was possible to declare a unique type of a type ''helper''.<br />
* '''New behaviour''': The compiler now interprets the keyword ''helper'' as a helper type if it immediately follows the ''type'' keyword (but only if the mode is ''ObjFPC'' or ''MacPas'' or the mode switch ''Class'' is set).<br />
* '''Example''':<br />
<syntaxhighlight><br />
{$mode objfpc}<br />
type<br />
helper = LongInt;<br />
<br />
otherhelper = type helper;<br />
</syntaxhighlight><br />
The above code will no longer compile.<br />
* '''Reason''': ''type helper'' is a more logical way to declare helpers for primitive types than Delphi's ''record helper'' is.<br />
* '''Remedy''': Escape the keyword ''helper'' using a ''&''. E.g.:<br />
<syntaxhighlight><br />
{$mode objfpc}<br />
type<br />
helper = LongInt;<br />
<br />
otherhelper = type &helper;<br />
</syntaxhighlight><br />
<br />
==== "''strict protected''" and "''protected''" visibility modifier in extended records ====<br />
* '''Old behaviour''': ''strict protected'' and ''protected'' could be used used in extended records.<br />
* '''New behaviour''': ''strict protected'' and ''protected'' are no longer allowed in extended records.<br />
* '''Reason''': The only difference between ''(strict) protected'' and ''(strict) private'' is that the former allows you to access members of a parent class or object. As records don't support inheritence it makes no sense to support ''(strict) protected'' in them. This is also Delphi-compatible.<br />
* '''Remedy''': Use ''private'' instead of ''protected'' and ''strict private'' instead of ''strict protected''.<br />
<br />
==== "''static''" directive on non-class methods ====<br />
* '''Old behaviour''': It was possible to use the ''static'' on normal, non-''class'' methods<br />
* '''New behaviour''': The compiler now generates an error if ''static'' is used on normal, non-''class'' methods (except in ''object'' types)<br />
* '''Reason''': It is only correct to leave out the ''Self'' parameter if it is a class method. This is also Delphi compatible.<br />
* '''Remedy''': Prepend the ''class'' keyword to the method.<br />
<br />
==== "''static''" directive on class operators ====<br />
* '''Old behaviour''': It was possible to use the ''static'' on class operators.<br />
* '''New behaviour''': The compiler now generates an error if ''static'' is used on class operators.<br />
* '''Reason''': Class operators are by definition static, thus the ''static'' would be redundant. This is also Delphi compatible.<br />
* '''Remedy''': Remove the ''static'' keyword from class operators.<br />
<br />
====Classes implementing forward-declared interfaces====<br />
* '''Old behaviour''': It was possible to declare classes as implementing a forward-declared interface.<br />
* '''New behaviour''': Classes can no longer implement forward-declared interfaces.<br />
* '''Reason''': This occasionally [http://bugs.freepascal.org/view.php?id=24184 caused crashes], the compiler did not check in such a case whether the class actually implemented the methods of that interface. Recent versions of Delphi also reject such constructs.<br />
* '''Remedy''': If there is a cyclic dependency between a class and an interface, use a forward declaration for the class instead.<br />
<br />
====Using the function name as alias for loading its current result value in MacPas mode====<br />
* '''Old behaviour''': Inside a function the name of the function could be used on the right hand side (RHS) of an expression in order to refer to the current value of the function result.<br />
* '''New behaviour''': Using the name of a function on the RHS of an expression inside that function's body now always results in a recursive function call.<br />
* '''Reason''': The old behaviour existed because under '''some''' circumstances CodeWarrior behaved that way. Under other circumstances [http://bugs.freepascal.org/view.php?id=22344 it however behaves according to the new rule] and there appears to be no definition available of when it does what. Since it is easier to fix a compilation error than to find out where an intended recursive function call is not doing anything, we opted to change the behaviour.<br />
* '''Remedy''': Either use a temporary local variable to hold the function result if you want to reuse it on the RHS of other expressions, or add '''{$modeswitch result}''' and use the '''result''' pseudo-variable as an alias for the function result.<br />
<br />
==== nostackframe forbidden for Pascal subroutines ====<br />
* '''Old behaviour''': The nostackframe directive could be applied to all types of subroutines.<br />
* '''New behaviour''': The nostackframe directive is allowed only for pure assembler subroutines,<br />
* '''Reason''': Depending on the architecture, ABI and code of the subroutine, nostackframe might have worked or caused random crashes. This was unpredictable and makes no sense.<br />
* '''Remedy''': Remove the nostackframe from Pascal subroutines. In any case, if the compiler can omit the stack frame, it will do so.<br />
<br />
====Conversion preference of pansichar to various string types====<br />
* '''Old behaviour''': In {$h-} mode, the compiler preferred ''pansichar''->''shortstring'' to ''pchar''->''ansistring'' conversions, and gave ''pansichar''->''ansistring'' and ''pchar''->''unicodestring'' the same conversion preference.<br />
* '''New behaviour''': The compiler now always prefers ''pansichar''->''ansistring'' to ''pansichar''->''shortstring'', and also prefers ''pansichar''->''ansistring'' to ''pansichar''->''unicodestring'' (which it in turn prefers to ''pansichar''->''shortstring'').<br />
* '''Reason''': Prevent truncation of long pchars, make it easier to add unicodestring overloads to the RTL without causing ''can't decide which overloaded function to call'' errors when using pchars, Delphi compatibility.<br />
* '''Remedy''': Use ''strpas()'' to explicitly truncate pchars to shortstrings if desired.<br />
<br />
==== Comparative operators can have any result type ====<br />
* '''Old behaviour''': Overloaded comparative operators could only have a ''Boolean'' result type.<br />
* '''New behaviour''': Overloaded comparative operators can have any result type.<br />
* '''Reason''': The result type is checked by the regular type checking mechanism. For example, overloaded comparative operators that return non-Boolean results cannot be used in IF, WHILE or UNTIL expressions, but it is still possible to use them in other situations. This is also Delphi compatible.<br />
* '''Example''':<br />
<syntaxhighlight><br />
SQLResult := Database.Query(<br />
Select(<br />
[ PersonsTable.FirstName, PersonsTable.LastName ],<br />
[ PersonsTable ],<br />
[ <br />
PersonsTable.Country = 'NL',<br />
PersonsTable.Age >= 25<br />
]<br />
)<br />
);<br />
</syntaxhighlight><br />
* '''Remedy''': Not applicable.<br />
<br />
==== True and False are not keywords anymore ====<br />
* '''Old behaviour''': True and False were keywords and as a result it was not possible to use them as identifiers.<br />
* '''New behaviour''': True and False are now predefined constants in the system unit's scope and can be used as identifiers.<br />
* '''Example''':<br />
<syntaxhighlight><br />
const<br />
False = 0;<br />
True = 1;<br />
</syntaxhighlight><br />
* '''Reason''': Compatibility with other Pascal compilers.<br />
* '''Remedy''': Not applicable.<br />
<br />
==== For-in loop variable cannot be assigned to anymore ====<br />
* '''Old behaviour''': Inside a ''for X in Y'' loop it was possible to assign a value to X. This was different from the ''for X:=A to B'' loop, where assigning to the loop variable X was not allowed.<br />
* '''New behaviour''': The variable X of a ''for X in Y'' loop cannot be changed.<br />
* '''Reason''': Compatibility with for ''X:=A to B'' loop.<br />
* '''Remedy''': Use a temporary variable instead.<br />
<br />
==== Casting integer variables to floating point ====<br />
* '''Old behaviour''': Explicitly typecasting an integer variable to a floating point type of the same size caused the bit pattern of the integer to be reinterpreted as a floating point value.<br />
* '''New behaviour''': Such explicit typecasts now result in a conversion of the integer value to an equal floating point value (to the extent that the floating point type can represent the integer value)..<br />
* '''Example''': The following program now prints twice " 1.3890388970000000E+009", while previously the first writeln printed " 6.86276399744918E-315"<br />
<syntaxhighlight><br />
var<br />
i: int64;<br />
begin<br />
i:=1389038897;<br />
writeln(Double(i))<br />
writeln(Double(1389038897))<br />
end.<br />
</syntaxhighlight><br />
* '''Reason''': Consistency with the behaviour of a compile-time integer to floating point conversions, as demonstrated by the above example.<br />
* '''Remedy''': Add an intermediate typecast to a record type to reinterpret the actual bit pattern.<br />
<br />
== Unix platforms ==<br />
<br />
=== cthreads: critical sections and recursive mutex support ===<br />
* '''Old behaviour''': If the ''cthreads'' unit thread manager was used on a platform without recursive mutex support, critical sections were non-reentrant.<br />
* '''New behaviour''': Initialising a critical section under the above circumstances will now result in a run time error.<br />
* '''Reason''': One of the basic properties of (Delphi/Windows-compatible) critical sections is that they are reentrant, and that is how they are generally used in Pascal code.<br />
* '''Remedy''': Use an RTLEvent instead if reentrancy is not required.<br />
<br />
== Darwin platforms ==<br />
<br />
=== Location of certain function result types on Darwin/i386 and iPhoneSim/i386 ===<br />
* '''Old behaviour''': Small records and method pointers were always returned according to the official ABI.<br />
* '''New behaviour''': When a calling convention other than ''cdecl'', ''cppdecl'' or ''mwpascal'' is used, the same convention as on other platforms is now used.<br />
* '''Reason''': Better compatibility with assembler code written for other platforms.<br />
* '''Remedy''': Update your assembler code, or better: if possible, convert it to Pascal.<br />
<br />
=== Default assembler for Darwin/i386/x86_64/ARM and iPhoneSimulator/i386/x86_64 ===<br />
* '''Old behaviour''': The default assembler for these platforms was the ''as'' binary.<br />
* '''New behaviour''': The default assembler for these platforms now is the ''clang'' binary.<br />
* '''Reason''': Xcode 7 no longer includes the old assembler, and the ''as'' binary now simply invokes ''clang''. Additionally, Xcode 7 now requires the compiler to specify the OS variant (OS X, iOS) and version to the assembler, which was not possible with the ''as'' binary that shipped with older Xcode versions. In order to disambiguate between an assembler that does and that does not support these options, we now explicitly invoke ''clang'' with these options.<br />
* '''Remedy''': If you have an older version of Xcode and wish to use the old assembler, you can use the ''-Aas-darwin'' command line option.<br />
<br />
=== Default debug format for Darwin/i386 ===<br />
* '''Old behaviour''': The default debug format for Darwin/i386 was ''Stabs''.<br />
* '''New behaviour''': The default debug format for Darwin/i386 is ''DWARF 2''.<br />
* '''Reason''': The assembler included with Xcode 7 and later no longer supports Stabs.<br />
* '''Remedy''': If you have an older version of Xcode and wish to use Stabs, you can use ''-Aas-darwin -gs'' to force the use of the old assembler in combination with Stabs.<br />
<br />
=== MacOSAll unit: changed parameter and opaque types ===<br />
<br />
* '''Change''': The headers have been updated to the Mac OS X 10.8 SDK, and in this process a number of signatures have been changed/corrected, and several opaque types have been changed from ^SInt32 into pointers to different/incompatible empty records.<br />
* '''Reason''': The reasons for the signature changes are detailed below. The opaque types have been made incompatible so that the compiler can give error messages when trying to use one opaque type instead of another (e.g., in the past the compiler did not complain when passing a ControlRef to a routine that expected a WindowPtr).<br />
* '''Remedy''': Adjust your code to conform to the new signatures. Regarding the opaque types, that means that these types are no longer assignment-compatible. Some of the more prominent ones that may affect existing, correct, code are HIObject and ControlRef=HIViewRef. This may require adding typecasts to keep code compiling (the same typecasts are required in C)<br />
* '''Changes:''' (apart from the opaque type changes)<br />
** CGGLContextCreate : fixed first parameter (was "var", now is value parameter)<br />
** CFHostGetAddressing: var hasBeenResolved: boolean -> booleanptr because can be nil<br />
** CFHostGetNames: var hasBeenResolved: boolean -> booleanptr because can be nil<br />
** ColorSyncIterateInstalledProfiles: var seed: UInt32 -> UInt32Ptr because can be nil<br />
** AudioStreamGetPropertyInfo: outSize and outWritable changed to pointer because can be nil<br />
** cblas (several var-parametes changed to pointers because they represent arrays):<br />
*** cblas_sswap, cblas_dswap: X, Y<br />
*** cblas_scopy, cblas_dcopy: Y<br />
*** cblas_saxpy, cblas_daxpy: Y<br />
*** catlas_saxpby, catlas_daxpby: Y<br />
*** catlas_sset, catlas_dset: X<br />
*** cblas_sscal, cblas_dscal: X<br />
*** cblas_sgemv, cblas_dgemv: X<br />
*** cblas_strmv, cblas_dtrmv: X<br />
*** cblas_stbmv, cblas_dtbmv: X<br />
*** cblas_stpmv, cblas_dtpmv: Ap, X<br />
*** cblas_strsv, cblas_dtrsv: X<br />
*** cblas_stbsv, cblas_dtbsv: X<br />
*** cblas_stpsv, cblas_dtpsv: Ap, X<br />
*** cblas_ssymv, cblas_dsymv: X<br />
*** cblas_ssbmv, cblas_dsbmv: Y<br />
*** cblas_sspmv, cblas_dspmv: Ap, Y<br />
*** cblas_sger, cblas_dger: A<br />
*** cblas_ssyr, cblas_dsyr: A<br />
*** cblas_sspr, cblas_dspr: Ap<br />
*** cblas_ssyr2, cblas_dsyr2: A<br />
*** cblas_sspr2, cblas_dspr2: A<br />
*** cblas_sgemm, cblas_sgemm: C<br />
*** cblas_ssymm, cblas_Dsymm: C<br />
*** cblas_ssyrk, cblas_dsyrk: C<br />
*** cblas_ssyr2k, cblas_dsyr2k: C<br />
*** cblas_strmm, cblas_dtrmm: B<br />
*** cblas_strsm, cblas_strsm: B<br />
** vBLAS (idem)<br />
*** SDOT: X, Y<br />
*** SNRM2: X<br />
*** SASUM: X<br />
*** ISAMAX: X<br />
*** SSWAP: X, Y<br />
*** SCOPY: X, Y<br />
*** SAXPY: X, Y<br />
*** SROT: X, Y<br />
*** SSCAL: X<br />
*** SGEMV, A, X, Y<br />
*** SGEMM: A, B, C<br />
** vDSP (idem)<br />
*** vDSP_sve_svesq, vDSP_sve_svesqD: __vDSP_A<br />
*** vDSP_normalize, vDSP_normalizeD: __vDSP_A, __vDSP_C<br />
<br />
== Windows 9x series ==<br />
<br />
=== Windows 9x series unsupported ===<br />
* '''Old behaviour''': While 2.6.x formally didn't support the Windows 9x Series, 3rd party maintenance kept most FPC 2.6.x versions working with the Windows 9x series (Windows 95, 98/98SE, ME), and problems were the exception rather than the rule.<br />
* '''New behaviour''': Starting from this compiler version, the Windows 9x series is not supported anymore.<br />
* '''Reason''': the Windows 9x series has been discontinued for a long time; there is no support (including support for newer Windows features) and no Microsoft online documentation. Supporting this platform has been increasingly difficult due to this and the number of users/developers interested in performing the development/test work.<br />
* '''Remedy''': users that want to use FPC for Win9x development can continue to use earlier compiler versions (e.g. FPC 2.6.4).<br />
<br />
== Windows/x86_64 ==<br />
<br />
=== Exception handling has been changed to be ABI-conformant ===<br />
<br />
* '''Old behaviour''': Exceptions were handled using platform-independent mechanism based on SetJmp/LongJmp.<br />
* '''New behaviour''': Exceptions are handled using OS-provided means. The most important differences from generic handling are as follows:<br />
** Every executable contains a <tt>.pdata</tt> section describing layout of function stack frames. This data is used to perform stack back-tracing. As a consequence, the backtraces generated when exception occurs are no longer dependent of code optimization settings. However, they may be different from ones produced by gdb.<br />
** GNU binutils have troubles creating executables with <tt>.pdata</tt> sections. In particular, ld version < 2.22 crashes at such executables, and using GNU as together with internal linker will strip all <tt>.pdata</tt>, resulting in a non-working executable.<br />
** An exception is handled in two phases. First phase determines the target frame (i.e. the 'except' statement that will handle the exception), the second phase does actual stack unwinding and executing code in 'finally' statements. In contrast, the generic mechanism is single-phase: it starts unwinding immediately and proceeds until an 'except' statement handles the exception or the stack runs out.<br />
* '''Reason''': Multiple compatibility issues with Windows and third-party DLLs (see http://bugs.freepascal.org/view.php?id=12974 and related issues)<br />
* '''Remedy''': No changes are necessary unless your code relies on specific exception handling details. Build programs using FPC's internal assembler and linker, do not use GNU binutils. The entire feature can be disabled by cycling the compiler with <tt>OPT=-dDISABLE_WIN64_SEH</tt> in command line.<br />
<br />
=== ''winwidestringalloc'' has been deprecated ===<br />
<br />
* '''Old behaviour''': The ''winwidestringalloc'' variable enabled switching the WideString behaviour on Windows between COM BSTR (if set to true) and an internal UnicodeString-like container (if set to false).<br />
* '''New behaviour''': The ''winwidestringalloc"" has been deprecated and will be removed completely from the RTL code in the future.<br />
* '''Reason''': This setting predates the availability of the separate ''UnicodeString'' types, and was meant to enable Windows targets to use reference counted long strings. Nowadays, the ''UnicodeString'' type is available as an alternative on all platforms.<br />
* '''Remedy''': Check whether you set <code>winwidestringalloc := false</code> in your program code and if so, replace all ''WideString'' declarations with ''UnicodeString''.<br />
<br />
== WinCE ==<br />
<br />
=== Define ''UNICODE'' was changed to ''FPC_OS_UNICODE'' ===<br />
<br />
* '''Old behaviour''': For arm-wince and i386-wince ''UNICODE'' was defined by default.<br />
* '''New behaviour''': For arm-wince and i386-wince ''FPC_OS_UNICODE'' is defined by default.<br />
* '''Reason''': For upcoming support for setting String to UnicodeString, the define ''UNICODE'' now is defined if the type String is currently defined as UnicodeString. This is also increases Delphi compatibility, as ''UNICODE'' is defined from Delphi 2009 on.<br />
* '''Remedy''': Check for ''FPC_OS_UNICODE'' to decide whether the OS only provides a Unicode API (in the sense of Wide- or UnicodeString) and use ''UNICODE'' to decide whether the type String is currently defined as UnicodeString or not.<br />
<br />
== Other == <br />
<br />
=== Stabs support has been disabled for 64 bit targets ===<br />
* '''Old behaviour''': While the default debug information format for 64 bit targets was DWARF (except for AIX, where it's Stabx), it was possible to switch it to Stabs via the -gs command line parameter.<br />
* '''New behaviour''': Only the DWARF debug format is still supported on 64 bit targets (except for AIX, where Stabx is used).<br />
* '''Reason''': Stabs is not well-defined for 64 bit targets, nor well-supported by gdb on those same targets. This can lead to [http://bugs.freepascal.org/view.php?id=23365 problems]<br />
* '''Remedy''': Do not use -gs when compiling for 64 bit targets. If you do so anyway, the compiler will display a warning and keep the previously set (supported) debug format.<br />
<br />
<br />
== Previous release notes ==<br />
{{Navbar Lazarus Release Notes}}<br />
<br />
[[Category:FPC]]<br />
[[Category:FPC 3.0+ stuff]]<br />
[[Category:FPC User Changes by release]]<br />
[[Category:Release Notes]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=FPC_New_Features_3.0.0&diff=97963FPC New Features 3.0.02015-11-26T08:20:02Z<p>Dirk Fellenberg: FPC version 3.0.0 has been released.</p>
<hr />
<div>== About this page ==<br />
<br />
Below you can find a list of new features introduced since the [[FPC_New_Features_2.6.2|previous release]], along with some background information and examples.<br />
<br />
== All systems ==<br />
<br />
=== Language ===<br />
<br />
==== Delphi-like namespaces units ====<br />
* '''Overview''': Support has been added for unit names with dots. <br />
* '''Notes''': Delphi-compatible.<br />
* '''More information''': Unit names with dots creates namespace symbols which always have a precedence over unit names in an identifier search.<br />
<br />
==== Dynamic array constructors ====<br />
* '''Overview''': Support has been added for constructing dynamic arrays with class-like constructors.<br />
* '''Notes''': Delphi-compatible.<br />
* '''More information''': Only constructor name 'CREATE' is valid for dynamic arrays.<br />
* '''Examples''': SomeArrayVar := TSomeDynArrayType.Create(value1, value2)<br />
<br />
==== New compiler intrinsic ''Default'' ====<br />
* '''Overview''': A new compiler intrinsic ''Default'' has been added which allows you get a correctly initialized value of a type which is given as parameter. It can also be used with generic type parameters to get a default value of the type.<br />
* '''Notes''': Delphi-compatible.<br />
* '''More information''': In simple terms the value returned by ''Default'' will be initialized with zeros. The ''Default'' intrinsic is not allowed on file types or records/objects/arrays containing such types (Delphi ignores file types in sub elements).<br />
* '''Examples''': <br />
<syntaxhighlight><br />
type<br />
TRecord = record<br />
i: LongInt;<br />
s: AnsiString;<br />
end;<br />
<br />
var<br />
i: LongInt;<br />
o: TObject;<br />
r: TRecord;<br />
begin<br />
i := Default(LongInt); // 0<br />
o := Default(TObject); // Nil<br />
r := Default(TRecord); // ( i: 0; s: '')<br />
end.<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight><br />
type<br />
generic TTest<T> = class<br />
procedure Test;<br />
end;<br />
<br />
procedure TTest.Test;<br />
var<br />
myt: T;<br />
begin<br />
myt := Default(T); // will have the correct Default if class is specialized<br />
end;<br />
</syntaxhighlight><br />
<br />
==== Support for type helpers ====<br />
* '''Overview''': Support has been added for type helpers which allow you to add methods and properties to primitive types. They require modeswitch ''TypeHelpers'' to be set.<br />
* '''Notes''': In mode ''Delphi'' it's implemented in a Delphi-compatible way using ''record helper'' for declaration, while the modes ''ObjFPC'' and ''MacPas'' use ''type helper''. The modeswitch ''TypeHelpers'' is enabled by default ''only'' in mode ''Delphi'' and ''DelphiUnicode''.<br />
* '''More information''':<br />
** [http://lists.freepascal.org/fpc-announce/2013-February/000587.html This] announcement e-mail contains a detailed description of the feature<br />
** The tests are named ''tthlp*.pp'' and are available in http://svn.freepascal.org/svn/fpc/trunk/tests/test/<br />
<br />
==== Support for codepage-aware strings ====<br />
* '''Overview''': Ansistrings have been made codepage-aware. This means that every ansistring now has an extra piece of meta-information that indicates the codepage in which the characters of that string are encoded.<br />
* '''Notes''': Delphi-compatible (2009 and later).<br />
* '''More Information:'''<br />
** [[FPC_Unicode_support|FPC Unicode Support]]<br />
** [http://edn.embarcadero.com/article/images/38980/Delphi_and_Unicode.pdf Embarcadero white paper], specifically the sections ''The Many String Types'' and ''Converting Strings''<br />
<br />
=== Code generator ===<br />
<br />
==== Class field reordering ====<br />
* '''Overview''': The compiler can now reorder instance fields in classes in order to minimize the amount of memory wasted due to alignment gaps.<br />
* '''Notes''': Since the internal memory layout of a class is opaque (except by querying the RTTI, which is updated when fields are moved around), this change should not affect any code. It may cause problems when using so-called "class crackers" in order to work around the language's type checking though.<br />
* '''More information''': This optimization is currently only enabled by default at the new optimization level -O4, which enables optimizations that may have (unforeseen) side effects. The reason for this is fairly widespread use of some existing code that relies on class crackers. In the future, this optimization may be moved to level -O2. You can also enable the optimization individually using the ''-Ooorderfields'' command line option, or by adding ''{$optimization orderfields}'' to your source file. It is possible to prevent the fields of a particular class from being reordered by adding ''{$push} {$optimization noorderfields}'' before the class' declaration and ''{$pop}'' after it.<br />
<br />
==== Removing the calculation of dead values ====<br />
* '''Overview''': The compiler can now in some cases (which may be extended in the future) remove the calculation of dead values, i.e. values that are computed but not used afterwards.<br />
* '''Notes''': While the compiler will never remove such calculations if they have explicit side effects (e.g. they change the value of a global variable), this optimization can nevertheless result in changes in program behaviour. Examples include removed invalid pointer dereferences and removed calculations that would overflow or cause a range check error.<br />
* '''More information''': This optimization is only enabled by default at the new optimization level -O4, which enables optimizations that may have (unforeseen) side effects. You can also enable the optimization individually using the ''-Oodeadvalues'' command line option, or by adding ''{$optimization deadvalues}'' to your source file.<br />
<br />
==== Shortcuts to speed up floating point calculations ====<br />
* '''Overview''': The compiler can now in some cases (which may be extended in the future) take shortcuts to optimize the evaluation of floating point expressions, at the expense of potentially reducing the precision of the results.<br />
* '''Notes''': Examples of possible optimizations include turning divisions by a value into multiplications with the reciprocal value (not yet implemented), and reordering the terms in a floating point expression.<br />
* '''More information''': This optimization is only enabled by default at the new optimization level -O4, which enables optimizations that may have (unforeseen) side effects. You can also enable the optimization individually using the ''-Oofastmath'' command line option, or by adding ''{$optimization fastmath}'' to your source file.<br />
<br />
==== Constant propagation ====<br />
* '''Overview''': The compiler can now, to a limited extent, propagate constant values across multiple statements in function and procedure bodies.<br />
* '''Notes''': Constant propagation can cause range errors that would normally manifest themselves at runtime to be detected at compile time already.<br />
* '''More information''':This optimization is enabled by default at optimization level -O3 and higher. You can also enable the optimization individually using the ''-Ooconstprop'' command line option, or by adding ''{$optimization constprop}'' to your source file.<br />
<br />
==== Dead store elimination ====<br />
* '''Overview''': The compiler can now, to a limited extent, remove stores to local variables and parameters if these values are not used before they are overwritten.<br />
* '''Notes''': The use of this optimization requires that data flow analysis (-Oodfa) is enabled. It can help in particular with cleaning up instructions that have become useless due to constant propagation.<br />
* '''More information''': This optimization is currently not enabled by default at any optimization level because -Oodfa is still a work in progress. You can enable the optimization individually using the ''-Oodeadstore'' command line option, or by adding ''{$optimization deadstore}'' to your source file.<br />
<br />
==== Node dfa for liveness analysis ====<br />
* '''Overview''': The compiler can now perform static data flow analysis (dfa) to determine data liveness.<br />
* '''Notes''': This analysis is only enabled when -O3 is used.<br />
* '''More information''': Warnings about uninitialized variables are more exact when using dfa compared with the previous approach. However, the current dfa approach is static and non-global, so one might get false positives:<br />
<br />
<syntaxhighlight><br />
var<br />
b : boolean;<br />
i : longint;<br />
begin<br />
if b then<br />
i:=1;<br />
writeln;<br />
if b then<br />
writeln(i);<br />
end.<br />
</syntaxhighlight><br />
<br />
In this case, the compiler warns about ''i'' being uninitialized. While some cases like the case above could be detected and the warning could be prevent, this does no apply if ''b'' is a function. To workaround this, add an assignment to ''i'' at the entry of the subroutine body.<br />
<br />
The same applies to functions/procedures:<br />
<br />
<syntaxhighlight><br />
var<br />
i : longint;<br />
procedure p;<br />
begin<br />
i:=1;<br />
end;<br />
begin<br />
p;<br />
writeln(i);<br />
end.<br />
</syntaxhighlight><br />
<br />
The current dfa approach works only intra-procedurally instead of globally, so the above case cannot yet be handled correctly. The compiler does not see that ''i'' is initialized. To work around this, add an assignment to i at the entry of the outer subroutine body.<br />
<br />
=== Units and packages ===<br />
==== TDBF support for Visual FoxPro files ====<br />
* '''Overview''': TDBf now has explicit support for Visual FoxPro (tablelevel 30) files, including the VarBinary and VarChar datatypes.<br />
* '''Notes''': TDBF version increased to 7.0.0.<br />
* '''More information''': The code does not support .dbc containers, only freestanding dbfs. It does not support (and quite likely will never support) .cdx index files.<br />
Additionally, TDBf is now included in the database test suite and has received several fixes (including better Visual FoxPro codepage support).<br />
<br />
==== Bufdataset supports ftAutoInc fields ====<br />
* '''Overview''': Bufdataset now has support for automatically increasing ftAutoinc field values.<br />
<br />
==== TDBF, bufdataset (and descendents such as TSQLQuery) allow escaped delimiters in string expression filter ====<br />
* '''Overview''': filters that contain string expressions should be quoted (using either ' or "). However, having the same quotes within the filter was not parsed as there was no support for escaping quotes in the string<br />
Support has been added for escaping quotes to allow this.<br />
* '''Notes''': Double up the delimiter within the string to escape the delimiter. Example:<br />
<syntaxhighlight><br />
Filter:='(NAME=''O''''Malley''''s "Magic" Hammer'')';<br />
//which gives<br />
//(NAME='O''Malley''s "Magic" Hammer')<br />
//which will match record<br />
//O'Malley's "Magic" Hammer<br />
</syntaxhighlight><br />
* '''More information''': N/A<br />
<br />
==== TODBCConnection (odbcconn) Support for 64 bit ODBC ====<br />
* '''Overview''': 64 bit ODBC support has been added.<br />
* '''Notes''': if you use unixODBC version 2.3 or higher on Linux/Unix, the unit has to be (re)compiled with -dODBCVER352 to enable 64 bit support<br />
* '''More information''': Only tested on Windows and Linux.<br />
<br />
==== TZipper support for zip64 format ====<br />
* '''Overview''': TZipper now supports the zip64 extensions to the zip file format: > 65535 files and > 4GB file size (bug #23533). Related fixes also allow path/filenames > 255 characters.<br />
* '''Notes''': the zip64 format will automatically be used if the number or size of files involved exceed the limits of the old zip format. Note that there still are 2GB limits on streams as used in extraction/compression. Zip64 is unrelated to the processor type/bitness (such as x86, x64, ...).<br />
* '''More information''': More information on zip64: http://en.wikipedia.org/wiki/ZIP_%28file_format%29#ZIP64<br />
<br />
==== Multiple codepage and unicode support for most file-related RTL routines ====<br />
* '''Overview''': Most file-related routines from the ''system'' and ''sysutils'' units have been made codepage-aware: they now accept ansistrings encoded in arbitrary codepages as well as unicodestrings, and will convert these to the appropriate codepage before calling OS APIs.<br />
* '''Notes''': /<br />
* '''More information''': [[FPC_Unicode_support#Current_support_via_merged_cpstrrtl_branch|Detailed list]] of all related changes to the RTL.<br />
<br />
==== SQL parser/generator improvements ====<br />
* '''Overview''': The SQL parser/generator in packages/fcl-db/src/sql has been improved:<br />
* '''Notes''': N/A<br />
** Support for FULL [OUTER] JOIN; optional OUTER in LEFT OUTER and RIGHT OUTER JOIN<br />
** support table.column notation for fields like SELECT A.B FROM MYTABLE or SELECT B FROM MYTABLE ORDER BY C.D<br />
** Small improvements (e.g. in array datatype access) that allow the parser to parse the Firebird employee sample database DDL. ''Note: there is no support for isql SET TERM statements, so isql DDL dumps containing stored procedures/triggers with semicolons can still not be processed properly''<br />
* '''More information''': N/A<br />
<br />
=== Tools and miscellaneous ===<br />
==== New ''Pas2jni'' utility ====<br />
* '''Overview''': The new ''pas2jni'' utility generates a JNI (Java Native Interface) bridge for Pascal code. This enables Pascal code (including classes and other advanced features) to be easily used from Java programs.<br />
* '''Notes''': The following Pascal features are supported by pas2jni: function/procedure, var/out parameters, class, record, property, constant, enum, TGuid type, pointer type, string types, all numeric types<br />
* '''More information''': [[pas2jni]]<br />
<br />
== (Mac) OS X/iOS ==<br />
<br />
=== New ''iosxlocale'' unit ===<br />
* '''Overview''': The new unit called ''iosxlocale'' can be used to initialise the ''DefaultFormatSettings'' and other related locale information in the ''sysutils'' unit based on the settings in the (Mac) OS X ''System Preferences'' or the iOS ''Settings'' app.<br />
* '''Notes''': The ''clocale'' unit, which also works on (Mac) OS X and iOS, instead gets its information from the Unix-layer. This information depends on the contents of the ''LC_ALL'', ''LC_NUMERIC'' etc environment variables (see ''man locale'' for more information). Adding both ''clocale'' and ''iosxlocale'' to the uses clause will cause the second in line to overwrite the settings set by the first one.<br />
* '''More information''': Adding this unit to the uses clause is enough to use its functionality.<br />
<br />
== New compiler targets ==<br />
<br />
=== Support for the Java Virtual Machine and Dalvik targets ===<br />
<br />
* '''Overview''': Support has been added for generating Java byte code as supported by the Java Virtual Machine and by the Dalvik (Android) virtual machine.<br />
* '''Notes''': Not all language features are supported for these targets.<br />
* '''More information''': [[FPC_JVM|The FPC JVM target]]<br />
<br />
=== Support for the AIX target ===<br />
<br />
* '''Overview''': Support has been added for the AIX operating system. Both PowerPC 32bit and 64bit are supported, except that at this time the resource compiler does not yet work for ppc64.<br />
* '''Notes''': AIX 5.3 and later are supported.<br />
* '''More information''': [[FPC_AIX_Port|The FPC AIX port]]<br />
<br />
=== Support for the 16-bit real mode MS-DOS target ===<br />
<br />
* '''Overview''': Support has been added for the 16-bit real mode MS-DOS target. Multiple memory models are supported (including ones, not supported by TP/BP)<br />
* '''Notes''': Open Watcom binutils (wlib and wlink) are required. Crosscompilation from go32v2 still has issues, due to lack of long file name support in Open Watcom's binutils and incompatibilities between Open Watcom's dos extender and the GO32 dos extender.<br />
* '''More information''': [[DOS]]<br />
<br />
=== Support for the Android target ===<br />
<br />
* '''Overview''': Support has been added for the Android target. Supported CPUs: ARM, x86, MIPS. <br />
* '''Notes''': You need to build a cross-compiler from FPC sources to be able to compile for the Android target.<br />
* '''More information''': [[Android|The FPC Android target]]<br />
<br />
=== Support for the armhf EABI ===<br />
<br />
* '''Overview''': Support has been added for the armhf EABI.<br />
* '''Notes''': This support was already available in some patched FPC distribution by Debian GNU/Linux, but now it is officially supported.<br />
* '''More information''': To bootstrap a compiler with armhf support, the compiler must be compiled with -dFPC_ARMHF. An armhf compiler compiling itself will automatically create a new armhf compiler.<br />
<br />
=== Support for the AROS target ===<br />
<br />
* '''Overview''': Support has been added for the AROS target. Supports: i386-ABIv0, i386-ABIv0-on-trunk.<br />
* '''Notes''': You need to build a cross-compiler from FPC sources to be able to compile for the AROS target 9requires collect-aros to support binutils)<br />
* '''More information''': [[AROS]]<br />
<br />
== New Features from other versions ==<br />
{{Navbar Lazarus Release Notes}}<br />
<br />
[[Category:FPC 3.0+ stuff]]<br />
[[Category: FPC New Features by release]]<br />
[[Category:Release Notes]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=fcl-image&diff=94848fcl-image2015-08-18T15:51:35Z<p>Dirk Fellenberg: typo fixed</p>
<hr />
<div>{{fcl-image}}<br />
<br />
== Introduction ==<br />
<br />
FCL-Image started life as "fpimage", pretty much as an attempt to implement a generally portable TImage like class, without the deep win32 and VCL ties.<br />
<br />
== Current file list ==<br />
<br />
The central units are ''[[doc:fcl/fpimage|fpimage]]'' and ''[[doc:fcl/fpcanvas|fpcanvas]]'' and these are further enhanced by OOP derivation.<br />
<br />
* '''bmpcomn''' A few structures and constants for the BMP fileformat<br />
* '''clipping''' Some utility routines that help with clipping and intersecting of rects.<br />
* '''ellipses''' Drawing of ellipses and arcs, and filling ellipses and pies.<br />
** TEllipseInfo<br />
* '''extinterpolation''' interpolation filters for TFPCanvas.StretchDraw (<br />
** TBlackmanInterpolation<br />
** TBlackmanSincInterpolation<br />
** TBlackmanBesselInterpolation<br />
** TGaussianInterpolation<br />
** TBoxInterpolation<br />
** THermiteInterpolation<br />
** TLanczosInterpolation<br />
** TQuadraticInterpolation<br />
** TCubicInterpolation<br />
** TCatromInterpolation<br />
** TBilineairInterpolation<br />
** THanningInterpolation<br />
** THammingInterpolation<br />
* '''fpcanvas''' Generic Canvas classes.<br />
** [[doc:fcl/fpcanvas/tfpcanvasexception.html|TFPCanvasException]]<br />
** TFPPenException<br />
** TFPBrushException<br />
** TFPFontException<br />
** TFPCustomCanvas<br />
** TFPCanvasHelper<br />
** TFPCustomFont<br />
** TFPCustomFontClass<br />
** TFPCustomPen<br />
** TFPCustomPenClass<br />
** TFPCustomBrush<br />
** TFPCustomBrushClass<br />
** TFPCustomInterpolation<br />
** TFPBaseInterpolation<br />
** [[doc:fcl/fpcanvas/tmitchelinterpolation.html|TMitchelInterpolation]]<br />
** TFPCustomCanvas<br />
** TFPCustomDrawFont<br />
** TFPEmptyFont<br />
** TFPCustomDrawPen<br />
** TFPEmptyPen<br />
** TFPCustomDrawBrush<br />
** TFPEmptyBrush<br />
* '''fpcolhash''' an implementation of a color hash table.<br />
** TFPColorHashException<br />
** TFPColorHashTable<br />
* '''fpditherer''' contains classes used to dither images.<br />
** FPDithererException<br />
** TFPBaseDitherer<br />
** TFPFloydSteinbergDitherer<br />
* '''fpimage''' fpImage base definitions and classes<br />
** TFPCustomImageReader<br />
** TFPCustomImageWriter<br />
** TFPCustomImage<br />
** FPImageException<br />
** TFPPalette<br />
** TFPCustomImage<br />
** TFPMemoryImage<br />
** TFPCustomImageHandler<br />
** TFPCustomImageReader<br />
** TFPCustomImageWriter<br />
** TIHData<br />
** TImageHandlersManager<br />
* '''fpimgcanv''' Image Canvas - canvas which draws on an image.<br />
** TFPImageCanvas <br />
* '''fpimgcmn''' Image Common: small procedural Helpers (swap,crc)<br />
* '''fppixlcanv''' <br />
** TPixelCanvas <br />
* '''fpquantizer''' classes used to quantize images. See [http://lazarus.freepascal.org/index.php/topic,13468.0]<br />
* '''freetype''' Encapsulating classes over freetype<br />
* '''freetypeh''' Freetype header translation<br />
* '''ftfont''' More freetype related font classes<br />
* '''pcxcomn''' PCX fileformat records and types<br />
* '''pixtools''' Pixel drawing routines.<br />
* '''pngcomn''' PNG fileformat records and types<br />
* '''pscanvas''' TPostScriptCanvas implementation.<br />
* '''targacmn''' Targa fileformat records and types<br />
<br />
'''Readers and writers for various image formats'''<br />
<br />
* '''fpreadbmp'''<br />
* '''fpreadjpeg'''<br />
* '''fpreadpcx'''<br />
* '''fpreadpng'''<br />
* '''fpreadpnm'''<br />
* '''fpreadtga'''<br />
* '''fpreadtiff'''<br />
* '''fpreadxpm'''<br />
* '''fpwritebmp'''<br />
* '''fpwritejpeg'''<br />
* '''fpwritepcx'''<br />
* '''fpwritepng'''<br />
* '''fpwritepnm'''<br />
* '''fpwritetga'''<br />
* '''fpwritetiff'''<br />
* '''fpwritexpm'''<br />
<br />
'''INC files uses in fpcanvas'''<br />
* fpbrush <br />
* fpcanvas<br />
* fpcdrawh<br />
* fpfont<br />
* fphelper<br />
* fpinterpolation<br />
* fppen<br />
<br />
INC files uses in fpmake<br />
<br />
* fpcolors<br />
* fpimage<br />
* fphandler<br />
* fpcolcnv<br />
* fppalette<br />
<br />
Demoes<br />
<br />
* drawing<br />
* imgconv<br />
<br />
== Known Issues and limitations ==<br />
<br />
* fcl-image is written for maximal portability and maintainability and is quite slow. The main storage type is 16-bit RGBA, storing always 64-bit per pixel, and a function is called to get each pixel.<br />
* pngwriter doesn't implement automatic detection of filters, and thus is always "filter none"<br />
* most writers don't autodetect what format to save. You must correctly set the relevant writer options ( see also [http://bugs.freepascal.org/view.php?id=17621 bug 17621]).<br />
* the color format can be counter intuitive, read [http://www.mail-archive.com/fpc-devel@lists.freepascal.org/msg16506.html this thread]<br />
* png only implements basic chunk types (idat,trns,plte,ihdr and iend). It e.g. can't handle chunks like pHYs,iCCP,gAMA,cHRM yet. ([http://bugs.freepascal.org/view.php?id=19209 bug 19209]).<br />
<br />
== Image formats ==<br />
<br />
Here is a table with the correct class to use for each image format, as well as comparing to the LCL.<br />
<br />
{| class="wikitable"<br />
|-<br />
! Format !! fcl-image reader unit !! fcl-image writer unit !! LCL class<br />
|-<br />
|Windows Bitmap. A very simple format, usually used without compression and without transparency, but it may also have them, although many applications don't support those extra features. (*.bmp)||fpreadbmp||fpwritebmp||TBitmap<br />
|-<br />
|A popular format for websites. It supports up to 8 bits per pixels, which are 256 distinct colors chosen from the 24-bit RGB color space. This limitation makes it unsuitable for complex images, but useful for simple graphics. The image is compressed without loss in quality and the format also supports animations. (*.gif)||fpreadgif||-||TGIFImage<br />
|-<br />
|The most popular format for websites, and an ISO standard since 1994. The format compressed the image but generates a small loss of quality. (*.jpeg, *.jpg)||fpreadjpeg||fpwritejpeg||TJpegImage<br />
|-<br />
|A format widely used in DOS applications, but now less popular. (*.pcx)||fpreadpcx||fpwritepcx||-<br />
|-<br />
|Portable Network Graphics. A popular format for it's efficient compression without quality loss. (*.png)||fpreadpng||fpwritepng||TPortableNetworkGraphic<br />
|-<br />
||Supports the formats Portable BitMaps (*.pbm), Portable GrayMaps (*.pgm) and Portable PixMaps (*.ppm)||fpreadpnm||fpwritepnm||TPortableAnyMapGraphic<br />
|-<br />
|The default file format for Adobe Photoshop® (*.pds)||fpreadpsd||-||-<br />
|-<br />
|Called either Truevision TGA File Format or TARGA File Format, this is a compressed format commonly used in games. (*.tga, *.tpic)||fpreadtga||fpwritetga||-<br />
|-<br />
|Tagged Image File Format (TIFF), originally created to have a common image format for scanners. (*.tiff, *.tif). Controlled by Adobe®||fpreadtiff||fpwritetiff||TTiffImage<br />
|-<br />
|X PixMap, an image format used by the X Window System which stores the data in ASCII text. Is also used as an icon format in UNIX applications. (*.xpm)||fpreadxpm||fpwritexpm||TPixmap<br />
|-<br />
|X Window Dump file format. Used by the program xwd which generates screenshots in the X Window System. (*.xwd)||fpreadxwd||-||-<br />
|-<br />
|Windows Icon. Is a list of small bitmaps in various color depths and sizes, with transparency support and no compression. (*.ico)||-||-||TIcon<br />
|-<br />
|Windows Cursor. Exactly the same format as the Windows Icon, but with an extra field in the header for the cursor hotspot. (*.cur)||-||-||TCursorImage<br />
|-<br />
|Mac OS X icon. List of small images in various sizes. (*.icns)||-||-||TIcnsIcon<br />
|}<br />
<br />
===Tiff===<br />
<br />
Working features of the reader:<br />
<br />
*Black and white/lineart/1 bit (FPC trunk only, not in FPC 2.6.x)<br />
*Grayscale 8,16bit (optional alpha),<br />
*RGB 8,16bit (optional alpha),<br />
*Orientation, except for rotated orientation<br />
*compression: packbits, LZW, deflate<br />
*endian<br />
*multiple images/multipage<br />
*strips and tiles<br />
*Sets properties in the image Extras properties, which is used by the writer, so that reading/writing keeps many common tags like Artist, Copyright, DateAndTime, HostComputer, ImageDescription, Maker, Model, Software, DocumentName, XResolution, YResolution, Orientation, bit depts, page name, isThumbnail.<br />
<br />
Here is an incomplete list of open / not yet implemented features of the reader:<br />
<br />
*Compression: jpeg, CCITT Group 3, CCITT Group 4<br />
*PlanarConfiguration 2<br />
*ColorMap<br />
*separate mask<br />
*fillorder - not needed by baseline tiff reader<br />
*bigtiff 64bit offsets<br />
*XMP tag 700<br />
*ICC profile tag 34675<br />
*Orientation with rotation<br />
<br />
Working features of the writer:<br />
<br />
*Grayscale 8,16bit (optional alpha)<br />
*RGB 8,16bit (optional alpha)<br />
*Orientation except rotated<br />
*multiple images, pages<br />
*thumbnail<br />
*Compression: deflate<br />
<br />
Here is an incomplete list of open / not yet implemented features of the writer:<br />
<br />
*Compression: LZW, packbits, jpeg, CCIT Group 3,CCIT Group 4,...<br />
*Planar<br />
*ColorMap<br />
*separate mask<br />
*fillorder - not needed by baseline tiff reader<br />
*bigtiff 64bit offsets<br />
*endian - currently using system endianess<br />
*Orientation with rotation<br />
<br />
== Walk-through ==<br />
<br />
=== Basic Canvas Setup ===<br />
<br />
You'll need a few things to start up. A canvas, image, and writer. The writer is to write images like PNG. The sample below will give you a 100x100 black png.<br />
<br />
<syntaxhighlight>{$mode objfpc}{$h+}<br />
program demo;<br />
<br />
uses classes, sysutils,<br />
FPImage, FPCanvas, FPImgCanv,<br />
FPWritePNG;<br />
<br />
var canvas : TFPCustomCanvas;<br />
image : TFPCustomImage;<br />
writer : TFPCustomImageWriter;<br />
begin<br />
{ Create an image 100x100 pixels}<br />
image := TFPMemoryImage.Create (100,100);<br />
<br />
{ Attach the image to the canvas }<br />
Canvas := TFPImageCanvas.Create (image);<br />
<br />
{ Create the writer }<br />
Writer := TFPWriterPNG.Create;<br />
<br />
{ Save to file }<br />
image.SaveToFile ('DrawTest.png', writer);<br />
<br />
{ Clean up! }<br />
Canvas.Free;<br />
image.Free;<br />
writer.Free;<br />
end.</syntaxhighlight><br />
<br />
=== Drawing a Circle ===<br />
<br />
Drawing a circle requires a bit more then just giving a width. You'll need to setup the pen style, mode, width, and color to do this. FCL-Image comes with a few pen modes and styles, it will really be up to you to decide which you'll need. Its best for now to try with a few modes and styles to get a better understanding of what FCL-Image can do.<br />
<br />
<br />
<syntaxhighlight>{$mode objfpc}{$h+}<br />
program demo;<br />
<br />
uses classes, sysutils,<br />
FPImage, FPCanvas, FPImgCanv,<br />
FPWritePNG;<br />
<br />
var canvas : TFPcustomCanvas;<br />
image : TFPCustomImage;<br />
writer : TFPCustomImageWriter;<br />
{ <br />
Colors range from 0 to 65535 in each primary color. <br />
They can also show as hexideciaml:<br />
$FFFF = 65535, $0000 = 0 <br />
}<br />
passionRed: TFPColor = (Red: 65535; Green: 0; Blue: 0; Alpha: 65535);<br />
begin<br />
image := TFPMemoryImage.Create (100,100);<br />
Canvas := TFPImageCanvas.Create (image);<br />
Writer := TFPWriterPNG.Create;<br />
<br />
{ Set the pen styles }<br />
with canvas do<br />
begin<br />
pen.mode := pmCopy;<br />
pen.style := psSolid;<br />
pen.width := 1;<br />
pen.FPColor := passionRed;<br />
end;<br />
<br />
{ Draw a circle }<br />
canvas.Ellipse (10,10, 90,90);<br />
<br />
{ Save to file }<br />
image.SaveToFile ('DrawTest.png', writer);<br />
<br />
{ Clean up! }<br />
Canvas.Free;<br />
image.Free;<br />
writer.Free;<br />
end.</syntaxhighlight><br />
<br />
=== Pen Modes ===<br />
<br />
The pen mode is how the pixel drawn will react to the pixels beneath it. So if its a white pixel and you draw a red pixel over it with the mode of pmXor then you'll get a vibrate blue pixel.<br />
<br />
* pmBlack <br />
* pmWhite <br />
* pmNop <br />
* pmNot <br />
* pmCopy <br />
* pmNotCopy <br />
* pmMergePenNot <br />
* pmMaskPenNot <br />
* pmMergeNotPen <br />
* pmMaskNotPen <br />
* pmMerge <br />
* pmNotMerge <br />
* pmMask <br />
* pmNotMask <br />
* pmXor <br />
* pmNotXor <br />
<br />
<br />
=== Pen Styles ===<br />
* psSolid<br />
* psDash <br />
* psDot<br />
* psDashDot<br />
* psDashDotDot <br />
* psinsideFrame <br />
* psPattern<br />
* psClear<br />
<br />
=== Drawing text ===<br />
<br />
Here is an example, how to create a 200x100 image, painting a white background and some text and saving it as .png:<br />
<syntaxhighlight>program fontdraw;<br />
<br />
{$mode objfpc}{$H+}<br />
<br />
uses<br />
Classes, SysUtils, FPimage, FPImgCanv, ftfont, FPWritePNG, FPCanvas;<br />
<br />
procedure TestFPImgFont;<br />
var<br />
Img: TFPMemoryImage;<br />
Writer: TFPWriterPNG;<br />
ms: TMemoryStream;<br />
ImgCanvas: TFPImageCanvas;<br />
fs: TFileStream;<br />
AFont: TFreeTypeFont;<br />
begin<br />
Img:=nil;<br />
ImgCanvas:=nil;<br />
Writer:=nil;<br />
ms:=nil;<br />
fs:=nil;<br />
AFont:=nil;<br />
try<br />
// initialize free type font manager<br />
ftfont.InitEngine;<br />
FontMgr.SearchPath:='/usr/share/fonts/truetype/ttf-dejavu/';<br />
AFont:=TFreeTypeFont.Create;<br />
<br />
// create an image of width 200, height 100<br />
Img:=TFPMemoryImage.Create(200,100);<br />
Img.UsePalette:=false;<br />
// create the canvas with the drawing operations<br />
ImgCanvas:=TFPImageCanvas.create(Img);<br />
<br />
// paint white background<br />
ImgCanvas.Brush.FPColor:=colWhite;<br />
ImgCanvas.Brush.Style:=bsSolid;<br />
ImgCanvas.Rectangle(0,0,Img.Width,Img.Height);<br />
<br />
// paint text<br />
ImgCanvas.Font:=AFont;<br />
ImgCanvas.Font.Name:='DejaVuSans';<br />
ImgCanvas.Font.Size:=20;<br />
ImgCanvas.TextOut(10,30,'Test');<br />
<br />
// write image as png to memory stream<br />
Writer:=TFPWriterPNG.create;<br />
ms:=TMemoryStream.Create;<br />
writer.ImageWrite(ms,Img);<br />
// write memory stream to file<br />
ms.Position:=0;<br />
fs:=TFileStream.Create('testfont.png',fmCreate);<br />
fs.CopyFrom(ms,ms.Size);<br />
finally<br />
AFont.Free;<br />
ms.Free;<br />
Writer.Free;<br />
ImgCanvas.Free;<br />
Img.Free;<br />
fs.Free;<br />
end;<br />
end;<br />
<br />
begin<br />
TestFPImgFont;<br />
end.</syntaxhighlight><br />
<br />
===Reading an image file===<br />
<br />
It is very easy to read image files with fcl-image, as the example below shows:<br />
<br />
<syntaxhighlight><br />
uses<br />
fpreadgif, fpimage;<br />
<br />
var<br />
image: TFPCustomImage;<br />
reader: TFPCustomImageReader;<br />
begin<br />
Image := TFPMemoryImage.Create(10, 10);<br />
Reader := TFPReaderGIF.Create;<br />
Image.LoadFromFile(AFileName, Reader);<br />
// ...<br />
</syntaxhighlight><br />
<br />
===Converting between two raster image formats===<br />
<br />
To convert simply open in one format and save in the desired one, like in this example:<br />
<br />
<syntaxhighlight><br />
uses<br />
fpreadgif, fpimage, fpwritebmp;<br />
<br />
var<br />
image: TFPCustomImage;<br />
reader: TFPCustomImageReader;<br />
writer: TFPCustomImageWriter;<br />
begin<br />
Image := TFPMemoryImage.Create(10, 10);<br />
Reader := TFPReaderGIF.Create;<br />
Writer := TFPWriterBMP.Create;<br />
<br />
Image.LoadFromFile(AFileName, Reader);<br />
Image.SaveToFile(ADestFileName, Writer);<br />
//...<br />
</syntaxhighlight><br />
<br />
==See also==<br />
<br />
* [[Package_List|Packages List]]<br />
* [[Developing with Graphics]]<br />
* [http://code.google.com/p/javapng/wiki/BrokenSuit Testsuite for png]<br />
<br />
[[Category:Packages]]<br />
[[Category:Free Component Library]]<br />
[[Category:Graphics]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Talk:Lazarus-ccr_SourceForge_repository&diff=80831Talk:Lazarus-ccr SourceForge repository2014-06-08T15:22:57Z<p>Dirk Fellenberg: Re: Has the repository been moved?</p>
<hr />
<div>== What is CCR ? ==<br />
<br />
I can't understand from this page what is ccr and what reason to use this repository when lazarus have http://svn.freepascal.org/svn/lazarus/ ? --[[User:Nashev|Nashev]] 00:11, 8 September 2012 (UTC)<br />
<br />
: CCR is Code and Component Reportisoty - in other words a repository where you can download some ported or created for Lazarus components, code examples and applications which are not distributed together with Lazarus. Those components and other code are supported by the Lazarus community. -- 07:13, 8 September 2012 Paul Ishenin<br />
<br />
===Has the repository been moved?===<br />
When I point Tortoise checkout at https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr I get a message: <br />
<br />
Error: Repository moved permanently to <br />
Error: https://svn.code.sf.net/p/lazarus-ccr/svn/!svn/vcc/default; please relocate <br />
<br />
But entering this URL into tortoise produces:<br />
<br />
Error: URL 'https://svn.code.sf.net/p/lazarus-ccr/svn/!svn/vcc/default' doesn't exist<br />
<br />
== Re: Has the repository been moved? ==<br />
<br />
Use <code>https://svn.code.sf.net/p/lazarus-ccr/svn</code> as new URL.</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Talk:Lazarus-ccr_SourceForge_repository&diff=80830Talk:Lazarus-ccr SourceForge repository2014-06-08T15:21:39Z<p>Dirk Fellenberg: /* Re: Has the repository been moved? */ new section</p>
<hr />
<div>== What is CCR ? ==<br />
<br />
I can't understand from this page what is ccr and what reason to use this repository when lazarus have http://svn.freepascal.org/svn/lazarus/ ? --[[User:Nashev|Nashev]] 00:11, 8 September 2012 (UTC)<br />
<br />
: CCR is Code and Component Reportisoty - in other words a repository where you can download some ported or created for Lazarus components, code examples and applications which are not distributed together with Lazarus. Those components and other code are supported by the Lazarus community. -- 07:13, 8 September 2012 Paul Ishenin<br />
<br />
===Has the repository been moved?===<br />
When I point Tortoise checkout at https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr I get a message: <br />
<br />
Error: Repository moved permanently to <br />
Error: https://svn.code.sf.net/p/lazarus-ccr/svn/!svn/vcc/default; please relocate <br />
<br />
But entering this URL into tortoise produces:<br />
<br />
Error: URL 'https://svn.code.sf.net/p/lazarus-ccr/svn/!svn/vcc/default' doesn't exist<br />
<br />
== Re: Has the repository been moved? ==<br />
<br />
Use<br />
svn co https://svn.code.sf.net/p/lazarus-ccr/svn lazarus-ccr</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Lazarus-ccr_SourceForge_repository&diff=80829Lazarus-ccr SourceForge repository2014-06-08T15:19:15Z<p>Dirk Fellenberg: SVN URL aktualisiert</p>
<hr />
<div>This page describes the policy for using the Lazarus Code and Component Repository on SourceForge SVN (Lazarus CCR project). Anybody porting components to lazarus can ask the [[User:Vincent|Lazarus CCR project admin]] for write access.<br />
<br />
=== Read access ===<br />
Everybody has read access to this SVN repository. You can browse the SVN repository at http://lazarus-ccr.svn.sourceforge.net/viewvc/lazarus-ccr/<br />
<br />
=== Write access ===<br />
Unfortunately, at this moment Sourceforge doesn't support restricting access to svn to only a subtree of the complete repository. So we will give write access to the complete svn tree, with the assumption svn committers will only write to their own part of the tree.<br />
<br />
If you want to commit something to a part of the tree, for which you are not the maintainer, please contact the maintainer before committing.<br />
<br />
=== Working with the Lazarus-CCR SVN repository ===<br />
This is a short guide mainly focussing on the URLs and sourceforge specifics. It is not an introduction to the use of SVN.<br />
<br />
==== Checking out ====<br />
The Lazarus-CCR is located at https://svn.code.sf.net/p/lazarus-ccr/svn<br />
<br />
The following command will check out the complete tree into the lazarus-ccr subdirectory of your current directory:<br />
svn co https://svn.code.sf.net/p/lazarus-ccr/svn lazarus-ccr<br />
<br />
==== Committing ====<br />
The fist time you commit something, svn will ask for your password. Use the password, which belongs to your SourceForge account. This password is stored in the svn metadata in the checked out tree and won't be asked the next time.<br />
<br />
=== Directory owners ===<br />
The following lists shows the directory structure and their maintainers.<br />
<br />
* [http://lazarus-ccr.svn.sourceforge.net/viewvc/lazarus-ccr/applications applications]<br />
** [[fpbrowser]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
** [[Lazarus Image Editor|lazimageeditor]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
** [[fpvectorial|fpvviewer]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
** [[wikihelp]]: [[User:Christian|Christian Ulrich]]<br />
** [[fpChess|fpchess]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
** [[TappyTux|tappytux]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
** [[InstantFPC|instantfpc]]: [[User:Mattias2|Mattias Gärtner]]<br />
** [[gir2pascal]]: [[User:AndrewH|Andrew Haines]]<br />
** [[LazEdit|LazEdit]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]] <br />
** [[idlparser]]: [[User:Loesje|Joost van der Sluis]] <br />
* [http://lazarus-ccr.svn.sourceforge.net/viewvc/lazarus-ccr/bindings bindings]<br />
** [[Objective-c to Pascal bindings|objc]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]] -- Note: Obsolete<br />
** [[PasCocoa|pascocoa]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]], [[User:Skalogryyz|Dmitry Boyarintsev]] -- Note: Obsolete<br />
*** [[ObjCParser|parser]]: [[User:Skalogryyz|Dmitry Boyarintsev]] -- Note: Obsolete<br />
** [[Android Interface|android_ndk]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
** [[Android Interface|android_sdk]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
** [[Gtk+3|gtk3]]: [[User:AndrewH|Andrew Haines]]<br />
* [http://lazarus-ccr.svn.sourceforge.net/viewvc/lazarus-ccr/components/ components]<br />
** [[BeepFp|beepfp]]: [[User:Wimpie|Wimpie Nortje]]<br />
** [[CsvDocument|csvdocument]]: [[User:Vvzh|Vladimir Zhirov]]<br />
** [[Freetype|freetypepascal]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
** [[FPSpreadsheet|fpspreadsheet]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]], [[User:Joshy|Jose Mejuto]], [[User:BigChimp|Reinier Olislagers]], wp<br />
** [[GradControls|gradcontrols]]: [[User:EugenE|Eugen Bolz]]<br />
** [http://web.fastermac.net/~MacPgmr/OrphPort/OrphStatus.html orpheus]: [[User:Phil]]<br />
** [[iPhone Laz Extension]]: [[User:Skalogryyz|Dmitry Boyarintsev]]<br />
** [[iOS Designer]]: [[User:Loesje|Joost van der Sluis]]<br />
** [[PowerPDF|powerpdf]]: [[User:Jesusrmx|Jesús Reyes]], [[User:Christian|Christian Ulrich]]<br />
** [[LazRGBGraphics|rgbgraphics]]: [[User:Tombo|Tom Gregorovic]]<br />
** [[Parallel_procedures|multithreadprocs]]: [[User:Mattias2|Mattias Gärtner]]<br />
** [[RTFView|rtfview]]: [[User:Jesusrmx|Jesús Reyes]]<br />
** [[RXfpc|rx]]: Aleksy Lagunov, Andrew Ivanov<br />
** [[SvnClasses|svn]]: [[User:Vincent|Vincent Snijders]]<br />
** [[TParadoxDataSet|tparadoxdataset]]: [[User:Christian|Christian Ulrich]]<br />
** [[Turbopower Visual PlanIt|tvplanit]]: [[User:Christian|Christian Ulrich]]<br />
** [[VirtualTreeview|virtualtreeview]]: [[User:Christian|Christian Ulrich]]<br />
** [[Zlibar]]: [[User: AndrewH| Andrew Haines]]<br />
** [[Manual Docker|manualdocker]]: [[User:Skalogryyz|Dmitry Boyarintsev]]<br />
** [http://lazarusroad.blogspot.com/2007/02/children-of-port.html virtualtreeview-unstable]: [[User:Luizmed|Luiz Américo Pereira Câmara]]<br />
** [[GeckoPort|GeckoPort]]: [[User:Joshy|Jose Mejuto]], [[User:Loesje|Joost van der Sluis]]<br />
** [[Freetype|freetype]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
** [[THtmlPort|thtmlport]]: [[User:Phil]]<br />
** [[nvidia-widgets|nvidia-widgets]]: Darius Blaszyk<br />
** [[jujiboutils|jujiboutils]]: [[User:Jujibo|Julio Jiménez Borreguero]]<br />
** [[ZVDateTimeControls Package|ZVDateTimeCtrls]]: [[User:Zoran| Zoran Vučenović]]<br />
** [[SpkToolbar Package|SpkToolbar]]: [[User:Luizmed|Luiz Américo Pereira Câmara]]<br />
** [[cmdlinecfg]]: [[User:Skalogryyz|Dmitry Boyarintsev]]<br />
* [http://lazarus-ccr.svn.sourceforge.net/viewvc/lazarus-ccr/examples/ examples]<br />
** [[Perlin Noise|noise]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
** [[Executing External Programs#Using input and output of a TProcess|process]]: [[User:Vincent|Vincent Snijders]]<br />
** [[germesorders]] : [https://sourceforge.net/users/mageslayer/ MageSlayer]<br />
** [[Android Interface|androidlcl]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
* [[LCL Bindings|lclbindings]]: [[User:Sekelsenmat|Felipe Monteiro de Carvalho]]<br />
* [[Web Service Toolkit|wst]]: [[User:Inoussa|Inoussa Ouedraogo]]<br />
<br />
[[Category:Revision control]]<br />
[[Category:Lazarus-CCR]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Lazarus_IDE_Tools/de&diff=77302Lazarus IDE Tools/de2014-03-08T11:12:03Z<p>Dirk Fellenberg: Syntax korrigiert</p>
<hr />
<div>{{Lazarus IDE Tools}}<br />
<br />
== Überblick ==<br />
Die IDE verwendet eine Bibliothek von Werkzeugen zum Analysieren und Bearbeiten von Pascal-Quelltexten, genannt die "CodeTools". Diese Werkzeuge bieten Features wie Deklaration finden, Codevervollständigung, Isolation, Verschieben, Einfügen und Verschönern von Pascal-Quelltext. Diese Funktionen sparen Ihnen eine Menge Zeit und doppelte Arbeit. Sie können angepasst werden. Jedes Feature ist über Tastenkombinationen verfügbar (siehe Editoreinstellungen).<br />
<br />
Weil sie ausschließlich mit Quelltexten arbeiten und den Code von FPC, Delphi und Kylix verstehen, benötigen sie weder kompilierte Units noch einen installierten Borland Compiler. Sie können Delphi- und FPC-Code zur gleichen Zeit bearbeiten. Sie können sogar mit verschiedenen Delphi- und FPC-Versionen zur selben Zeit arbeiten. Dies macht die Portierung von Delphi-Code sehr viel einfacher.<br />
<br />
== Übersichtstabelle der IDE-Tastenkombinationen ==<br />
{|<br />
|-<br />
| [[Lazarus_IDE_Tools/de#Find Declaration|Declaration Jumping]] || {{keypress|Strg}}+Klick (springt zur Deklaration eines Typs oder einer Variablen)<br />
|-<br />
| [[Lazarus_IDE_Tools/de#Methodenspringen|Methodenspringen]] || {{keypress|Strg}}+{{keypress|Shift}}+{{keypress|Up}} (schaltet zwischen Definition und Rumpf einer Prozedur/Methode um)<br />
|-<br />
| [[Lazarus_IDE_Tools/de#Code-Schablonen|Code-Schablonen]] || {{keypress|Strg}}+{{keypress|J}}<br />
|-<br />
| [[Lazarus_IDE_Tools/de#Synchronbearbeitung|Synchronbearbeitung]] || {{keypress|Strg}}+{{keypress|J}} (bei ausgewähltem Text)<br />
|-<br />
| [[Lazarus_IDE_Tools/de#Codevervollständigung|Codevervollständigung]] (Klassenvervollständigung) || {{keypress|Strg}}+{{keypress|Shift}}+{{keypress|C}}<br />
|-<br />
| [[Lazarus_IDE_Tools/de#Bezeichner-Vervollständigung|Bezeichner-Vervollständigung]] || {{keypress|Strg}}+{{keypress|Space}}<br />
|-<br />
| [[Lazarus_IDE_Tools/de#Wortvervollständigung|Wortvervollständigung]] || {{keypress|Strg}}+{{keypress|W}}<br />
|-<br />
| [[Lazarus_IDE_Tools/de#Parameter-Hinweise|Parameter-Hinweise]] || {{keypress|Strg}}+{{keypress|Shift}}+{{keypress|Space}}<br />
|-<br />
| [[Lazarus_IDE_Tools/de#Inkrementelle Suche|Inkrementelle Suche]] || {{keypress|Strg}}+{{keypress|E}}<br />
|-<br />
| [[Lazarus_IDE_Tools/de#Bezeichner umbenennen|Bezeichner umbenennen]] || {{keypress|Strg}}+{{keypress|Shift}}+{{keypress|E}}<br />
|}<br />
<br />
==Methodenspringen==<br />
Um zwischen einem Prozedurrumpf (begin..end) und der Prozedurdefinition (procedure Name;) zu springen, verwenden Sie {{keypress|Strg}}+{{keypress|Shift}}+{{keypress|Nach oben}}.<br />
<br />
Zum Beispiel:<br />
<syntaxhighlight>interface<br />
<br />
procedure DoSomething; // Prozedurdefinition<br />
<br />
implementation<br />
<br />
procedure DoSomething; // Prozedurrumpf <br />
begin<br />
end;</syntaxhighlight><br />
<br />
Wenn der Cursor auf dem Prozedurrumpf ist und Sie {{keypress|Strg}}+{{keypress|Shift}}+{{keypress|Nach oben}} drücken, dann wird der Kursor zur Definition springen. Erneutes Drücken von {{keypress|Strg}}+{{keypress|Shift}}+{{keypress|Nach oben}} wird wieder zum Rumpf springen, nach 'begin'.<br />
<br />
Dies funktioniert ebenfalls zwischen Methoden (Prozeduren in Klassen).<br />
<br />
Hinweise:<br />
Methodenspringen springt zur selben Prozedur mit dem selben Namen und Parameterliste. Wenn es keine bestimmte Prozedur gibt, springt es zum besten Kandidaten und positioniert den Kursor auf dem ersten Unterschied. (Für Delphianer: Delphi kann dies nicht tun).<br />
<br />
Zum Beispiel eine Prozedur mit verschiedenen Parametertypen:<br />
<syntaxhighlight>interface<br />
<br />
procedure DoSomething(p: char); // Prozedurdefinition<br />
<br />
implementation<br />
<br />
procedure DoSomething(p: string); // Prozedurrumpf<br />
begin<br />
end;</syntaxhighlight><br />
<br />
Das Springen von der Definition zum Rumpf wird den Kursor auf dem 'string' Schlüsselwort positionieren. Dies kann verwendet werden für das Umbenennen von Methoden und/oder das Ändern von Parametern. <br />
<br />
Zum Beispiel:<br><br />
Sie benannten 'DoSomething' in 'MakeIt' um: <br />
<syntaxhighlight>interface<br />
<br />
procedure MakeIt; // Prozedurdefinition<br />
<br />
implementation<br />
<br />
procedure DoSomething; // Prozedurrumpf<br />
begin<br />
end;</syntaxhighlight><br />
<br />
Dann springen Sie von MakeIt zum Rumpf. Die IDE sucht nach einem passenden Rumpf, findet keinen, und sucht daher nach einem Kandidaten. Weil Sie nur eine Prozedur umbenannt haben, gibt es exakt einen Rumpf ohne Definition (DoSomething) und daher wird sie zu DoSomething springen und den Kursor rechts neben 'DoSomething' positionieren. Dann können Sie sie dort auch umbenennen. Das funktioniert ebenfalls für Parameter.<br />
<br />
== Include-Dateien ==<br />
Include-Dateien sind Dateien, die mit der ($I Dateiname) oder ($INCLUDE Dateiname) Compilerdirektive in die Quellen eingefügt werden. Lazarus und FPC verwenden oft Include-Dateien, um Redundanz zu reduzieren und unlesbare ($IFDEF) Konstrukte zu vermeiden um verschiedene Plattformen zu unterstützen.<br />
<br />
Im Gegensatz zu Delphi bietet die Lazarus IDE volle Unterstützung für Include-Dateien. Sie können zum Beispiel von der Methode in der .pas Datei zum Methodenrumpf in der Include-Datei springen. Alle CodeTools wie ''Codevervollständigung'' berücksichtigen Include-Dateien als spezielle Schranken.<br />
<br />
Zum Beispiel: Wenn die ''Codevervollständigung'' einen neuen Methodenrumpf hinzufügt hinter anderen Methodenrümpfen, behält sie beide in der selben Datei. Auf diese Weise können Sie ganze Klassenimplementierungen in Include-Dateien verwenden, wie es die LCL für nahezu alle Bedienelemente tut.<br />
<br />
Aber es gibt eine Anfängerfalle:<br />
Wenn Sie eine Include-Datei zum ersten Mal öffnen und ''method jumping'' oder ''find declaration'' ausprobieren, erhalten Sie eine Fehlermeldung. Die IDE weiß nicht, zu welcher Unit die Include-Datei gehört. Sie müssen die Unit zuerst öffnen.<br />
<br />
Sobald die IDE die Unit analysiert, wird sie die Include-Direktive dort finden und die IDE wird sich an diese Beziehung erinnern. Sie wird diese Informationen beim Beenden (oder beim Speichern des Projekts) speichern in der Datei ~/.lazarus/includelinks.xml. Wenn Sie diese Include-Datei das nächste Mal öffnen und eine 'find declaration' durchführen, wird die IDE die Unit intern öffnen und das Springen wird funktionieren.<br />
Sie können die IDE auch direkt hinweisen mit <br />
<syntaxhighlight>{%mainunit yourunit.pas}</syntaxhighlight> <br />
am Anfang Ihrer yourinclude.inc.<br />
<br />
Dieser Mechanismus hat natürlich Grenzen. Einige Include-Dateien sind zweimal oder mehrfach einbezogen. Zum Beispiel: lcl/include/winapih.inc.<br />
<br />
Das Springen von den Prozedur-/Methodendefinitionen in diese Include-Datei zu den Rümpfen hängt von Ihren letzten Aktionen ab. Wenn Sie an lcl/lclintf.pp gearbeitet haben dann wird die IDE zu winapi.inc springen. Wenn Sie an lcl/interfacebase.pp gearbeitet haben, dann wird sie zu lcl/include/interfacebase.inc springen (oder einer der anderen Include-Dateien). Wenn Sie an beiden arbeiten, dann können Sie verwirrt werden. ;)<br />
<br />
==Code-Schablonen==<br />
Code-Schablonen konvertieren einen Bezeichner in einen Text oder Code-Fragment.<br />
<br />
Die Code-Schablonen Vorgabetastenkombination ist {{keypress|Strg}}+{{keypress|J}}. Sie können einen Bezeichner eintippen, {{keypress|Strg}}+{{keypress|J}} drücken und der Bezeichner wird durch den Text ersetzt, der für den Bezeichner definiert ist. Code-Schablonen können definiert werden in Einstellungen -> Code-Schablonen.<br />
<br />
Beispiel:<br />
Schreiben Sie den Bezeichner 'classf', lassen Sie den Kursor hinter dem 'f' stehen und drücken Sie {{keypress|Strg}}+{{keypress|J}}. Das 'classf' wird ersetzt durch<br />
<syntaxhighlight>T = class(T)<br />
private<br />
<br />
public<br />
constructor Create;<br />
destructor Destroy; override;<br />
end;</syntaxhighlight><br />
<br />
und der Cursor ist hinter dem 'T'.<br />
Sie können die Liste der Vorlagen abrufen, in dem Sie den Kursor an eine freie Stelle positionieren (nicht auf einem Bezeichner) und {{keypress|Strg}}+{{keypress|J}} drücken. Die Liste der Code-Schablonen wird auftauchen. Verwenden Sie die Kursortasten oder tippen Sie einige Buchstaben um eine auszuwählen. {{keypress|Eingabe}} erzeugt die gewählte Vorlage und {{keypress|Escape}}schließt das Popup-Fenster.<br />
<br />
Die größten Zeitsparer sind die Schablonen 'b'+{{keypress|Strg}}+{{keypress|J}} für begin..end.<br />
<br />
== Parameter-Hinweise ==<br />
<br />
Parameter-Hinweise zeigen eine Hinweisbox mit den Parameter-Deklarationen für die aktuelle Parameterliste.<br />
<br />
Zum Beispiel<br />
<br />
<syntaxhighlight> Canvas.FillRect(|);</syntaxhighlight><br />
<br />
Platzieren Sie den Cursor in den Klammern und drücken Sie {{keypress|Strg}}+{{keypress|Shift}}+{{keypress|Leertaste}}. Eine Hinweisbox erscheint mit den Parametern von FillRect.<br />
<br />
[[Image:Parameterhints1.png]]<br />
<br />
Seit Version 0.9.31 gibt es eine Schaltfläche rechts neben jeder Deklaration um fehlende Parameters einzufügen. Diese kopiert die Parameternamen aus der ausgewählten Deklaration an die Kursorposition.<br />
<br />
[[Image:Parameterhints2.png]]<br />
<br />
Tipp: Benutzen Sie die [[#Variable Declaration Completion|Variable Declaration Completion]] um Variablen zu deklarieren.<br />
<br />
Beachten Sie: Der Name des Tastenkürzels ist "Code-Context anzeigen".<br />
<br />
== Inkrementelle Suche ==<br />
<br />
Die inkrementelle Suche ändert die Statuszeile des Quelltexteditors. Geben Sie ein paar Zeichen ein und der Editor sucht und markiert sofort alle Fundstellen im Text. Das Tastaturkürzel ist {{keypress|Strg}}+{{keypress|E}}.<br />
*Zum Beispiel: Sie drücken {{keypress|A}}, sucht und markiert alle Fundstellen von 'A'.<br />
*Dann drücken Sie {{keypress|T}} und alle Fundstellen von 'at' sind markiert usw.<br />
*Sie springen zur nächsten Fundstelle mit {{keypress|F3}} (oder {{keypress|Strg}}+{{keypress|E}} während der Suche) und zur vorigen Fundstelle mit {{keypress|Umschalt}}+{{keypress|F3}}.<br />
*{{keypress|Backspace}} entfernt das letzte Zeichen<br />
*{{keypress|Eingabe}} stoppt die Suche ohne eine neue Zeile im Editor.<br />
*Sie nehmen die letzte Suche erneut auf mit einem zweiten {{keypress|Strg}}+{{keypress|E}}, sofort nach dem Start der Suche mit {{keypress|Strg}}+{{keypress|E}}. Das gilt solange das Suchfeld noch leer ist.<br />
*Einfügen mit {{keypress|Strg}}+{{keypress|V}} hängt den Text aus der Zwischenablage an den aktuellen Suchtext an (seit Lazarus 0.9.27 r19824).<br />
<br />
=== Hinweis: Schnelle Suche nach einem Bezeichner mit der inkrementellen Suche ===<br />
<br />
*Stellen Sie den Textkursor auf den Bezeichner. (Wählen Sie nichts aus!)<br />
*Drücken Sie {{keypress|Strg}}+{{keypress|C}}. Der Editor wählt den Bezeichner aus und kopiert ihn in die Zwischenablage<br />
*Drücken Sie {{keypress|Strg}}+{{keypress|E}} - startet die inkrementelle Suche<br />
*Drücken Sie {{keypress|Strg}}+{{keypress|V}} - sucht nach dem Bezeichner (seit Version 0.9.27)<br />
*Mit {{keypress|F3}} und {{keypress|Umschalt}}+{{keypress|F3}} springen Sie zum nächsten/vorigen Fund.<br />
*Mit einer beliebigen Taste (beispielsweise Kursor links oder rechts) beenden Sie die Suche<br />
<br />
==Synchronbearbeitung==<br />
<br />
Die Synchronbearbeitung ermöglicht es Ihnen, alle Fundstellen eines Wortes gleichzeitig (synchronisiert) zu bearbeiten. Sie bearbeiten einfach das Wort an einer Stelle und gleichzeitig mit Ihren Eingaben werden auch alle anderen Fundstellen des Wortes aktualisiert.<br />
<br />
Die Synchronbearbeitung verarbeitet alle Worte in einem ausgewählten Bereich:<br />
* Selektieren Sie einen Textblock<br />
* Drücken Sie {{keypress|Strg}}+{{keypress|J}} oder klicken Sie auf das Symbol in der Randleiste. (Das funktioniert nur, wenn Worte in der Auswahl mehr als einmal auftreten.)<br />
* Benutzen Sie die {{keypress|Tab}}-Taste, um das zu bearbeitende Wort auszuwählen (wenn einige verschiedene Wörter mehrfach auftreten).<br />
* Bearbeiten Sie das Wort.<br />
* Drücken Sie {{keypress|Esc}} zum Beenden<br />
<br />
Sehen Sie sich [[New_IDE_features_since#Syncron-Edit|hier]] ein animiertes Beispiel an.<br />
<br />
* Anmerkung: {{keypress|Strg}}+{{keypress|J}} wird auch beim Bearbeiten von Vorlagen benutzt. Die Bedeutung ändert sich, wenn Sie einen Text auswählen.<br />
<br />
== Suche nächste / vorhergehende Fundstelle des Wortes ==<br />
<br />
Die zwei Funktionen sind im Kontextmenü des Quelltexteditors zu finden<br />
<br />
*Quelltexteditor / Kontextmenü / Suchen / Nächste Fundstelle des Wortes<br />
*Quelltexteditor / Kontextmenü / Suchen / Vorhergehende Fundstelle des Wortes<br />
<br />
Und Sie können diesen Funktionen in den Editoreinstellungen ein Tastenkürzel zuweisen.<br />
<br />
== Codevervollständigung ==<br />
Die Codevervollständigung ist im IDE-Menü zu finden unter Bearbeiten -> Quelltext vervollständigen und hat das Standardkürzel {{keypress|Strg|Shift|C}}. <br />
<br />
Für Delphianer:<br />
Delphi bezeichnet mit "Codevervollständigung" die Funktion, die die Liste der Bezeichner an der aktuellen Quellenposition zeigt ({{keypress|Strg|Leertaste}}). Unter Lazarus wird dies ''Bezeichnervervollständigung'' genannt.<br />
<br />
''Codevervollständigung'' kombiniert verschiedene mächtige Funktionen. Beispiele:<br />
* [[#Class Completion|Class Completion]]: komplettiert Eigenschaften; fügt Methodenrümpfe, private Variablen und private Zugriffsmethoden hinzu<br />
* [[#Forward Procedure Completion|Forward Procedure Completion]]: fügt Prozedurenrümpfe hinzu<br />
* [[#Event Assignment Completion|Event Assignment Completion]]: komplettiert Ereigniszuweisungen; fügt Methodendefinition und -rumpf hinzu<br />
* [[#Variable Declaration Completion|Variable Declaration Completion]]: fügt lokale Variablendefinitionen hinzu <br />
* [[#Reversed Class Completion|Reversed Class Completion]]: fügt Methoden-Deklarationen für Methodenrümpfe hinzu<br />
* [[#Procedure Call Completion|Procedure Call Completion]]: fügt eine neue Prozedur hinzu<br />
* [[#Reversed Procedure Completion|Reversed procedure completion]]: fügt Deklarationen für Prozedur-/Funktionsrümpfe hinzu<br />
<br />
Welche Funktion genutzt wird, hängt von der Kursorposition im Editor ab und wird unten beschrieben.<br />
<br />
Die Codevervollständigung ist im IDE-Menü zu finden unter Bearbeiten -> Quelltext vervollständigen und hat das Standardkürzel {{keypress|Strg|Shift|C}}. <br />
<br />
===Class Completion===<br />
<br />
Das mächtigste Codevervollständigungs-Feature ist ''Class Completion''. Sie schreiben eine Klasse, fügen die Methoden und Eigenschaften hinzu und Codevervollständigung wird die Methodenrümpfe hinzufügen, die Methoden/Variablen des Eigenschaftszugriffs und die private Variablen. <br />
<br />
Zum Beispiel: Erzeugen Sie eine Klasse (siehe Code-Schablonen, um einige Tipparbeit zu sparen): <br />
<br />
<syntaxhighlight>TExample = class(TObject)<br />
public<br />
constructor Create;<br />
destructor Destroy; override;<br />
end;</syntaxhighlight><br />
<br />
Positionieren Sie den Kursor irgendwo in der Klasse und drücken Sie {{keypress|Strg|Shift|C}}. Dies wird die fehlenden Methodenrümpfe erzeugen und den Kursor zu dem ersten erzeugten Methodenrumpf bewegen, so dass Sie jetzt mit dem Schreiben des Klassencodes beginnen können: <br />
<br />
<syntaxhighlight>{ TExample }<br />
<br />
constructor TExample.Create;<br />
begin<br />
|<br />
end;<br />
<br />
destructor TExample.Destroy;<br />
begin<br />
inherited Destroy;<br />
end;</syntaxhighlight><br />
<br />
Anmerkung: Das '|' ist der Kursor und nicht hinzugefügt. <br />
<br />
Hinweis: Sie können zwischen einer Methode und ihrem Rumpf springen mit {{keypress|Strg|Shift|Nach oben}}. <br />
<br />
Sie können sehen, dass die IDE auch den 'inherited Destroy' Aufruf hinzugefügt hat. Dies passiert, wenn es ein 'override' Schlüsselwort in der Klassendefinition gibt. <br />
<br />
Jetzt fügen Sie eine Methode DoSomething hinzu: <br />
<br />
<syntaxhighlight>TExample = class(TObject)<br />
public<br />
constructor Create;<br />
procedure DoSomething(i: integer);<br />
destructor Destroy; override;<br />
end;</syntaxhighlight><br />
<br />
Dann drücken Sie {{keypress|Strg|Shift|C}} und die IDE wird hinzufügen: <br />
<br />
<syntaxhighlight>procedure TExample.DoSomething(i: integer);<br />
begin<br />
|<br />
end;</syntaxhighlight><br />
<br />
Sie sehen, der neue Methodenrumpf wurde zwischen Create und Destroy eingefügt, exakt wie in der Klassendefinition. So behalten auch die Methodenrümpfe die gleiche logische Ordnung bei (wie von Ihnen festgelegt). Sie legen die Einfügerichtlinien fest in Einstellungen -> Codetools Einstellungen -> Quelltexterzeugung. <br />
<br />
'''Complete Properties'''<br><br />
Fügen Sie eine Eigenschaft 'AnInteger' hinzu:<br />
<syntaxhighlight>TExample = class(TObject)<br />
public<br />
constructor Create;<br />
procedure DoSomething(i: integer);<br />
destructor Destroy; override;<br />
property AnInteger: Integer;<br />
end;</syntaxhighlight><br />
<br />
Drücken Sie Strg+Shift+C und Sie erhalten:<br />
<syntaxhighlight>procedure TExample.SetAnInteger(const AValue: integer);<br />
begin<br />
|if FAnInteger=AValue then exit;<br />
FAnInteger:=AValue;<br />
end;</syntaxhighlight><br />
<br />
Die Codevervollständigung hat den Schreibzugriff geändert und den üblichen Code ergänzt.<br />
Springen Sie mit {{keypress|Strg|Shift|Nach oben}} zur Klasse, um die neue Klasse ganz zu sehen:<br />
<syntaxhighlight>TExample = class(TObject)<br />
private<br />
FAnInteger: integer;<br />
procedure SetAnInteger(const AValue: integer);<br />
public<br />
constructor Create;<br />
procedure DoSomething(i: integer);<br />
destructor Destroy; override;<br />
property AnInteger: integer read FAnInteger write SetAnInteger;<br />
end;</syntaxhighlight><br />
<br />
Die Eigenschaft wurde um einen Lese- und Schreibzugriff erweitert. Die Klasse erhielt den neuen Abschnitt 'private' mit einer Variable 'FAnInteger' und der Methode 'SetAnInteger'.<br />
Es ist eine allgemein übliche Delphi-Stil-Regel, den privaten Variablen ein 'F' und der write-Methode ein 'Set' voranzustellen. Wenn Sie das nicht mögen, können Sie es ändern unter Einstellungen -> Codetools Einstellungen -> Quelltexterzeugung.<br />
<br />
Erzeugen einer Eigenschaft 'read only':<br />
<syntaxhighlight>property PropName: PropType read;</syntaxhighlight><br />
wird erweitert zu<br />
<syntaxhighlight>property PropName: PropType read FPropName;</syntaxhighlight><br />
Erzeugen einer Eigenschaft 'write only':<br />
<syntaxhighlight>property PropName: PropType write;</syntaxhighlight><br />
wird erweitert zu<br />
<syntaxhighlight>property PropName: PropType write SetPropName;</syntaxhighlight><br />
Erzeugen einer Eigenschaft 'read only' mit einer Read-Methode:<br />
<syntaxhighlight>property PropName: PropType read GetPropName;</syntaxhighlight><br />
wird beibehalten und eine Funktion 'GetPropName' wird angefügt:<br />
<syntaxhighlight>function GetpropName: PropType;</syntaxhighlight><br />
Erzeugen einer Eigenschaft mit einem stored-Modifizierer:<br />
<syntaxhighlight>property PropName: PropType stored;</syntaxhighlight><br />
wird erweitert zu<br />
<syntaxhighlight>property PropName: PropType read FPropName write SetPropName stored PropNameIsStored;</syntaxhighlight><br />
Weil 'stored' für das Streaming benutzt wird, werden automatisch auch die read- und write-Modifizierer angefügt.<br />
<br />
Hinweis:<br />
Die ''Bezeichnervervollständigung'' erkennt auch unvollständige Eigenschaften und wird die Standardnamen vorschlagen. Zum Beispiel:<br />
<syntaxhighlight>property PropName: PropType read |;</syntaxhighlight><br />
Platzieren Sie den Kursor eine Leerstelle hinter dem 'read'-Schlüsselwort und drücken Strg+Space für die Bezeichnervervollständigung. Diese wird Ihnen die Variable 'FPropName' und die Prozedur 'SetPropName' präsentieren.<br />
<br />
===Forward Procedure Completion===<br />
Die ''Forward Procedure Completion'' ist ein Teil der Codevervollständigung und fügt fehlende Prozedurrümpfe hinzu. Sie wird aufgerufen, wenn der Kursor auf einer vorwärts definierten Prozedur ist.<br />
<br />
Zum Beispiel:<br />
Fügen Sie eine neue Prozedur zum Interface-Abschnitt hinzu:<br />
<syntaxhighlight>procedure DoSomething;</syntaxhighlight><br />
Platzieren Sie den Kursor darauf und drücken Sie {{keypress|Strg|Shift|C}} für Codevervollständigung. Es wird im Implementation-Abschnitt erzeugen:<br />
<syntaxhighlight>procedure DoSomething;<br />
begin<br />
|<br />
end;</syntaxhighlight><br />
<br />
Hinweis: Sie können zwischen einer Prozedurdefinition und ihrem Rumpf springen mit {{keypress|Strg|Shift|Nach oben}}.<br />
<br />
Der neue Prozedurrumpf wird vor den Klassenmethoden eingefügt. Wenn es bereits einige Prozeduren im Interface-Abschnitt gibt, versucht die IDE die Ordnung einzuhalten. Zum Beispiel:<br />
<syntaxhighlight>procedure Proc1;<br />
procedure Proc2; // neue Prozedur<br />
procedure Proc3;</syntaxhighlight><br />
<br />
Wenn die Rümpfe von Proc1 und Proc3 bereits existieren, dann wird der Proc2 Rumpf zwischen den Rümpfen von Proc1 und Proc3 eingefügt. Dieses Verhalten kann eingestellt werden in Einstellungen -> CodeTools Einstellungen -> Quelltexterzeugung.<br />
<br />
Mehrere Prozeduren:<br />
<syntaxhighlight>procedure Proc1_Old; // Rumpf existiert<br />
procedure Proc2_New; // Rumpf existiert nicht<br />
procedure Proc3_New; // "<br />
procedure Proc4_New; // "<br />
procedure Proc5_Old; // Rumpf existiert</syntaxhighlight><br />
<br />
Die Codevervollständigung wird alle 3 Prozedurrümpfe hinzufügen (Proc2_New, Proc3_New, Proc4_New).<br />
<br />
Warum wird das ''Forward Procedure Completion'' genannt?<br />
<br />
Weil es nicht nur für Prozeduren funktioniert, die im Interface definiert sind, sondern auch für Prozeduren mit dem "forward"-Bezeichner. Und weil die CodeTools Prozeduren im Interface so behandeln als hätten sie einen impliziten "forward"-Bezeichner.<br />
<br />
===Event Assignment Completion===<br />
Die "Event Assignment Completion" ist ein Teil der ''Codevervollständigung'' und komplettiert eine einzelne Ereignis:=| Anweisung. Sie wird aufgerufen, wenn der Kursor hinter einer Ereigniszuweisung steht.<br />
<br />
Zum Beispiel:<br />
In einer Methode, sagen wir dem FormCreate Ereignis, fügen wir eine Zeile 'OnPaint:=' hinzu:<br />
<syntaxhighlight>procedure TForm1.Form1Create(Sender: TObject);<br />
begin<br />
OnPaint:=|<br />
end;</syntaxhighlight><br />
<br />
Das '|' ist der Kursor und sollte nicht eingegeben werden.<br />
Dann drücken sie Strg+Shift+C für die ''Codevervollständigung''. Die Anweisung wird komplettiert zu<br />
<syntaxhighlight>OnPaint:=@Form1Paint;</syntaxhighlight><br />
Eine neue Methode Form1Paint wird zur Klasse TForm1 hinzugefügt. Dann wird die ''class completion'' gestartet und Sie erhalten:<br />
<syntaxhighlight>procedure TForm1.Form1Paint(Sender: TObject);<br />
begin<br />
|<br />
end;</syntaxhighlight><br />
Das funktioniert wie das Hinzufügen von Methoden im Objektinspektor.<br />
<br />
Anmerkung:<br><br />
Sie müssen den Kursor hinter dem ':=' Zuweisungsoperator platzieren. Wenn Sie den Kursor auf dem Bezeichner platzieren (z.B. OnPaint) wird die Codevervollständigung die "Local Variable Completion" aufrufen, was fehlschlägt, weil OnPaint bereits definiert ist.<br />
<br />
Hinweis:<br><br />
Sie können den neuen Methodennamen selbst definieren. Zum Beispiel:<br />
<syntaxhighlight>OnPaint:=@ThePaintMethod;</syntaxhighlight><br />
<br />
===Variable Declaration Completion===<br />
Die "Variable Declaration Completion" ist ein Teil der Codevervollständigung und fügt eine lokale Variablendefinition zu einer Identifier:=Term; Anweisung hinzu. Sie wird aufgerufen, wenn der Kursor auf dem Bezeichner in einer Zuweisung oder einem Parameter ist.<br />
<br />
Zum Beispiel:<br />
<syntaxhighlight>procedure TForm1.Form1Create(Sender: TObject);<br />
begin<br />
i:=3;<br />
end;</syntaxhighlight><br />
Platzieren Sie den Kursor auf dem 'i' oder genau dahinter. Dann drücken Sie {{keypress|Strg|Shift|C}} für die Codevervollständigung und Sie erhalten:<br />
<syntaxhighlight>procedure TForm1.Form1Create(Sender: TObject);<br />
var<br />
i: Integer;<br />
begin<br />
i:=3;<br />
end;</syntaxhighlight><br />
<br />
Die CodeTools prüfen zuerst, ob der Bezeichner 'i' bereits definiert ist und wenn nicht werden sie die Deklaration 'var i: integer;' hinzufügen. Der Typ des Bezeichners wird erraten vom Ausdruck rechts des ':=' Zuweisungsoperators. Zahlen wie die 3 sind mit Integer vorbelegt.<br />
<br />
Ein anderes Beispiel:<br />
<syntaxhighlight>type<br />
TWhere = (Behind, Middle, InFront);<br />
<br />
procedure TForm1.Form1Create(Sender: TObject);<br />
var<br />
a: array[TWhere] of char;<br />
begin<br />
for Where:=Low(a) to High(a) do writeln(a[Where]);<br />
end;</syntaxhighlight><br />
<br />
Platzieren Sie den Kursor auf 'Where' und drücken Sie {{keypress|Strg|Shift|C}} für die Codevervollständigung. Sie erhalten:<br />
<syntaxhighlight> procedure TForm1.Form1Create(Sender: TObject);<br />
var<br />
a: array[TWhere] of char;<br />
Where: TWhere;<br />
begin<br />
for Where:=Low(a) to High(a) do writeln(a[Where]);<br />
end;</syntaxhighlight><br />
<br />
Seit Version 0.9.11 komplettiert Lazarus auch Parameter. Zum Beispiel<br />
<syntaxhighlight> procedure TForm1.FormPaint(Sender: TObject);<br />
begin<br />
with Canvas do begin<br />
Line(x1,y1,x2,y2);<br />
end;<br />
end;</syntaxhighlight><br />
<br />
Platzieren Sie den Kursor auf 'x1' und drücken Sie {{keypress|Strg|Shift|C}} für die Codevervollständigung. Sie erhalten:<br />
<syntaxhighlight> procedure TForm1.FormPaint(Sender: TObject);<br />
var<br />
x1: integer;<br />
begin<br />
with Canvas do begin<br />
Line(x1,y1,x2,y2);<br />
end;<br />
end;</syntaxhighlight><br />
<br />
===Procedure Call Completion===<br />
Die Codevervollständigung kann auch eine neue Prozedur aus dem Prozeduraufruf selbst erzeugen.<br />
<br />
Angenommen, Sie haben gerade die Anweisung "DoSomething(Width);" geschrieben<br />
<syntaxhighlight>procedure SomeProcedure;<br />
var<br />
Width: integer;<br />
begin<br />
Width:=3;<br />
DoSomething(Width);<br />
end;</syntaxhighlight><br />
<br />
Platzieren Sie den Kursor über dem Bezeichner "DoSomething" und drücken Sie {{keypress|Strg|Shift|C}}. Sie erhalten:<br />
<br />
<syntaxhighlight>procedure DoSomething(aWidth: LongInt);<br />
begin<br />
<br />
end;<br />
<br />
procedure SomeProcedure;<br />
var<br />
Width: integer;<br />
begin<br />
Width:=3;<br />
DoSomething(Width);<br />
end;</syntaxhighlight><br />
<br />
Es werden derzeit noch keine Funktionen oder Methoden erzeugt.<br />
<br />
===Reversed Class Completion===<br />
<br />
"Reversed Class Completion" ist ein Teil der '''Codevervollständigung''' und fügt eine private Methodendeklaration zum aktuellen Methodenrumpf hinzu. Sie wird aufgerufen, wenn der Cursor in einem Methodenrumpf ist, der noch nicht in der Klasse definiert wurde.<br />
Dieses Feature ist seit Lazarus 0.9.21 verfügbar.<br />
<br />
Zum Beispiel:<br />
<syntaxhighlight> procedure TForm1.DoSomething(Sender: TObject);<br />
begin<br />
end;</syntaxhighlight><br />
<br />
Die Methode DoSomething ist noch nicht in TForm1 deklariert. Drücken Sie {{keypress|Strg|Shift|C}} und die IDE wird "procedure DoSomething(Sender: TObject);" zu den privaten Methoden von TForm1 hinzufügen.<br />
<br />
Für Delphianer:<br />
Die Klassenergänzung arbeitet unter Lazarus immer in einer Richtung: Von dem Klasseninterface zur Implementation oder rückwärts/umgekehrt von der Klassenimplementation zum Interface. Delphi ruft immer beide Richtungen auf. Das Delphi-Verfahren hat den Nachteil, dass bei einem Rechtschreibfehler leicht eine neue Methodenvorlage erzeugt wird ohne Benachrichtigung.<br />
<br />
===Kommentare und Codevervollständigung===<br />
Die Codevervollständigung versucht die Kommentare dort zu behalten, wo sie hingehören. <br />
Zum Beispiel:<br />
<syntaxhighlight> FList: TList; // list of TComponent<br />
FInt: integer;</syntaxhighlight><br />
Wenn eine neue Variable zwischen FList und FInt eingesetzt wird, dann wird der Kommentar in der FList Zeile beibehalten. Das selbe gilt für<br />
<syntaxhighlight> FList: TList; { list of TComponent<br />
Dies ist ein Kommentar über mehrere Zeilen, beginnend<br />
in der FList-Zeile. Die CodeTools nehmen an, er gehöre <br />
zu der FList-Zeile und brechen diese Beziehung nicht<br />
auf. Der Code wird hinter dem Kommentar eingefügt. }<br />
FInt: integer;</syntaxhighlight><br />
Wenn der Kommentar in der nächsten Zeile startet, dann wird er behandelt, wie wenn er zum nachfolgenden Code gehört. Zum Beispiel:<br />
<syntaxhighlight> FList: TList; // list of TComponent<br />
{ Dieser Kommentar gehört zur nachfolgenden Anweisung. <br />
Neuer Code wird oberhalb des Kommentars eingefügt und <br />
hinter dem Kommentar der FList-Zeile. }<br />
FInt: integer;</syntaxhighlight><br />
<br />
===Method update===<br />
Normalerweise fügt die Klassenergänzung alle fehlenden Methodenrümpfe ein. (Seit Version 0.9.27) Falls sich aber genau eine Methode zwischen Klassendeklaration und Rümpfen unterscheidet, dann wird der Methodenrumpf aktualisiert. Zum Beispiel: Sie haben eine Methode ''DoSomething''.<br />
<syntaxhighlight> public<br />
procedure DoSomething;<br />
end;<br />
<br />
procedure TForm.DoSomething;<br />
begin<br />
end;</syntaxhighlight><br />
<br />
Fügen Sie jetzt einen Parameter hinzu:<br />
<br />
<syntaxhighlight> public<br />
procedure DoSomething(i: integer);<br />
end;</syntaxhighlight><br />
<br />
und rufen Sie die Codevervollständigung auf mit ({{keypress|Strg|Shift|C}}). Der Methodenrumpf wird aktualisiert und der neue Parameter wird kopiert:<br />
<br />
<syntaxhighlight>procedure TForm.DoSomething(i: integer);<br />
begin<br />
end;</syntaxhighlight><br />
<br />
==Refactoring==<br />
<br />
===Invert Assignments===<br />
<br />
;Kurz gefasst: "Invert Assignments" nimmt einige ausgewählte Pascal-Anweisungen und invertiert alle Zuweisungen aus diesem Code. Dieses Werkzeug ist hilfreich für das Umwandeln eines "Speicher"-Codes in einen "Lade"-Code und umgekehrt.<br />
<br />
Beispiel:<br><br />
<syntaxhighlight>procedure DoSomething;<br />
begin<br />
AValueStudio:= BValueStudio;<br />
AValueAppartment :=BValueAppartment;<br />
AValueHouse:=BValueHouse;<br />
end;</syntaxhighlight><br />
<br />
Wählen Sie die Zeilen mit den Zuweisungen aus (zwischen begin und end) und führen Sie "Invert Assignments" aus. Alle Zuweisungen werden invertiert und die Einrückung wird automatisch hinzugefügt. Zum Beispiel:<br />
<br />
Resultat:<br />
<syntaxhighlight>procedure DoSomething;<br />
begin<br />
BValueStudio := AValueStudio;<br />
BValueAppartment := AValueAppartment;<br />
BValueHouse := AValueHouse;<br />
end;</syntaxhighlight><br />
<br />
=== Enclose Selection ===<br />
Wählen Sie einigen Text aus und rufen Sie die Vervollständigung auf. In dem aufscheinenden Dialog können Sie auswählen, ob der selektierte Text in '''try..finally''' oder einen der vielen anderen üblichen Blöcke eingeschlossen werden soll.<br />
<br />
===Bezeichner umbenennen===<br />
Stellen Sie den Kursor auf einen Bezeichner und rufen Sie die Vervollständigung auf. Es erscheint ein Dialog, wo Sie den Suchbereich und den neuen Namen festlegen können. <br />
* Es werden alle Vorkommen umbenannt und zwar nur jene, die tatsächlich diese Deklaration verwenden. Das bedeutet, dass nicht automatisch alle Deklarationen mit dem selben Namen umbenannt werden. <br />
* Und es wird zuerst auf Namenskonflikte überprüft.<br />
* Beschränkungen: Das funktioniert nur mit Pascal-Quellen, benennt keine Dateinamen um und bearbeitet weder lfm/lrs-Dateien noch lazdoc-Dateien.<br />
<br />
===Find Identifier References===<br />
Stellen Sie den Kursor auf einen Bezeichner und rufen Sie die Vervollständigung auf. Es erscheint ein Dialog, wo Sie den Suchbereich festlegen können. Die IDE sucht dann nach allen Vorkommen und nur solchen, die tatsächlich diese Deklaration verwenden. Das bedeutet, dass nicht andere Deklarationen mit dem selben Namen angezeigt werden.<br />
<br />
=== Show abstract methods ===<br />
Dieses Merkmal listet und ergänzt automatisch virtuelle, abstrakte Methoden, die noch implementiert werden müssen.<br />
Stellen Sie den Kursor auf eine Klassendeklaration und rufen Sie die Vervollständigung auf. Falls es fehlende abstrakte Methoden gibt, werden diese in einem Dialog aufgelistet. Wählen Sie die zu implementierende Methode aus und die IDE erzeugt eine Methodenschablone.<br />
<br />
===Prozedur extrahieren===<br />
<br />
Siehe [[IDE_Window:_Extract_Procedure|Prozedur extrahieren]]<br />
<br />
==Find Declaration==<br />
Positionieren Sie den Kursor auf einem Bezeichner und starten Sie ''Find Declaration''. Das wird die Deklaration dieses Bezeichners suchen, die Datei öffnen und zu ihr springen. Falls der Kursor bereits auf der Deklaration ist, erfolgt ein Sprung zur vorherigen Deklaration mit dem selben Name. Dies erlaubt es, Neudefinitionen und Overrides zu finden.<br />
<br />
Jede ''find declaration'' setzt einen Sprungpunkt. Das bedeutet, Sie springen mit ''find declaration'' zur Deklaration und einfach zurück mit Suche -> Zurückspringen.<br />
<br />
Es gibt einige Unterschiede zu Delphi:<br />
Die CodeTools arbeiten mit den Quellen, den normalen Pascal-Regeln folgend, anstelle der Verwendung der Compiler-Ausgaben. Der Compiler liefert den finalen Typ zurück. Die CodeTools sehen die Quellen und alle Schritte dazwischen. Zum Beispiel:<br />
<br />
Die ''Visible'' Eigenschaft wird zuerst in TControl (controls.pp) definiert, dann neu definiert in TCustomForm und letztlich in TForm neu definiert.<br />
Das Aufrufen von ''find declaration'' auf Visible wird Sie zuerst zu Visible in TForm bringen. Dann können Sie ''Find Declaration'' erneut aufrufen um zu Visible in TCustomForm zu springen und nochmals, um zu Visible in TControl zu springen.<br />
<br />
Das selbe gilt für Typen wie TColor.<br />
Für den Compiler ist es einfach ein 'longint'. Aber in den Quellen ist es definiert als<br />
<syntaxhighlight>TGraphicsColor = -$7FFFFFFF-1..$7FFFFFFF;<br />
TColor = TGraphicsColor;</syntaxhighlight><br />
<br />
Und das selbe für '''forward defined classes''':<br />
Zum Beispiel gibt es in TControl eine private Variable<br />
<syntaxhighlight>FHostDockSite: TWinControl;</syntaxhighlight><br />
Find declaration auf TWinControl springt zur forward definition<br />
<syntaxhighlight>TWinControl = class;</syntaxhighlight><br />
Und ein erneuter Aufruf springt zur realen Implementierung<br />
<syntaxhighlight>TWinControl = class(TControl)</syntaxhighlight><br />
Auf diese Weise können Sie jeden Bezeichner aufspüren und jede Überladung finden.<br />
<br />
'''Tipps:''' <br />
* Sie können zurück springen mit {{keypress|Strg|H}}.<br />
* Sie können alle besuchten Orte anzeigen/erreichen mittels Menü: Ansicht / Sprungliste anzeigen ...<br />
* Mit einer 5-Tasten-Maus können Sie die beiden Extratasten dazu verwenden, vorwärts/rückwärts zu den besuchten Orten zu gehen<br />
:(Sie können die Tastenbelegung ändern mit Menü: Einstellungen / Maus / Erweitert <br />
Siehe auch: [[IDE_Window:_EditorMouseOptionsAdvanced#Change_History_Jumps_for_3_button_Mouse_.28follow_back_the_.22Source_Link.22_trail.29|advanced mouse options]])<br />
<br />
==Bezeichner-Vervollständigung==<br />
Die "Bezeichner-Vervollständigung" wird aufgerufen mittels {{keypress|Strg|space}}. Sie zeigt alle Bezeichner im Suchbereich. Zum Beipiel:<br />
<br />
<syntaxhighlight>procedure TForm1.FormCreate(Sender: TObject);<br />
begin<br />
|<br />
end;</syntaxhighlight><br />
<br />
Stellen Sie den Kursor zwischen ''begin'' und ''end'' und drücken Sie {{keypress|Strg|space}}. Die IDE/CodeTools untersuchen nun den gesamten erreichbaren Code und präsentieren Ihnen eine Liste aller gefundenen Bezeichner. Die CodeTools speichern die Ergebnisse zwischen, sodass ein neuerlicher Aufruf sehr viel schneller verläuft.<br />
<br />
'''Anmerkung für Delphianer:''' Delphi nennt das ''Code completion''.<br />
<br />
Einige Bezeichner wie 'Write', 'ReadLn', 'Low', 'SetLength', 'Self', 'Result', 'Copy' sind in den Compiler eingebaut und nirgends sonst im Quellcode definiert. Die Bezeichner-Vervollständigung hat ebenfalls viele solche Dinge eingebaut. Falls Ihnen eines fehlt, schreiben Sie einfach einen Wunsch ("feature request") im Bug-Tracker.<br />
<br />
Die ''Bezeichner-Vervollständigung'' ergänzt nicht alle '''Schlüsselwörter'''. So können Sie sie nicht dazu benutzen 'repe' zu 'repeat' zu ergänzen. Nehmen Sie dafür {{keypress|Strg|W}} [[#Word Completion|Wortvervollstandigung]] oder {{keypress|Strg|J}} [[#Code Templates|Code-Schablonen]]. Seit Version 0.9.27 ergänzt die ''Bezeichner-Vervollständigung'' einige Schlüsselwörter.<br />
<br />
Die Bezeichner-Vervollständigung zeigt sogar solche Bezeichner an, die inkompatibel sind.<br />
<br />
===Präfix===<br />
Sie könne die Bezeichner-Vervollständigung mitten in einem Wort starten. Dann werden die Buchstaben links als Präfix genommen. Zum Beispiel:<br />
<br />
<syntaxhighlight>procedure TForm1.FormCreate(Sender: TObject);<br />
begin<br />
Ca|ption<br />
end;</syntaxhighlight><br />
<br />
Die Suchliste zeigt Ihnen dann nur diejenigen Bezeichner an, die mit 'Ca' beginnen.<br />
<br />
===Tasten===<br />
<br />
* Buchstabe oder Ziffer: füge das Zeichen hinzu im Quelltexteditor und im aktuellen Präfix. Dadurch wird die Liste aktualisiert.<br />
* Backspace: entfernt das letzte Zeichen aus dem Quelltexteditor und dem Präfix. Aktualisiert die Liste.<br />
* Eingabe: ersetzt das ganze Wort am Kursor mit dem ausgewählten Bezeichner und schließt das Popup-Fenster.<br />
* Umschalt+Eingabe: wie ''Eingabe'', aber ersetzt nur das Präfix (linker Teil) des Wortes am Kursor.<br />
* Nach oben/Nach unten: bewegt die Auswahl<br />
* Escape: schließt das Popup-Fenster ohne Änderungen<br />
* Tab: ergänzt das Präfix zur nächsten Auswahl. Zum Beispiel: Das aktuelle Präfix ist 'But' und die Bezeichner-Vervollständigung zeigt nur 'Button1' und 'Button1Click'. Durch Drücken von ''Tab'' wird das Präfix zu 'Button1' ergänzt.<br />
* Else: wie ''Eingabe'' und fügt das Zeichen zum Quelltexteditor hinzu<br />
<br />
===Methoden===<br />
<br />
Wenn der Kursor in einer Klassendefinition steht und Sie die Vervollständigung aufrufen für eine in einer Vorfahren-Klasse definierten Methode, dann werden automatisch die Parameter und das Schlüsselwort 'override' angefügt. Zum Beispiel:<br />
<br />
<syntaxhighlight>TMainForm = class(TForm)<br />
protected<br />
mous|<br />
end;</syntaxhighlight><br />
<br />
Die Vervollständigung von '''MouseDown''' ergibt:<br />
<br />
<syntaxhighlight>TMainForm = class(TForm)<br />
protected<br />
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,<br />
Y: Integer); override;<br />
end;</syntaxhighlight><br />
<br />
===Eigenschaften===<br />
<br />
<syntaxhighlight>property MyInt: integer read |;</syntaxhighlight><br />
<br />
Die Bezeichner-Vervollständigung zeigt Ihnen '''FMyInt''' und '''GetMyInt'''.<br />
<br />
<syntaxhighlight>property MyInt: integer write |;</syntaxhighlight><br />
<br />
Die Bezeichner-Vervollständigung zeigt Ihnen '''FMyInt''' und '''SetMyInt'''.<br />
<br />
===Uses-Abschnitt / Unitnamen===<br />
<br />
In Uses-Abschnitten zeigt die Bezeichner-Vervollständigung die Dateinamen aller Units im Suchpfad. Diese werden immer in Kleinbuchstaben angezeigt (z.B. '''avl_tree'''), weil die meisten Units ohnehin kleinbuchstabige Dateinamen haben. Bei der Vervollständigung wird aber die "niedliche" Schreibweise für Dateinamen eingesetzt (z.B. '''AVL_Tree''').<br />
<br />
===Anweisungen===<br />
<br />
<syntaxhighlight>procedure TMainForm.Button1Click(Sender: TObject);<br />
begin<br />
ModalRe|;<br />
end;</syntaxhighlight><br />
<br />
wird zu:<br />
<br />
<syntaxhighlight>procedure TMainForm.Button1Click(Sender: TObject);<br />
begin<br />
ModalResult:=|;<br />
end;</syntaxhighlight><br />
<br />
==Wortvervollständigung==<br />
Die "Wortvervollständigung" wird aufgerufen mit {{keypress|Strg|W}}. Sie zeigt alle Wörter aus allen derzeit offenen Editoren und kann deshalb auch in Nicht-Pascal-Quelltexten, in Kommentaren und für Schlüsselwörter benutzt werden.<br />
<br />
Ansonsten funktioniert sie genau gleich wie die Bezeichner-Vervollständigung.<br />
<br />
==Zu Include-Anweisung springen==<br />
"Zu Include-Anweisung springen" im Menü 'Suchen' der IDE springt zur {$I filename} Anweisung, wo die aktuelle Include-Datei verwendet wird.<br />
<br />
==Projekt veröffentlichen==<br />
Erzeugt eine Kopie des gesamten Projekts. Wenn Sie jemandem einfach die Quellen und Kompilereinstellungen Ihres Codes senden wollen, dann ist diese Funktion Ihr Freund.<br />
<br />
Ein normales Projektverzeichnis enthält eine Menge an Informationen. Das meiste davon wird für eine Veröffentlichung nicht benötigt:<br />
Die .lpi Datei enthält Sessioninformationen (wie Cursorposition und Lesezeichen geschlossener Units) und das Projektverzeichnis enthält eine Menge von .ppu und .o Dateien und die ausführbare Datei.<br />
Um eine .lpi Datei zu erzeugen, die nur die Basisinformationen und nur den Quellen enthält (zusammen mit allen Unterverzeichnissen), verwenden Sie "Projekt veröffentlichen".<br />
<br />
'''Anmerkung''': Seit Version 0.9.13 gibt es eine neue ''Projekteinstellung'' die es Ihnen erlaubt, Sessioninformationen in einer anderen Datei als der normalen .lpi Datei zu speichern. Diese neue Datei endet mit der .lps Erweiterung und enthält nur Sessioninformationen, was die .lpi Datei viel übersichtlicher macht.<br />
<br />
In dem Dialog können Sie den Exclude- und Include-Filter einstellen, und mit dem anschließenden Kommando können Sie den Output in ein einzelnes Archiv komprimieren.<br />
<br />
==Tipps von Kommentaren==<br />
<br />
An verschiedenen Stellen zeigt die IDE Tipps für einen Bezeichner an. Beispielsweise, wenn Sie den Mauszeiger über einen Bezeichner im Quelltexteditor bewegen und einige Sekunden warten.<br />
Wenn die IDE einen Tipp für einen Bezeichner anzeigt, sucht sie die Deklaration und alle ihre Vorfahren und hält nach Kommentaren und fpdoc-Dateien Ausschau. Es gibt viele Kodierstile und viele Kommentierstile. Um möglichst viele der allgemein üblichen Stile zu unterstützen, benutzt die IDE folgende Heuristik:<br />
<br />
===Kommentare im Tipp angezeigt===<br />
<br />
Kommentare vor einer Deklaration, ohne Leerzeile und nicht mit dem '''<'''-Zeichen beginnend:<br />
<br />
<syntaxhighlight>var<br />
{Comment}<br />
Identifier: integer;</syntaxhighlight><br />
<br />
Kommentare mit dem '''<'''-Zeichen gehören zum vorhergehenden Bezeichner.<br />
<br />
Kommentare hinter einem Bezeichner in der selben Zeile:<br />
<br />
<syntaxhighlight>var <br />
identifier, // Comment<br />
other,</syntaxhighlight><br />
<br />
Kommentare hinter der Definition in der selben Zeile:<br />
<br />
<syntaxhighlight>var<br />
identifier: <br />
char; // Comment</syntaxhighlight><br />
<br />
Ein Beispiel für das '''<'''-Zeichen:<br />
<br />
<syntaxhighlight>const<br />
a = 1;<br />
//< comment for a<br />
b = 2;<br />
// comment for c<br />
c = 3;</syntaxhighlight><br />
<br />
Alle drei Kommentartypen werden unterstützt:<br />
<syntaxhighlight> {Comment}(*Comment*)//Comment<br />
c = 1;</syntaxhighlight><br />
<br />
Kommentare, die mit '''$''' und '''%''' beginnen, werden ignoriert.<br />
<br />
===Kommentare, nicht im Tipp angezeigt===<br />
<br />
Vorlaufende Kommentare, die mit einer Leerzeile abgetrennt werden, werden als unspezifisch für den folgenden Bezeichner angesehen. Beispielsweise wird der Kommentar für den folgenden Klassenheader nicht im Tipp angezeigt:<br />
<br />
<syntaxhighlight>type<br />
{ TMyClass }<br />
<br />
TMyClass = class</syntaxhighlight><br />
<br />
Die Kommentare für Klassenheader werden bei der Klassenvervollständigung erzeugt. Sie können dies ausschalten unter ''Einstellungen / Codetools / Klassenvervollständigung / Header-Kommentar für die Klasse''. Falls Sie den Header-Kommentar im Tipp anzeigen wollen, entfernen Sie einfach die Leerzeile.<br />
<br />
Der folgende Kommentar wird angezeigt für GL_TRUE, aber nicht für GL_FALSE:<br />
<br />
<syntaxhighlight> // Boolean<br />
GL_TRUE = 1;<br />
GL_FALSE = 0;</syntaxhighlight><br />
<br />
[[Category:Lazarus/de]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=sOptimization/de&diff=72037sOptimization/de2013-08-29T15:30:10Z<p>Dirk Fellenberg: Irritierenden Kommentar entfernt</p>
<hr />
<div>{{sOptimization}}<br />
<br><br />
Zurück zu den [[local compiler directives/de|lokalen Compiler Direktiven]].<br><br />
<br><br />
=$OPTIMIZATION=<br />
Die Direktive $OPTIMIZATION gehört zur Code-Optimierung.<br><br />
<br><br />
<table><br />
<tr><br />
<td>ON</td><td>Entspricht dem Schalter LEVEL2</td><br />
</tr><br />
<tr><br />
<td>OFF</td><td>Löscht alle Arten von Optimierungen</td><br />
</tr><br />
<tr><br />
<td>DEFAULT</td><td>Setzt alle Optimierungen auf die Standardeinstellungen</td><br />
</tr><br />
<tr><br />
<td>xyz</td><td>Durchsucht den String nach Optimierungen (siehe Tabelle unten)</td><br />
</tr><br />
</table><br />
<br><br />
Folgende Strings können der Direktive $OPTIMIZATION mitgegeben werden:<br><br />
<table><br />
<tr><br />
<td>LEVEL1</td><td>Level 1 Optimierungen</td><br />
</tr><br />
<tr><br />
<td>LEVEL2</td><td>Level 2 Optimierungen</td><br />
</tr><br />
<tr><br />
<td>LEVEL3</td><td>Level 3 Optimierungen</td><br />
</tr><br />
<tr><br />
<td>REGVAR</td><td>verwendet Register Variablen</td><br />
</tr><br />
<tr><br />
<td>UNCERTAIN</td><td>unsichere Optimierungen</td><br />
</tr><br />
<tr><br />
<td>SIZE</td><td>optimiert auf Grösse (geringere Grösse im Arbeitsspeicher)</td><br />
</tr><br />
<tr><br />
<td>STACKFRAME </td><td>erlaubt keine Stackframes</td><br />
</tr><br />
<tr><br />
<td>PEEPHOLE</td><td>Minimiert den Code auf ein Minimum an Befehlen</td><br />
</tr><br />
<tr><br />
<td>ASMCSE</td><td>Verwendet im Assemblerlevel allgemeine subexpressions (Die Subexpressions werden verwendet, wenn es sich deren Einsatz lohnt).</td><br />
</tr><br />
<tr><br />
<td>LOOPUNROLL</td><td>Beschleunigt die Verarbeitung von Schleifen. Das Programm wird dadurch grösser.</td><br />
</tr><br />
<tr><br />
<td>TAILREC</td><td>Wandelt eine Fussgesteuerte Schleife in eine While-Schleife um.</td><br />
</tr><br />
<tr><br />
<td>CSE</td><td>Beseitigt die Verwendung von allgemeinen subexpressions.</td><br />
</tr><br />
<tr><br />
<td>DFA</td><td>Verwendet DFA (deterministic finite automaton)</td><br />
</tr><br />
</table><br />
<br><br />
Beispiel:<br><br />
<syntaxhighlight><br />
{$OPTIMIZATION ON}<br />
</syntaxhighlight><br />
<br><br />
Die Direktive {$OPTIMIZATION ...} entspricht der Kommandozeilen Option -Oo.<br><br />
<br><br />
<br><br />
--[[User:Olaf|Olaf]] 17:05, 12 January 2013 (UTC)<br />
[[Category:Free Pascal Programmers Guide/de]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Delphi_language_features_missing_from_the_Free_Pascal_Compiler&diff=70897Delphi language features missing from the Free Pascal Compiler2013-06-29T15:01:44Z<p>Dirk Fellenberg: New since Delphi 2010: Custom Attributes</p>
<hr />
<div>Note: some new Delphi features are already implemented in [[FPC_New_Features_Trunk|FPC trunk]].<br />
<br />
== New since Delphi 2007 ==<br />
<br />
==== Advanced Records ====<br />
<br />
http://docwiki.embarcadero.com/RADStudio/en/Structured_Types#Records_.28advanced.29<br />
<br />
Advanced records are implemented in FPC 2.6.X without record constructors. Record constructors are implemented in FPC 2.7.1 (trunk).<br />
<br />
== New since Delphi 2009 ==<br />
==== Generics Syntax ====<br />
<br />
A good delphi reference is here: http://docwiki.embarcadero.com/RADStudio/en/Generics_Index<br />
<br />
Partially implemented in 2.5.1/2.6.x, further improved in 2.7.1 by Sven<br />
<br />
==== Support for ansistrings with a definable codepage ====<br />
<br />
Initial implementation available in trunk (2.7.1). Useful for small time testing, but the whole of the codebase hasn't adapted (2011-10-18)<br />
<br />
==== Anonymous Methods ====<br />
<br />
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/anonymousmethods_xml.html<br />
<br />
== New since Delphi 2010 ==<br />
==== Custom Attributes ====<br />
Custom Attributes are a language feature in Delphi that allow annotating types and type members with special objects that carry additional information. Attributes extend the object-oriented model with aspect-oriented elements.<br />
<br />
http://delphi.about.com/od/oopindelphi/a/delphi-attributes-understanding-using-attributes-in-delphi.htm<br />
<br />
==== Enhanced RTTI ====<br />
http://docwiki.embarcadero.com/RADStudio/en/RTTI_directive_(Delphi)<br />
<br />
==== Delayed directive ====<br />
<br />
Info is here: http://docwiki.embarcadero.com/RADStudio/en/Libraries_and_Packages#Delayed_Loading<br />
Some info about internals:<br />
#http://blogs.embarcadero.com/abauer/2009/08/25/38894<br />
#http://blogs.embarcadero.com/abauer/2009/08/29/38896<br />
#http://blogs.embarcadero.com/chrishesik/2009/11/02/35056<br />
<br />
fpc wiki about that topic: http://wiki.freepascal.org/Dynamically_loading_headers<br />
<br />
Originally I thought that delayed is similar to weakexternal which FPC has for some platforms but after reading this: http://docwiki.embarcadero.com/CodeExamples/XE3/en/DelayedLoading_(Delphi) I understand that this is simply a wrapper around LoadLibrary and GetProcessAdress with automatic loading and unloading.--[[User:Paul Ishenin|Paul Ishenin]] 13:45, 18 January 2013 (UTC)<br />
<br />
== Misc ==<br />
# [[packages|(Library) packages]]<br />
# "automated" keyword, which is like "public", but generates COM specific RTTI. Afaik this kind of COM usage is deprecated though.<br />
<br />
== Already implemented ==<br />
=== FPC 2.7.1/trunk ===<br />
==== Advanced records ====<br />
See above.<br />
<br />
=== FPC 2.6.0 ===<br />
==== AS and IS extended for interfaces ====<br />
New since Delphi 2010. Info is here: <br />
#http://docwiki.embarcadero.com/RADStudio/en/Interface_References#Casting_Interface_References_to_Objects<br />
#http://blogs.embarcadero.com/abauer/2009/08/21/38893<br />
<br />
Implemented in FPC 2.6.0.<br />
<br />
== Reference ==<br />
#http://edn.embarcadero.com/article/34324<br />
#http://edn.embarcadero.com/article/images/39076/New_Delphi_Coding_Styles_and_Architectures.pdf<br />
#http://docwiki.embarcadero.com/RADStudio/en/What's_New_in_Delphi_and_C%2B%2BBuilder_2010<br />
<br />
[[Category:Delphi]]<br />
[[Category:FPC]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Set&diff=65760Set2013-02-10T11:09:09Z<p>Dirk Fellenberg: wiki syntaxhighlight</p>
<hr />
<div>== Introduction ==<br />
<br />
A Set encodes many values from an enumeration into an Ordinal type.<br />
<br />
For example let's consider this enumaration:<br />
<br />
<syntaxhighlight><br />
TSpeed = (spVerySlow,spSlow,spAVerage,spFast,spVeryFast); <br />
</syntaxhighlight><br />
<br />
And this set:<br />
<br />
<syntaxhighlight><br />
TPossibleSpeeds = set of TSpeed<br />
</syntaxhighlight><br />
<br />
The TPossibleSpeeds can be defined as constant in right brackets:<br />
<br />
<syntaxhighlight><br />
const<br />
RatherSlow = [spVerySlow,spSlow];<br />
RatherFast = [spFast,spVeryFast];<br />
</syntaxhighlight><br />
<br />
RatherSlow and RatherFast are some Set of TSpeed.<br />
<br />
== Manipulating sets ==<br />
<br />
Usually two compiler functions are used to manipulate a set: '''Include(ASet,AValue)''' and '''Exclude(ASet,AValue)'''.<br />
<br />
<syntaxhighlight><br />
var<br />
SomeSpeeds = TPossibleSpeeds;<br />
begin<br />
SomeSpeeds := [];<br />
Include(SomeSpeeds,spVerySlow);<br />
Include(SomeSpeeds,spVeryFast);<br />
end;<br />
</syntaxhighlight><br />
<br />
Sets cannot be directly manipulated if they are published. You usually have to make a local copy, change the local copy and<br />
then to call the setter.<br />
<br />
<syntaxhighlight><br />
procedure TSomething.DoSomething(Sender: TFarObject);<br />
var<br />
LocalCopy = TPossibleSpeeds;<br />
begin<br />
LocalCopy := Sender.PossibleSpeeds; // getter to local<br />
Include(LocalCopy,spVerySlow);<br />
Sender.PossibleSpeeds := LocalCopy; // local to setter.<br />
end;<br />
</syntaxhighlight><br />
<br />
The Keyword '''in''' is also used to test if a value is in a set. It's usually used in this fashion:<br />
<br />
<syntaxhighlight><br />
var<br />
CanBeSlow: Boolean;<br />
const<br />
SomeSpeeds = [Low(TSpeed)..High(TSpeed)];<br />
begin<br />
CanBeSlow := (spVerySlow in SomeSpeeds) or (spSlow in SomeSpeeds);<br />
end;<br />
</syntaxhighlight></div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Interfaces&diff=64823Interfaces2013-01-01T19:00:18Z<p>Dirk Fellenberg: wiki syntax straightened</p>
<hr />
<div>Interfaces can be utilized as an alternative solution to the need of multiple inheritance, which Object Pascal currently does not support.<br />
<br />
==Full example program==<br />
<br />
<source lang="pascal"><br />
program project1;<br />
<br />
{$mode delphi}<br />
{$interfaces corba}<br />
<br />
type<br />
IMyDelegate = interface<br />
procedure DoThis (value: integer);<br />
end;<br />
<br />
TMyClass = class (TInterfacedObject, IMyDelegate)<br />
procedure DoThis (value: integer);<br />
end;<br />
<br />
procedure TestDelegate;<br />
var<br />
delegate: TMyClass;<br />
intfdelegate: IMyDelegate;<br />
begin<br />
delegate := TMyClass.Create;<br />
intfdelegate := IMyDelegate(delegate);<br />
intfdelegate.DoThis(1);<br />
end;<br />
<br />
{ TMyClass }<br />
<br />
procedure TMyClass.DoThis(value: integer);<br />
var<br />
Str: string;<br />
begin<br />
WriteLn('Success!!! Type <enter> to continue');<br />
ReadLn(Str);<br />
end;<br />
<br />
begin<br />
TestDelegate;<br />
end.<br />
</source><br />
<br />
[[Category:Pascal]]</div>Dirk Fellenberghttps://wiki.freepascal.org/index.php?title=Feature_Ideas&diff=27633Feature Ideas2008-04-12T19:46:06Z<p>Dirk Fellenberg: Link korrigiert</p>
<hr />
<div>{{Feature Ideas}}<br />
<br />
'''This Page is intended to collect ideas for features that could be included in Lazarus. Putting an idea here does not mean it WILL be put into Lazarus. It's just a place to gather ideas. Think of this as more of a wishlist.'''<br />
<br />
Also another place to log feature requests is here: [http://bugs.freepascal.org/ Lazarus Bugtracker]<br />
<br />
=IDE=<br />
Features that could be included in the IDE<br />
<br />
==Common==<br />
Open files in the same folder as the current tab editor, like SCite does, it's a bit annoying to navigate from folder to folder every time you need open a file related to the one we are editing at the moment.<br />
<br />
enable menu access through access keys like under windows (i hate mouse sessions :o)<br />
example: <alt>-<f> for file menu<br />
<br />
===Improvement of the menu and toolbars===<br />
* to allow final-user customisation<br />
* to obtain more styled menu (similar as Shagrouni xp-menu style)<br />
<br />
==Object Inspector==<br />
<br />
add a "search" text box at the top or bottom (preferred, maybe user settable) of Object Inspector to be able to search for a name or value (maybe with right click menu checkable options on whether Name or Value or both are searched) in the properties/events list<br />
<br />
add a "Recent" tab to Object Inspector apart from the "Favorites" one, would be more useful than the Favorites one since it's automatic (would keep all properties/events that have been edited [fields that have either been changed or ENTER was pressed to CONFIRM/REset their current value - focus lost events shouldn't be considered editing if value of property/event field didn't change])<br />
<br />
Add a field in the object inspector to allow specify the real class that will be instantiated, with that will allow to uses derived classes without remake/link the IDE, of course the new fields for the real class will not be available to edit in designer.<br />
An example:<br />
We place a TEdit in a form, but we want to use a derived class we made that add a new field/property/method to TEdit and we will use that new field/property/method programming but in design time it's enough to work with TEdit, actually there is an option to change the class but only to another one that's already linked on the IDE.<br />
<br />
==Refactoring==<br />
===Global Variable/Method renaming===<br />
Proper renaming (as in if I rename a field in an object it can change everything that uses it but NOT other stuff that happens to have the same name) -Plugwash<br />
: Already implemented: See Source Editor -> popup menu -> refactoring -> rename identifier<br />
<br />
===Parameter Renaming in Methods===<br />
adding a parameter to a method (and updating everything that uses it) -Plugwash<br />
: How should that work? What should the IDE/codetools put as parameter at the places?<br />
:: You specify that when you ask for the parameter to be added. [[User:Plugwash|Plugwash]] 05:09, 30 September 2006 (CEST)<br />
: For example, you add a parameter "b: boolean". The method is used a 100 times.<br />
* Possibility 1: You add a default parameter too. No change to the using methods is needed.<br />
* Possibility 2: You press compile and the compiler will jump to every occurence and you can decide, what to do.<br />
* Possibility 3: A new dialog is added to the IDE, where you can specify to insert a ",false" at every occurence.<br />
* Possibility 4: ?<br />
Do you have 3 in mind or 4?<br />
<br />
===Encapsulating Fields===<br />
though thats not really needed in object pascal because object pascal has properties but its vital in cleaning up thrown together java. -Plugwash<br />
: Please give an example.<br />
<br />
===Improvement of the IDE as GExperts for Delphi===<br />
* Multi lines tabs for the components palette.<br />
Implemented<br />
* Editor tool bar. <[[User:ggeldenhuys|I'm]] working on this><br />
* Procedures list. <[[User:ggeldenhuys|I've]] already done this. It's part of Lazarus><br />
* Backup tool...<br />
* Comment/uncomment selection: comment/uncomment the current line when no selection made...<br />
* Indent/unindent selection: Indent/unindent the current line when no selection made...<br />
* Tab : provision to set Tab spacing<br />
<br />
== I have a dream of components : Jedi ==<br />
Sure I switch immediatly from Delphi to Lazarus.<br />
<br />
==Code completion==<br />
===Create/Free objects===<br />
Declare an object myObj:TMyClass into a TForm class an type some Ctrl-Shift-Key, then the IDE adds a line myObj:=TMyClass.Create in FormCreate and myObj.Free in FormDestroy. -Rednaxel<br />
<br />
===Add list properties===<br />
Declaring an indexed property like 'property Items[i: integer]: TAType' and using this feature (Ctrl-Shift-Key, Menu), should popup a dialog to setup some parameters and then it should add a private variable fItems: TFPList; (or 'array of' or TList or ^AType), create code in the constructor, destroy code in the destructor and access methods GetItems, SetItems.<br />
<br />
==Visual Form Inheritance==<br />
Currently there is no VFI (Visual From Inheritane) support in Lazarus. This is something that will greatly appeal to users using Lazarus in a commercial environment or any other large project for that matter. The only way around this is to create all forms via code, which loses a lot of the appeal of Lazarus, and makes the application overly complex.<br />
<br />
[A bounty was created for this and accepted by Mattias.]<br />
<br />
==Conditional Compiler Options==<br />
<br />
See [[Conditional Compiler Options]].<br />
<br />
<br />
<br />
=LCL=<br />
<br />
==Components==<br />
<br />
Components that are possible to make that will work across all platforms supported by Lazarus<br />
<br />
===Visual===<br />
*Already implemented: Help system for apps created by Laz! It is a plugin system. That's why it supports cross-platform help system and using the OS's native help system.<br />
<br />
*The current LCL TStringGrid is a nice improvement over Delphi's feeble control with the same name. Would be great if it could be improved even more!<br />
**Support for data validation event handler, similar to Orpheus grid's OnUserValidation event. There are many events, for example OnEditing todo this. Please be more specific, what this OnUserValidation is.<br />
**Support for retrieving, displaying, editing and storing data that are stored in an existing memory structure or in a file rather than in grid itself, similar to the Orpheus grid's OnGetCellData and OnGetCellAttributes events. There is the TTIGrid, that can show TCollection, TList and TFPList of TPersistent. What else do you need?<br />
**An TImage Component wich support transparent winxp alpha 32 bit icon images<br />
<br />
*TTrayIcon<br />
** Add a TImageList property in TTrayIcon to change TrayIcon icon or animate it<br />
<br />
===NonVisual===<br />
*Clipboard and TTimer that don't depend on LCL. If you use these in a library or console app, the compiler drags in a lot of unused and unneeded LCL code. If you have multiple DLL's, this code is duplicated in each. Current implementations appear to follow the Delphi design approach, where Clipboard and TTimer have dependencies on the VCL - this probably wasn't necessary.<br />
<br />
: This may be true on Windows, but it´s False for Linux. I recently implemented TTimer for qt interface and the implementation calls Qt API. I think the same applies to Clipboard, since the clipboard depends on the widgetset used too (gtk or qt for example), not only on the operating system. --[[User:Sekelsenmat|Sekelsenmat]] 20:40, 5 Mar 2006 (CET)<br />
<br />
: The LCL is a visual component library. None visual components are provided by the FCL.<br />
<br />
: Lazarus will only provide components based on the LCL.<br />
<br />
==PDA Support==<br />
<br />
Something that currently does not exist is a complete multiplatform solution for PDAs. If we can implement this, Lazarus will become the first multiplatform RAD for PDAs ever created. Some devices work with Java, some work with c++ and Qtopia, some work with their particular APIs, there is no single solution currently that can embrace a large portion of PDAs. Application have to be redone for every PDA or simply just run on one of them (what most people do).<br />
<br />
The LCL implements many things. It is not necessary to implement them all to have a reasonably working Lazarus PDA widgetset. The most important things to be implementeded for PDAs are:<br />
<br />
* TApplication<br />
* TForm<br />
* TScreen<br />
* TCanvas and painting<br />
* Most Events (onClick and OnPaint at least)<br />
* Basic widgets like: TButton, TLabel, TEdit, TMemo.<br />
* Only minimum nessary LCLIntf functions to make TCanvas work. (GetDC, ReleaseDC, BeginPaint, EndPaint and some painting functions)<br />
<br />
Others can be easely implemented by people who need them after those are ready.<br />
<br />
Here is a list of some PDAs and the status of their support on Free Pascal / Lazarus:<br />
<br />
* Windows CE - The compiler already works really well cross compiling for Windows CE. The [[Windows CE Interface]] is under implementation.<br />
* Symbian OS - Possible for their ARM devices. Requires first adding a new Runtime Library for this OS to the Compiler. This OS has it's own API. There are open source projects for python and c to work on Symbian OS, so Free Pascal should work as well when a RTL is written.<br />
* Qtopia - For Zaurus and other linux-based PDAs. This is much easier now that basic Qt4 widgetset has being implemented, because Qtopia is very similar to Qt4. Some magick on the bindings is expected to make the same widgetset code to run for both Qtopia and Qt4.<br />
* Java - Some handheld devices, specially phones, only support java bytecode. May seam a little odd, but there is a Pascal Compiler capable of compiling the source into a jar and then into bytecode. It's name is Midlet Pascal http://www.midletpascal.com/ It may be possible to develop a similar technology that adds a java bytecode target for Free Pascal.<br />
* Palm OS - PalmOS 5 Garnet support requires that first the 68k compiler is working (runs on ARM processor with a kind of emulation) and then a RTL for palmos needs to be written. Only Free Pascal 1.0 supports 68k, this wasn't updated and the new compiler 2.0 doesn't support it yet (work in progress by [[fpc:User:Chain-Q]]), so will be a problem.<br />
<br />
PalmOS 6 Cobalt is fully arm, so it only requires a rtl, but it has zero devices working on it currently and won't be on the market until 2007 at least.<br />
<br />
Other compilers that support this target: [http://www.ppcompiler.org Pascal & Palm Compiler] and [http://hspascal.fihl.net/ HsPascal]. Unfortunately those compilers are not open source, so we can't use their code, we need to implement PalmOS RTL from zero.<br />
<br />
==More Interfaces==<br />
<br />
* Cocoa - Requires that first OpenSTEP bindings are created for Free Pascal.<br />
* BeAPI - interface for Haiku, ZetaOS and BeOS. There is no powerful RAD on this OS.<br />
* [http://www.libsdl.org SDL] - something like what was done in [http://www.kanzelsberger.com/pixel/ Pixel Image Editor].<br />
* MacApp 2.0 - For 68k-based Mac computers. MacApp was Apple Computer's primary object oriented application framework for the Mac OS for much of the 1990s. First released in 1985, it is arguably the first such system to be widely used, notably on a microcomputer platform. Microsoft's MFC and Borland's OWL were both based directly on MacApp concepts. This framework was completely written on Object Pascal, so it should integrate really nicely with Free Pascal and Lazarus. When Apple moved to PowerPC it also dropped Object Pascal support, but that's another story. A emulator for 68k-Mac can be easely set up with [http://basilisk.cebix.net/ BasiliskII]. There is also a project called MacApp2PPC that upgraded MacApp pascal code to run on Power PCs. <br />
* OS/2 native - Free Pascal works well with OS/2, so this should be quite possible.<br />
* Solaris - OpenSolaris versions exist and it's quite similiar to Linux so why not ?<br />
* Web Interface - Application compiles to an embedded HTTP Server who serves forms in ajax pages (or compiles it to an Apache Module), like Intraweb in Delphi. Discussion in http://www.lazarus.freepascal.org/index.php?name=PNphpBB2&file=viewtopic&t=2489<br />
* [http://opensoft.homeip.net/fpgui/ fpGUI] - A widget set written in Free Pascal without any large library requirements. fpGUI talks directly to the underlying graphics library and is very easy to port to new platforms. Currently it supports Linux, Windows and WinCE. - Under development here: [[fpGUI_Interface]]<br />
* Support for Lua interfacing. (Binary moduals?) <br />
** What is Lua interfacing? Is it a graphical widgetset? What is the difference between what you want and is supplied by the lua units of fpc: http://svn.freepascal.org/svn/fpc/trunk/packages/extra/lua/<br />
<br />
=Other=<br />
* SVN changelog as RSS (http://cia.navi.cx/ ?)<br />
** added one to the fpc repository for testing purposes: http://svn.freepascal.org/feeds/fpcsvn.rss Lazarus got one too: http://svn.freepascal.org/feeds/lazarussvn.rss</div>Dirk Fellenberg