Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2010-10

Delphi-Lazarus compatible code including serial port?

23 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bo Berglund

I have a rather extensive comm unit created in Delphi for communication with a data acquisition instrument via RS232. The task is to port a project using this file to Lazarus on Linux. Thanks to advice here I have found a serial port component that works in similar ways to the one I have used in Windows, so now I am embarking on the porting task.

In the existing unit the serial port communication component is instantiated in code rather than being dropped on a form.

Now I believe I have two options:
1) Sprinkle the code with conditionams for Delphi/Lazarus and use the 5dpo component and its specific calls for Lazarus and the existing code for Delphi. This will be rather ugly since the comm object FComm is used in many places in the code.

or
2) Maybe I can somehow disguise the actual implementation of FComm from my existing code and instead create a 5dpo object in Lazarus and the other type in Windows, but give the wrapper the same properties and methods as the existing component has.
This would involve wrapping 5dpo in a superclass, which translates the used properties/methods into 5dpo specifics.
Then I would be able to select the proper one to make based on conditionals inside a different unit from my main unit.

But how would this be done more specifically? Is there some description available on making code compatible between Delphi and Lazarus when there are component differences in the two systems as I described above?

(I don't know if this is off-topic here and should be posted to the fpc list instead, but since GMANE does not yet allow posting to the fpc group I hope you will not be offended by me posting this question here. It seems like it is both a Lazarus vs Delphi question and one regarding subclassing...)

Bo Berglund

Reply by email

Mattias Gaertner
to Bo Berglund
Show quoted text 25 lines
I have a rather extensive comm unit created in Delphi for communication with a data acquisition instrument via RS232. The task is to port a project using this file to Lazarus on Linux. Thanks to advice here I have found a serial port component that works in similar ways to the one I have used in Windows, so now I am embarking on the porting task. In the existing unit the serial port communication component is instantiated in code rather than being dropped on a form. Now I believe I have two options: 1) Sprinkle the code with conditionams for Delphi/Lazarus and use the 5dpo component and its specific calls for Lazarus and the existing code for Delphi. This will be rather ugly since the comm object FComm is used in many places in the code. or 2) Maybe I can somehow disguise the actual implementation of FComm from my existing code and instead create a 5dpo object in Lazarus and the other type in Windows, but give the wrapper the same properties and methods as the existing component has. This would involve wrapping 5dpo in a superclass, which translates the used properties/methods into 5dpo specifics. Then I would be able to select the proper one to make based on conditionals inside a different unit from my main unit.

Many projects did 2).

But how would this be done more specifically? Is there some description available on making code compatible between Delphi and Lazarus when there are component differences in the two systems as I described above?

There are many ways. For example:

uses
  {$IFDEF LCL} // or use ifdef FPC
  fpcunit
  {$ELSE}
  delphiunit
  {$ENDIF};

or you can put the whole unit into ifdefs:

myserial.pas:

{$IFDEF FPC}
{$INCLUDE fpcserial.pas}
{$ELSE}
{$INCLUDE delphiserial.pas}
{$ENDIF}
Show quoted text 5 lines
(I don't know if this is off-topic here and should be posted to the fpc list instead, but since GMANE does not yet allow posting to the fpc group I hope you will not be offended by me posting this question here. It seems like it is both a Lazarus vs Delphi question and one regarding subclassing...)

Mattias

Reply by email

Luca Olivetti
to Bo Berglund: I have a rather extensive comm unit created in Delphi for communication with a data…

Al 10/10/10 11:46, En/na Bo Berglund ha escrit:

But how would this be done more specifically? Is there some description available on making code compatible between Delphi and Lazarus when there are component differences in the two systems as I described above?

Drop Delphi and simply use Lazarus both for windows and Linux?

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 (Ext.133) Fax +34 93 5883007

Reply by email

Bo Berglund
to Luca Olivetti
Luca Olivetti wrote 10 lines
Al 10/10/10 11:46, En/na Bo Berglund ha escrit: > But how would this be done more specifically? Is there some > description available on making code compatible between Delphi and > Lazarus when there are component differences in the two systems as I > described above? Drop Delphi and simply use Lazarus both for windows and Linux?

Well,
that is not really possible...
In other parts of the software we build there is a lot of Delphi and Windows specific stuff, like components only available for Delphi, access to databases via ADO and what have you...

The task before me is to use some preexisting classes from our Delphi system in a Lazarus project that can be ported over to Linux. We intend to include a Linux based touch panel front-end to the instrument and when programming that I have zoomed in on Lazarus in order to re-use existing Delphi code.
So I will use conditionals to make the class unit compatible to Lazarus and Delphi.

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Mattias Gaertner: On Sun, 10 Oct 2010 11:46:43 +0200 Many projects did 2). There are many ways. For example:
Mattias Gaertner wrote 28 lines
On Sun, 10 Oct 2010 11:46:43 +0200 Bo Berglund wrote: > But how would this be done more specifically? Is there some > description available on making code compatible between Delphi and > Lazarus when there are component differences in the two systems as I > described above? There are many ways. For example: uses {$IFDEF LCL} // or use ifdef FPC fpcunit {$ELSE} delphiunit {$ENDIF}; or you can put the whole unit into ifdefs: myserial.pas: {$IFDEF FPC} {$INCLUDE fpcserial.pas} {$ELSE} {$INCLUDE delphiserial.pas} {$ENDIF}

