Examples Delphi

Title: Some Relations between CLX and Qt
Question: How about licensing, libraries, constructors or event-handling in CLX with Qt? How to built Tetris on Linux for example?
Answer:
The Relationship between CLX and Qt
As you may know 3 porting techniques exists:
- Platform specific port: targets an OS and underlying APIs (Win32)
- Crossplatform port: targets a crossplaform API (like CLX)
- Emulation: leaves the code alone and port parts of the API it uses
Kylix uses CLX in place of the VCL for Crossplatform. CLX provides access to Qt widgets (from window+gadget) in the Qt shared libraries. This Qt-library is available on Linux and Win as well!
on win: qtinf.dll
on linux: qtinf.so
Functions are then wrapped in a shared object in Linux and DLL in Win. Cause Delphi can't have an direct access to the C++ Lib of Qt (Multiple Inheritance, RTTL and so on) all functions are wrapped in the interface with simple C functions like the Win API (uses qt.pas).
In most cases, we don't need to change occurences of TWinControl to TWidgetControl. The following type declaration appear in the QControls.pas to simplify sharing of source code:
TWinControl = TWidgetControl;
Because CLX is a wrapper around Qt, and most of the controls on the Kylix Component palette are simply Pascal wrappers around Qt classes, so most of the units starts with a Q in their names:
unit tetris1;
interface
uses
SysUtils, Classes, QGraphics, QDialogs, QComCtrls, QTypes, QExtCtrls,
QButtons, QControls, QForms, QStdCtrls;
Crossplatform
-------------------------------
Kylix with CLX runs only on Linux, and Delphi 6/7 supports also CLX on Windows. However, Qt alone has a wider range of deployment e.g.:
AIX 4.1, FreeBSD 2.1, HP-UX 10.20, Solaris 2.5.1, Tru64 (Digital UNIX) 4.0, Windows NT and so on.
Constructors
-------------------------------
When you explicitly create a CLX object in code, by using the Create(aHandle) instead of Create() method of the object, you are passing the instance of an existing Qt widget to the CLX so this CLX object does not own the Qt widget that is passed to it.
Licensing
-------------------------------
There is a free distribution of Qt that you can use for open-source projects on Linux. Various licensing agreements that involve payments are put into effect if you decide not to go to the opensource route.
That means, you can distribute Kylix apps in any manner you like. However, if you include even one direct call to Qt in your Kylix app, then the free Borland license for distributing your apps is no more valid.
FreeCLX
-------------------------------
At the time of this writing, the open-source version of Kylix is available since the summer of 2001. Updates to CLX appear on the following site. For instance, you can get the latest version of libqtintf.so.2.2.4.1 from the FreeCLX site.You can access FreeCLX at http://sourceforge.net/projects/freeclx/
or freeclx.sourceforge.net with a redirect to Borland.
FreeCLX is the Open Source project for Borland's CLX Component Library for GNU/Linux. The BaseCLX, VisualCLX and DataCLX packages have been dual-licensed to allow for open source collaboration. They are licensed under both the Borland proprietary No-Nonsense License and the GNU General Public License(GPL).
Events
-------------------------------
There is a complex interrelationship between CLX and Qt when it comes to capturing events.
In Qt, programmers traditionally do not respond directly to messages. Instead, they work with a signal and slot mechanism.
If you are creating a component and want to catch mouse move messages, you should use the following method:
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
This method overrides the CLX MouseMove method of the TControl object. The MouseMove method is called whenever the user moves the mouse over a component.
You ll get this event on right clicks and middle clicks as well as left clicks or keyDown like the example, so your first task is to check which Button or Key is generating the event.
procedure TTetro1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if ReentKeys then Exit
else ReentKeys := True;
if not FigureActive then begin
ReentKeys := False;
Exit;
end;
case Key of
Key_Up: RotateFigure;
Key_Down,
Key_Space: begin //VK_SPACE in Win
repeat
ClearFigureIntoGlass;
Inc(FigureY);
until not PutFigureIntoGlass(mdDown);
Inc(Score,5);
end;
Key_Left: if FigureX0 then begin
ClearFigureIntoGlass;
Dec(FigureX);
PutFigureIntoGlass(mdLeft);
end;
Key_Right: if FigureX+FigureXSize ClearFigureIntoGlass;
Inc(FigureX);
PutFigureIntoGlass(mdRight);
end;
end;
ReentKeys := False;
end;
For the standard Latin-1 characters (ie, #32 to #255), the Key code is the Ord() of the character. Setting the Key code to 0 suppresses further processing. If you do this in an OnKeyDown handler, for example, you ll still get an OnKeyUp event when the key is released, but you will not get an OnKeyPress.
Any Delphi code that uses Windows VK_ key names will have to be rewritten to use Qt s Key_ names.
It should be sure to note that the CLXs Brush.Bitmap is considerably more useful than the VCL s: Window s brushes only use the top-left 8x8 pixels of their bitmap, while Qt s brushes use the whole bitmap.
for I := 1 to MaxFigureSize-2 do
for J := 1 to MaxFigureSize do begin
X1 := NextLeftOfs+(J-1)*NextBarWidth;
X2 := X1+NextBarWidth;
Y1 := NextTopOfs+(I-1)*NextBarHeight;
Y2 := Y1+NextBarHeight;
if CurSheet[I,J]0 then begin
NewRect := Rect(X1+1,Y1+1,X2-1,Y2-1);
Canvas.Brush.Color := NextColor;
Canvas.FillRect(NewRect);
Canvas.Pen.Color := clGray;
Canvas.MoveTo(X1,Y1);
Canvas.LineTo(X1,Y2-1);
Canvas.LineTo(X2-1,Y2-1);
Canvas.Pen.Color := clWhite;
Canvas.LineTo(X2-1,Y1);
Canvas.LineTo(X1,Y1);
end
else begin
Canvas.Brush.Color := clSilver;
NewRect := Rect(X1,Y1,X2,Y2);
Canvas.FillRect(NewRect);
end;
end;
Move(GlassWorkSheet,OldGlassWorkSheet,SizeOf(OldGlassWorkSheet));
You can get the whole tetris-project under:
http://max.kleiner.com/download/clxtetris.zip
Migration
-------------------------------
Migration from VCL to CLX can be easy even if you have graphic-routines like in a game. But CLX/Qt don't prevent you from differentiate between Linux and Win. Let's have a last look at the differences:
CLX
uses
SysUtils, Classes, QGraphics, QDialogs, QComCtrls, QTypes, QExtCtrls,
QButtons, QControls, QForms, QStdCtrls;
VCL
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, ExtCtrls, Buttons, ComCtrls;
CLX: uses tetris2, Qt, Types;
VCL: uses Tetris2;
CLX only: tetro1.BorderStyle:= fbsDialog;
CLX on Linux:
case Key of
Key_Up: RotateFigure;
Key_Down,
Key_Space: begin //VK_SPACE in win
CLX on Win:
case Key of
VK_UP: RotateFigure;
VK_DOWN,
VK_SPACE: begin
So here we do have also a difference in between CLX, cause there is a dependency on the operation system in the constant table from CLib, the workaraound is easy:
{$IFDEF LINUX}
Key_Up: RotateFigure;
...
{$ENDIF}
{$IFDEF MSWINDOWS}
VK_UP: RotateFigure;
...
At the end some steps migrating existing Delphi/VCL apps to CLX
- Transfer or copy files to Linux
- Fix "{$R *.dfm}" references to xfm (keep separate)
- Rename *.dfm to *.xfm (names are CASE sensitiv!)
- Resolve different units, e.g. Forms.pas to QForms.pas
- Open project in Kylix and res file will be recreated if not copied
- Try to build project to get new dcu's
- Resolve any errors, diff. units or types or win32 API calls