Forum > Ported from Delphi/Kylix
Porting Lissajous Curve Maker from Delphi to Lazarus
Boleeman:
Hi.
I am trying to port a Lissajous Curve Maker from Delphi to Lazarus.
I compiled to Delphi program source using the Delphi 11 Community Version just to make sure the initial source code works. It works well.
Now for the conversion hassles:
The program uses a set of components which I converted from Delphi dpk to Lazarus dav7.lpk
I had an initial black screen which I solved by doing in TForm1.FormCreate(Sender: TObject);
form1.paintbox1.Canvas.Brush.Color := clWhite;
form1.paintbox1.Canvas.draw(0,0,map);
Now the errors that I get:
When trying to view the form I keep getting an error message
Unable to find the component class "TDavArrayBtn"
It is not registered via RegisterClass and no lfm was found
It is needed by unit1.pas
I opened the unit1.lfm and it was there:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- object DavArrayBtn1: TDavArrayBtn Left = 832 Top = 440 Width = 22 Height = 160 Hint = 'color selection' Border = 0 BtnHeight = 22 BtnSpacing = 1 BtnShape = bs3D BtnWidth = 22 BtnEdge = 2 Columns = 1 onBtnChange = DavArrayBtn1BtnChange onBtnPaint = DavArrayBtn1BtnPaint Rows = 7 end
One thread on the forumn by Jamie suggests to delete this to get to the form. If I delete that I can get to the form but then errors come up saying DavArrayBtn1 is not there. If I don't delete it then I cannot get to the form at design time. I even tried opening and registering the package but still no luck there (keep getting the error message).
Lastly no drawing of the Lissajous Curve shows up on the paintbox1.
Attached is the converted to Lazarus code plus the converted Dav7 components with the dav7.lpk lazarus package. What I did was loaded the code and then added the package by open package file and then add to project. The code compiles OK but I get that error and also nothing drawn to paintbox1.
Kind of going round in circles here trying to work out why nothing is drawing to the paintbox.
Been looking at unit2.pas
It contains pencolor procedures. Does something here have to be added to convert from Delphi to Lazarus?
rvk:
I just tried and it works fine.
But... did you install the dav7 package in your Lazarus?
I moved the dav7 zip to it's own directory and opened the package dav7 and installed it.
Then I opened your converted project (the other zip) and opened the project.
It couldn't find the dav7components.pas (which is logical because it's in another directory)
Then I added dav7 to the required packages (Project > Project Inspector > add required packages and choose dav7).
(adding the package as required also adds a search path to the directory with the dav7 pas files)
Then the project compiled and ran fine.
Note: Look under System in the component bar uf you see the 4 dav7 components (the one with the 3 colored bricks).
Boleeman:
OK I tried that but I still get the error and nothing drawn to the paintbox1. I am using Lazarus 2.2.4
Which Lazarus version are you using?
The project compiles OK and I get the form showing up at runtime. But when you mouse click labels/textboxes beside a, b or c on the program and then a curve should appear on the paintbox1. Nothing shows up here.
Also when I do View, Toggle Form/Unit view I still get that error.
Attached is my project inspector window with dav7components.pas included
I also looked at under System in the component bar but did NOT see the 4 dav7 components (the one with the 3 colored bricks).
Did your compiled version draw anything on the paintbox1?
wp:
Are the Dav7Components installed? They are visual components, and thus you should find the components on the component palette. If not you must install them: Normally you would go to "Package" > "Open Package File", navigate to the folder with the Dav7Components and load dav7.lpk. Click "Use" > "Install". But in this case, I suspect that the package is broken because it does not list any files. So - fix it, or better: do not install it, but create components at runtime!
Looking at the units of the Lissajous project i can see that the project uses only the TDavArrayBtn. When you create it at runtime you do not need to install the package. Do this:
* Make a backup copy of the entire project incl Dav7Components. The following operations are kind of "risky"...
* Open the file unit1.lfm in an external editor. Find the following block, copy it to the clipboard, then delete it. Save.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- object DavArrayBtn1: TDavArrayBtn Left = 832 Top = 440 Width = 22 Height = 160 Hint = 'color selection' Border = 0 BtnHeight = 22 BtnSpacing = 1 BtnShape = bs3D BtnWidth = 22 BtnEdge = 2 Columns = 1 onBtnChange = DavArrayBtn1BtnChange onBtnPaint = DavArrayBtn1BtnPaint Rows = 7 end
* Open Unit1.pas in the external editor, find the procedure TForm1.Create. Paste the clipboard after the "begin" of the procedure.
* In the first added line ("object DavArrayBtn1: TDavArrayBtn") delete the "object", replace the ":" by ":=", and add ".Create(self);" and - in a new line - "with DavArryBtn1 do begin" so this it becomes:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- DavArrayBtn1 := TDavArrayBtn.Create(self); with DavArrayBtn1 do begin
* In the following added lines replace the '=' by ':=' and add a ';' at the end of each line so that you have valid Pascal code. This is the result:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- DavArrayBtn1 := TDavArrayBtn.Create(self); with DavArraybtn1 do begin Left := 832; Top := 440; Width := 22; Height := 160; Hint := 'color selection'; Border := 0; BtnHeight := 22; BtnSpacing := 1; BtnShape := bs3D; BtnWidth := 22; BtnEdge := 2; Columns := 1; onBtnChange := DavArrayBtn1BtnChange; onBtnPaint := DavArrayBtn1BtnPaint; Rows := 7; end;
* Still in the external editor with Unit1.pas loaded, find the declaration of "DavArrayBtn1: TDavArrayBtn". Move it behind the "private" keyword of the form declaration. Save.
* Open the project in the IDE.
* In my case, the IDE reported that the Dav7Components cannot be found (or similar - I forgot...). I deleted the "..\Dav7Components\backup\backup\dav7components.pas" from the list of the project files and added the path to the Dav7Components files to the "Other unit files" path of the project options. Maybe this step is not required in your case. I removed the Dav7components entry from the "Include files" path because the package has no include files
* When I now compile the project there is an access violation, but the debugger does not show me the problematic source position. Looking at the project options ("Project" > "Project Options" > "Debugging") I see that there is no debugger support --> Checked "Generate info for debugger". When I re-run and the project aborts the debugger shows me the error in TWinControl.HandleAllocated - deep inside the LCL. I open "View" > "Debug Windows" > "Call stack", and the list shows me the path of code lines which lead to the error. The first accessible code line (lines are stacked from bottom up, though) points to TDavArrayBtn.BtnPaint. Obviously this is called too early before a handle has been created for the canvas. Adding a "if not canvas.HandleAllocated then exit" after the "begin" fixes the issue:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TdavArrayBtn.BtnPaint(btnNr : byte; bst : TBtnStatus);//if button hidden: erasevar r : Trect; radius : byte; k1,k2 : LongInt; i : byte;begin if not Canvas.HandleAllocated then exit; k1 := 0; k2 := 0; ...
* Running the project now, I see the white background. This is because you added the following lines to FormCreate. This is risky because the Canvas normally is not yet ready for painting in this early state. Also, do not mention "form1" in the code of the class TForm1 because then the code works only when its instance is named "form1". Moreover it is not clear whether "map" already exists here. Remove these lines - which makes the background black - which you wanted to avoid...
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- form1.paintbox1.Canvas.Brush.Color := clWhite; form1.paintbox1.Canvas.draw(0,0,map);
* I searched where "map" is created: Simply ctrl-left-click on the word "map", and the IDE opens the location where "map" is declared. It is in unit Unit2 and seems to be a TBitmap. Search for "Create", and the result tells that it is created in the initialization part of unit2 - well very early, rather inconventient, though, but not wrong. As I wrote in the other thread the best place to control the background color is immediately before creation of the bitmap:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- map := TBitmap.Create; with map do begin width := 800; height := 800; pixelformat := pf32bit; Canvas.Brush.Color := clWhite; Canvas.FillRect(0, 0, Width, Height); p0 := dword(scanline[0]); pstep := p0 - dword(scanline[1]); end;
* OK now, when I run the project now the white background is here again. But when I press "Paint" nothing happens. I change some parameter, "Paint" -- nothing..
* Fixing this requires to understand the code in unit2. Unfortunately this is no good code... Accessing "form1" again is a "crime", accessing pixels via pointers is not very clear. --> I think it is required to rewrite this part using fcl-image...Find in the attachment my current version.
rvk:
--- Quote from: Boleeman on September 01, 2023, 01:25:53 pm ---I also looked at under System in the component bar but did NOT see the 4 dav7 components (the one with the 3 colored bricks).
--- End quote ---
Woops. I forgot.
When opening dav4 package I noticed the dav7components.pas wasn't in the unit list. So there are no units that register themselves.
You need to add dav7components.pas to that unit list and then install dav7.
Then the components are installed correctly.
(I didn't test them further.)
Navigation
[0] Message Index
[#] Next page