I am trying to make a wrapper for the sdpoSerial so it will mimick the TSerial I am using in Delphi. With the conditionals in place Delphi with use unit Serial and Lazarus unit SerialLazarus (the wrapper):

uses
  {$IFDEF LCL} // or use ifdef FPC
  SerialLazarus,
  {$ELSE}
  Serial,
  {$ENDIF}

One question though:
I need to enter this at the top of my big unit to stop Lazarus/FPC from complaining about syntax errors:

{$MODE Delphi}
But if this is detected by Delphi it will complain that there is no
MODE command, so can I legally do this:
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}

(I.e. can one enter compiler directives condistioned on other things in an ifdef construct?)

Bo Berglund Developer in Sweden

Reply by email

Sven Barth
to Bo Berglund
Bo Berglund wrote 16 lines
One question though: I need to enter this at the top of my big unit to stop Lazarus/FPC from complaining about syntax errors: {$MODE Delphi} But if this is detected by Delphi it will complain that there is no MODE command, so can I legally do this: {$IFDEF FPC} {$MODE Delphi} {$ENDIF} (I.e. can one enter compiler directives condistioned on other things in an ifdef construct?)

Yes, that is perfectly legal and even necessary if you use multiple compilers.
You can also write all those settings into an *.inc file and just include that at the top of your unit (e.g. {$I compilerswitches.inc}); this works in both FPC and Delphi and so you have the same settings in all your units where you include that file (of course you need to include the {$ifdef fpc} inside the include file).

Regards,
Sven

Reply by email

Bo Berglund
to Sven Barth
Sven Barth wrote 10 lines
> (I.e. can one enter compiler directives condistioned on other things > in an ifdef construct?) > Yes, that is perfectly legal and even necessary if you use multiple compilers. You can also write all those settings into an *.inc file and just include that at the top of your unit (e.g. {$I compilerswitches.inc}); this works in both FPC and Delphi and so you have the same settings in all your units where you include that file (of course you need to include the {$ifdef fpc} inside the include file).

Well, it seems like there are more conditionals needed in a multi-use unit. For example there is no place for units Windows and Variants on Lazarus and there are Lazarus units that Delphi doesn't like. So I have first let Lazarus adjust my Delphi project and then I have examined the differences and put in conditionals for FPC so that the code passes through Delphi just like before.

But then I have encountered a lot of problems in a graphics class I created years ago to plot simple diagrams on a TImage Canvas. Apparently a *lot* of properties and methods pertaining to the TImage Canvas are defined in unit Windows, which must not be used with Lazarus...

So how can I get the darn graphics working in Lazarus and Delphi? I thought that the image canvas was somehow dealt with in Lazarus so it could be used just like in Delphi. Mind you, I am not doing rocket science with my graphics class, I just made it able to plot using floats as coourdinates and the shapes plotted are lines, circles, boxes and the like plus text.
Here is an example method that bombs:

