Lazarus with FPC3.0 without UTF-8 mode: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Lazarus with FPC3.0 without UTF-8 mode
| Old | New | Line | |
|---|---|---|---|
| 1 | + | This page explains the problems and their possible solutions when using Lazarus with FPC 3.0+ but without the new UTF-8 mode. It may be needed when big parts of program code depend on system codepage. The UTF-8 mode is explained here: | |
| 2 | + | ||
| 3 | + | - [[Unicode Support in Lazarus]] | |
| 4 | + | ||
| 5 | + | To disable the new UTF-8 mode, **-dDisableUTF8RTL** must be defined in project options, "Additions and Overrides" page. There is a button "Use system encoding" to help adding it with one click. This way it affects both the project and all its dependent packages, including LazUtils which contains the relevant code. If you use strings with codepoints \> 127 in your project, you have to change the file encoding to the system encoding too. | |
| 6 | + | ||
| 7 | + | Bart has collected some reported issues under a meta-issue. Fortunately most of them are solved and Lazarus libraries should be robust also without the UTF-8 mode. There is an unsolved FPC issue about RawByteString though. | |
| 8 | + | ||
| 9 | + | - <http://bugs.freepascal.org/view.php?id=28857> | |
| 10 | + | ||
| 11 | + | # Simple Example | |
| 12 | + | ||
| 13 | + | - create a *New Project* -\> *Simple Program* | |
| 14 | + | - activate the *-dDisableUTF8RTL* mode with *Project Options ...* -\> *Compiler Options* -\> *Additions and Overrides* -\> click on *Use system encoding* | |
| 15 | + | - change the file encoding: *Source Editor* -\> mouse rightclick -\> *File Settings* -\> *Encoding* -\> take your system encoding (for that example take 1252) and confirm | |
| 16 | + | ||
| 17 | + | Now you are able to build a project without UTF8 dependences. | |
| 18 | + | ||
| 19 | + | Write something in your source editor: | |
| 20 | + | ||
| 21 | + | ``` pascal | |
| 22 | + | program project1; | |
| 23 | + | ||
| 24 | + | {$mode objfpc}{$H+} | |
| 25 | + | {$codepage cp1252} | |
| 26 | + | ||
| 27 | + | var | |
| 28 | + | test: String; | |
| 29 | + | ||
| 30 | + | begin | |
| 31 | + | test := 'ÄÖÜ'; | |
| 32 | + | WriteLn(test); | |
| 33 | + | ReadLn; | |
| 34 | + | end. | |
| 35 | + | ``` | |
| 36 | + | ||
| 37 | + | Start your program. | |
| 38 | + | ||
| 39 | + | ## Problem System encoding and Console encoding (Windows) | |
| 40 | + | ||
| 41 | + | If you start the simple example, you will maybe see a wrong content for that `writeln('ÄÖÜ')`. This is because you can have different codepages for the console and the file system. To check which codepage you have you can make a simple test: | |
| 42 | + | ||
| 43 | + | ``` pascal | |
| 44 | + | Writeln('Console output codepage: ', GetTextCodePage(Output)); | |
| 45 | + | Writeln('System codepage: ', DefaultSystemCodePage); | |
| 46 | + | ``` | |
| 47 | + | ||
| 48 | + | If your console codepage is different from your system codepage, you can change it in that way (original code from [forum](http://forum.lazarus.freepascal.org/index.php/topic,30200.msg191843.html#msg191843)) | |
| 49 | + | ||
| 50 | + | ``` pascal | |
| 51 | + | unit setdefaultcodepages; | |
| 52 | + | ||
| 53 | + | interface | |
| 54 | + | ||
| 55 | + | uses | |
| 56 | + | Windows; | |
| 57 | + | ||
| 58 | + | implementation | |
| 59 | + | ||
| 60 | + | Const | |
| 61 | + | LF_FACESIZE = 32; | |
| 62 | + | ||
| 63 | + | Type | |
| 64 | + | CONSOLE_FONT_INFOEX = record | |
| 65 | + | cbSize : ULONG; | |
| 66 | + | nFont : DWORD; | |
| 67 | + | dwFontSize : COORD; | |
| 68 | + | FontFamily : UINT; | |
| 69 | + | FontWeight : UINT; | |
| 70 | + | FaceName : array [0..LF_FACESIZE-1] of WCHAR; | |
| 71 | + | end; | |
| 72 | + | ||
| 73 | + | { Only supported in Vista and onwards!} | |
| 74 | + | ||
| 75 | + | function SetCurrentConsoleFontEx(hConsoleOutput: HANDLE; bMaximumWindow: BOOL; var CONSOLE_FONT_INFOEX): BOOL; stdcall; external kernel32; | |
| 76 | + | ||
| 77 | + | var | |
| 78 | + | New_CONSOLE_FONT_INFOEX: CONSOLE_FONT_INFOEX; | |
| 79 | + | ||
| 80 | + | initialization | |
| 81 | + | SetConsoleOutputCP(DefaultSystemCodePage); | |
| 82 | + | SetTextCodePage(Output, DefaultSystemCodePage); | |
| 83 | + | ||
| 84 | + | FillChar(New_CONSOLE_FONT_INFOEX, SizeOf(CONSOLE_FONT_INFOEX), 0); | |
| 85 | + | New_CONSOLE_FONT_INFOEX.cbSize := SizeOf(CONSOLE_FONT_INFOEX); | |
| 86 | + | New_CONSOLE_FONT_INFOEX.FaceName := 'Consolas'; | |
| 87 | + | // New_CONSOLE_FONT_INFOEX.FaceName := 'Lucida Console'; //use Lucida Console for Win XP | |
| 88 | + | New_CONSOLE_FONT_INFOEX.FontWeight := 400; | |
| 89 | + | New_CONSOLE_FONT_INFOEX.dwFontSize.Y := 16; | |
| 90 | + | ||
| 91 | + | SetCurrentConsoleFontEx(StdOutputHandle, False, New_CONSOLE_FONT_INFOEX); | |
| 92 | + | end. | |
| 93 | + | ``` | |
| 94 | + | ||
| 95 | + | If you now build a project and use that unit, all strings are correctly shown (Strings also Shortstrings). For example: | |
| 96 | + | ||
| 97 | + | ``` pascal | |
| 98 | + | program project1; | |
| 99 | + | ||
| 100 | + | {$mode objfpc}{$H+} | |
| 101 | + | {$codepage cp1252} | |
| 102 | + | ||
| 103 | + | uses | |
| 104 | + | setdefaultcodepages; | |
| 105 | + | ||
| 106 | + | const | |
| 107 | + | StrCP1252 = #$80#$C4#$D6#$8C#$A5; | |
| 108 | + | ||
| 109 | + | var | |
| 110 | + | AStr : String; | |
| 111 | + | AShortString : ShortString; | |
| 112 | + | begin | |
| 113 | + | AStr := StrCP1252; | |
| 114 | + | AShortString := StrCP1252; | |
| 115 | + | WriteLn(StrCP1252); | |
| 116 | + | WriteLn('€ÄÖŒ¥'); | |
| 117 | + | WriteLn(AStr); | |
| 118 | + | WriteLn(AShortString); | |
| 119 | + | ReadLn; | |
| 120 | + | end. | |
| 121 | + | ``` | |
| 122 | + | ||
| 123 | + | # Problem applications with ACP strings and LCL controls | |
| 124 | + | ||
| 125 | + | If you want to use some LCL controls like TLabel, TEdit, TMemo etc., you have to convert the strings, cause the LCL controls use the UTF8 strings further. You can use the method SysToUTF8 for the conversion of a string to a LCL control string and UTF8ToSys for the conversion back. | |
| 126 | + | ||
| 127 | + | ## Example | |
| 128 | + | ||
| 129 | + | - create a new Project *Application* and change the encoding of your project file to *CP1252* and activate the *-dDisableUTF8RTL* mode | |
| 130 | + | - add a *TEdit* and a *TButton* on the form | |
| 131 | + | - create the event handler for the button click and write this code: | |
| 132 | + | ||
| 133 | + | ``` pascal | |
| 134 | + | procedure TForm1.Button1Click(Sender: TObject); | |
| 135 | + | var | |
| 136 | + | s: String; | |
| 137 | + | begin | |
| 138 | + | s := 'Läuse und Flöhe'; | |
| 139 | + | Edit1.Text := SysToUTF8(s); | |
| 140 | + | end; | |
| 141 | + | ``` | |
| 142 | + | ||
| 143 | + | --- | |
| 144 | + | *From the Free Pascal wiki, page "Lazarus with FPC3.0 without UTF-8 mode", as it stood on 2020-02-18 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* | |
| 145 | + | Category: FPC 3.0+ stuff | |
| 146 | + | Category: Unicode |