function TGraphImage.TiltedText(X1, Y1, A: double; sText: string):
boolean;
var
	lf : {$IFNDEF FPC} TLogFont {$ELSE} TFont {$ENDIF};
	tf : TFont;
	nX, nY, nH: integer;
begin
	Result := false;
	if not Assigned(FPlotImage) then exit;
	with FPlotImage.Canvas do
  begin
  	nH := Font.Height;
  	nX := Round((X1-FOffsX) * FScaleX);
  	nY := Round((FOffsY-Y1) * FScaleY) + nH;
  	tf := TFont.Create;
  	tf.Assign(Font);
  	GetObject(tf.Handle, sizeof(lf), @lf);
  	lf.lfEscapement := Round(A*10);
  	lf.lfOrientation := Round(A*10);
  	tf.Handle := CreateFontIndirect(lf);
  	Font.Assign(tf);
  	Brush.Style := bsClear;
  	TextOut(nX-nH, nY, sText);
  	{Reset orientation}
  	lf.lfEscapement := 0;
  	lf.lfOrientation := 0;
  	tf.Handle := CreateFontIndirect(lf);
  	Font.Assign(tf);
  	tf.Free;
	end;
	Result := true;
end;

Lazarus does not like TLogFont and I found it came from Windows so I put a conditional there. But it only stepped to the next error: GetObject is apparently a Windows defined method as well.... And on it goes (lfEscapement, lfOrientation, Handle, CreateFontIndirect).

(By the way I tried to indent the code example using settings that should put spaces in there but as you can see the indentation is by TAB chars instead...

Bo Berglund

Reply by email

Michael Schnell
to Bo Berglund: I have a rather extensive comm unit created in Delphi for communication with a data…
Show quoted text 5 lines
1) Sprinkle the code with conditionams for Delphi/Lazarus and use the 5dpo component and its specific calls for Lazarus and the existing code for Delphi. This will be rather ugly since the comm object FComm is used in many places in the code.

You can easily instantiate AsyncPro in user code in Delphi, too (I'm doing this all the time), so that I don't need to "install" complex packages with Delphi).

You can do your own "Async" unit (maybe even with an interface very similar to AsyncPro, so that you don't need to do many changes in your existing code <other than manually instantiating the object). In this unit you can use ifdefs or do two versions of same. (please do provide this unit as open source :) )

-Michael

Reply by email

Juha Manninen gmail
to Bo Berglund: On Sun, 10 Oct 2010 17:52:46 +0200, Sven Barth Well, it seems like there are more…
Bo Berglund wrote 5 lines
Lazarus does not like TLogFont and I found it came from Windows so I put a conditional there. But it only stepped to the next error: GetObject is apparently a Windows defined method as well.... And on it goes (lfEscapement, lfOrientation, Handle, CreateFontIndirect).

Why didn't you use the improved Delphi converter in Lazarus trunk version as I recommended earlier?

It does: 'Windows' --> 'LCLIntf, LCLType, LMessages'

It also does:
{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}

which you were asking.
If you have a technican problem with the converter, please create a bug report.

(By the way I tried to indent the code example using settings that should put spaces in there but as you can see the indentation is by TAB chars instead...

Get rid of the tabs first.

Juha

Reply by email

Vincent Snijders
to Michael Schnell

2010/10/11 Michael Schnell :

Show quoted text 7 lines
?On 10/10/2010 01:33 PM, Luca Olivetti wrote: > > Drop Delphi and simply use Lazarus both for windows and Linux? The seemingly still existing Lazarus Bug regarding TThread.Synchronize might be a show stopper.

What is its issue number in the bug tracker?

Vincent

Reply by email

Michael Schnell
to Vincent Snijders

On 10/11/2010 01:24 PM, Vincent Snijders wrote

What is its issue number in the bug tracker?

Sorry I don't know how to search the bug tracker.

Some days ago someone in some Forum posted that "Synchronize is not implemented as sophisticatedly as in Delphi and therefor if many Synchronizes are fired simultaneously the Application will hang".

Does that help ?
-Michael

Reply by email

Vincent Snijders
to Michael Schnell

2010/10/11 Michael Schnell :

Show quoted text 11 lines
?On 10/11/2010 01:24 PM, Vincent Snijders wrote > > What is its issue number in the bug tracker? > Sorry I don't know how to search the bug tracker. Some days ago someone in some Forum posted that "Synchronize is not implemented as sophisticatedly as in Delphi and therefor if many Synchronizes are fired simultaneously the Application will hang". Does that help ?

It helps spreading uncertainty, but it doesn't help to improving any seemingly existing issue (if any).

An issue in the bug tracker with an example that demonstrates this issue actually helps.

Vincent

Reply by email

Bo Berglund
to Juha Manninen gmail: Why didn't you use the improved Delphi converter in Lazarus trunk version as I…
Show quoted text 12 lines
On Monday 11 October 2010 00:47:56 Bo Berglund wrote: > Lazarus does not like TLogFont and I found it came from Windows so I > put a conditional there. But it only stepped to the next error: > GetObject is apparently a Windows defined method as well.... > And on it goes (lfEscapement, lfOrientation, Handle, > CreateFontIndirect). Why didn't you use the improved Delphi converter in Lazarus trunk version as I recommended earlier? It does: 'Windows' --> 'LCLIntf, LCLType, LMessages'

Thanks!
I manually added these conditionals to the uses section of the unit that complained about the TLogFont and its properties: {$IFDEF FPC}
LCLIntf,
LCLType,
LMessages,
{$ELSE}
Windows,
{$ENDIF}

With this in place the compiler did not stop there anymore! :-)

But now I am stuck at this code section, which has a similar cause I'm sure:

  FPlotImage.Canvas.Brush.Color := clFill;
  FPlotImage.Canvas.Brush.Style := bsSolid;
  FPlotImage.Canvas.FloodFill(nX, nY, clOrg, fsSurface);

On the last line FPC complains: "Identifier not found "fsSurface""

In Delphi7 this constant is defined in Windows, but now when I have replaced Windows by the three files you suggested it still does not work. How can i find out where in Lazarus this constant is defined?

I might add that Google just leads me to bible quotes (Lazarus) or to Delphi, which is not what I need...

Bo Berglund

Reply by email

Bo Berglund
to Michael Schnell: You can easily instantiate AsyncPro in user code in Delphi, too (I'm doing this all the…
Michael Schnell wrote 16 lines
> 1) Sprinkle the code with conditionams for Delphi/Lazarus and use the > 5dpo component and its specific calls for Lazarus and the existing > code for Delphi. This will be rather ugly since the comm object FComm > is used in many places in the code. > You can easily instantiate AsyncPro in user code in Delphi, too (I'm doing this all the time), so that I don't need to "install" complex packages with Delphi). You can do your own "Async" unit (maybe even with an interface very similar to AsyncPro, so that you don't need to do many changes in your existing code <other than manually instantiating the object). In this unit you can use ifdefs or do two versions of same. (please do provide this unit as open source :) )

Well the original communications code was written back in the last century using Delphi5 if I remember correctly. In any case it is not using AsyncPro because we got a much simpler Com port component from a guy in the UK at a reasonable price, at a time AsyncPro was priced comparable to the whole Delphi Pro package....

So I have now to camouflage sdpoSerial as a TSerial class where TSerial is the one we bought so long ago.

When I am discussing old Delphi code:

We made a child off of TListView which we called TEasyListView where we set certain properties differently (for example we always want it to be in Report style and we want full row select when clicking). We also added an event for the select (OnItemSelect) which we use extensively in all of our lists in the database applications.

Is there any chance at all of getting such a component working cross-platform on Lazarus/FPC? After all the TListView is a Windows MFC object.....
I know there is a TListView also in Lazarus, does it sport the same properties and methods/events as the Delphi one does?

And how do you add a graphics component to Lazarus? There is no Component menu item like there is in Delphi.
I would like to test by adding the TEasyListView as is if possible.

Bo Berglund Developer in Sweden

Reply by email

Felipe Monteiro de Carvalho
to Bo Berglund: On Mon, 11 Oct 2010 12:25:52 +0300, "Juha Manninen (gmail)" Thanks! I manually added…
Bo Berglund wrote
On the last line FPC complains: "Identifier not found "fsSurface""

In Lazarus. Open the menu Search -> Find in Files

Select "search in directories", put fsSurface and set the path to something equivalente in your system to
/Users/felipe/Programas/lazarus/lcl

Now search.

In 5 seconds I found in the constant in the unit GraphType

Right-clicking in a function or type and selecting "Find declaration" also allows you to find place were types are declared.

Felipe Monteiro de Carvalho

Reply by email

Bo Berglund
to Felipe Monteiro de Carvalho
Felipe Monteiro de Carvalho wrote 15 lines
On Mon, Oct 11, 2010 at 7:31 PM, Bo Berglund wrote: > On the last line FPC complains: "Identifier not found "fsSurface"" In Lazarus. Open the menu Search -> Find in Files Select "search in directories", put fsSurface and set the path to something equivalente in your system to /Users/felipe/Programas/lazarus/lcl Now search. In 5 seconds I found in the constant in the unit GraphType Right-clicking in a function or type and selecting "Find declaration" also allows you to find place were types are declared.

I had never used the Delphi search facility across files in all these years so it did not occur to me. I always used grep to find stuff in files and I did not know where lazarus stores the standard files.

Anyway thanks to your info I have now passed the compileation of my new wrapper for TSerial in the old Delphi app (it is just a skeleton yet, but the framework is in place).

Now compilation wanders forward from unit to unit where I need to add the conditional:

{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}

to get it working. :-)

I have done this on about 10 used units now and it seems to always work when there are error messages like typecasting string to PChar and it complains about shortstring being incompatible to PChar...

But now I have reached the problem with our own components, so I have to read up on how one can register components on the Lazarus palette (at least for the visible GUI components)...

Bo Berglund

Reply by email

Michael Schnell
to Bo Berglund: On Mon, 11 Oct 2010 11:25:45 +0200, Michael Schnell Well the original communications code…
Bo Berglund wrote 5 lines
Is there any chance at all of getting such a component working cross-platform on Lazarus/FPC? After all the TListView is a Windows MFC object..... I know there is a TListView also in Lazarus, does it sport the same properties and methods/events as the Delphi one does?

Should at least be very similar...

And how do you add a graphics component to Lazarus?

There is a decent menu system for adding packages / visual components. Other than with Delphi all this is based on source code and you need to recompile Lazarus to activate the new visual components in the tabs.

-Mic hael

Reply by email

Bo Berglund
to Michael Schnell
Michael Schnell wrote 12 lines
On 10/11/2010 08:21 PM, Bo Berglund wrote: > Is there any chance at all of getting such a component working > cross-platform on Lazarus/FPC? After all the TListView is a Windows > MFC object..... > I know there is a TListView also in Lazarus, does it sport the same > properties and methods/events as the Delphi one does? Should at least be very similar... > And how do you add a graphics component to Lazarus? There is a decent menu system for adding packages / visual components. Other than with Delphi all this is based on source code and you need to recompile Lazarus to activate the new visual components in the tabs.

So I have to create a new package in Lazarus, then add the sourcefile to this and compile + install?

Do Lazarus component sourcefiles also have a Register procedure thta tells Lazarus that it is in fact a component?

I have to get the darn thing through the compilation first of course and now I have problems with the properties of a TListView in Delphi being different from those of the Lazarus TListView. The Delphi custom component is a visual one, a descendant from TListView with built-in properties and methods/events like ItemIndex, OnItemSelect, sorting and more.

Right now I have reached error messages because of: StateIndex and CustomSort. Still struggling...

Bo Berglund

Reply by email

Luca Olivetti
to Michael Schnell: The seemingly still existing Lazarus Bug regarding TThread.Synchronize might be a show…

En/na Michael Schnell ha escrit:

Show quoted text 5 lines
On 10/10/2010 01:33 PM, Luca Olivetti wrote: > > Drop Delphi and simply use Lazarus both for windows and Linux? The seemingly still existing Lazarus Bug regarding TThread.Synchronize might be a show stopper.

That's new to me (and I use threads extensively).

Bye

Luca Olivetti Wetron Automatizaci?n S.A. http://www.wetron.es/ Tel. +34 93 5883004 (Ext.133) Fax +34 93 5883007

Reply by email