From 7516bd3d9dcc023e83a8136ef83f8694ebdb2f25 Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Tue, 10 Jun 2025 22:31:16 +0200 Subject: [PATCH] Blockly test --- Blockly/Delphi/BlocklyTest.dpr | 15 + Blockly/Delphi/BlocklyTest.dproj | 1195 ++++++++++++++++++++++++++++++ Blockly/Delphi/BlocklyTest.res | Bin 0 -> 154804 bytes Blockly/Delphi/LLVM.Runner.pas | 68 ++ Blockly/Delphi/MainUnit.fmx | 68 ++ Blockly/Delphi/MainUnit.pas | 314 ++++++++ Blockly/Readme.txt | 74 ++ Blockly/blockly_delphi_test.html | 163 ++++ Blockly/blockly_llvm.html | 192 +++++ 9 files changed, 2089 insertions(+) create mode 100644 Blockly/Delphi/BlocklyTest.dpr create mode 100644 Blockly/Delphi/BlocklyTest.dproj create mode 100644 Blockly/Delphi/BlocklyTest.res create mode 100644 Blockly/Delphi/LLVM.Runner.pas create mode 100644 Blockly/Delphi/MainUnit.fmx create mode 100644 Blockly/Delphi/MainUnit.pas create mode 100644 Blockly/Readme.txt create mode 100644 Blockly/blockly_delphi_test.html create mode 100644 Blockly/blockly_llvm.html diff --git a/Blockly/Delphi/BlocklyTest.dpr b/Blockly/Delphi/BlocklyTest.dpr new file mode 100644 index 0000000..a2684f8 --- /dev/null +++ b/Blockly/Delphi/BlocklyTest.dpr @@ -0,0 +1,15 @@ +program BlocklyTest; + +uses + System.StartUpCopy, + FMX.Forms, + MainUnit in 'MainUnit.pas' {MainForm}, + LLVM.Runner in 'LLVM.Runner.pas'; + +{$R *.res} + +begin + Application.Initialize; + Application.CreateForm(TMainForm, MainForm); + Application.Run; +end. diff --git a/Blockly/Delphi/BlocklyTest.dproj b/Blockly/Delphi/BlocklyTest.dproj new file mode 100644 index 0000000..ac9401a --- /dev/null +++ b/Blockly/Delphi/BlocklyTest.dproj @@ -0,0 +1,1195 @@ + + + {A64274A6-58A9-4216-B2AF-3BDD62B90E62} + 20.3 + FMX + True + Debug + Win64 + BlocklyTest + 3 + Application + BlocklyTest.dpr + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns + BlocklyTest + + 1031 + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + + + vclwinx;fmx;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;FireDACCommonODBC;FireDACCommonDriver;IndyProtocols;vclx;Skia.Package.RTL;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;bindcompfmx;inetdb;FireDACSqliteDriver;DbxClientDriver;Tee;soapmidas;vclactnband;TeeUI;fmxFireDAC;dbexpress;DBXMySQLDriver;VclSmp;inet;vcltouch;fmxase;dbrtl;Skia.Package.FMX;fmxdae;TeeDB;FireDACMSAccDriver;CustomIPTransport;vcldsnap;DBXInterBaseDriver;IndySystem;Skia.Package.VCL;vcldb;vclFireDAC;bindcomp;FireDACCommon;inetstn;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;adortl;vclimg;FireDACPgDriver;FireDAC;inetdbxpress;xmlrtl;tethering;bindcompvcl;dsnap;CloudService;fmxobj;bindcompvclsmp;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + $(BDS)\bin\default_app.manifest + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + + + vclwinx;fmx;vclie;DbxCommonDriver;bindengine;IndyIPCommon;VCLRESTComponents;FireDACCommonODBC;FireDACCommonDriver;IndyProtocols;vclx;IndyIPClient;dbxcds;vcledge;bindcompvclwinx;FmxTeeUI;bindcompfmx;inetdb;FireDACSqliteDriver;DbxClientDriver;Tee;soapmidas;vclactnband;TeeUI;fmxFireDAC;dbexpress;DBXMySQLDriver;VclSmp;inet;vcltouch;fmxase;dbrtl;fmxdae;TeeDB;FireDACMSAccDriver;CustomIPTransport;vcldsnap;DBXInterBaseDriver;IndySystem;Skia.Package.VCL;vcldb;vclFireDAC;bindcomp;FireDACCommon;inetstn;IndyCore;RESTBackendComponents;bindcompdbx;rtl;FireDACMySQLDriver;FireDACADSDriver;RESTComponents;DBXSqliteDriver;vcl;IndyIPServer;dsnapxml;dsnapcon;adortl;vclimg;FireDACPgDriver;FireDAC;inetdbxpress;xmlrtl;tethering;bindcompvcl;dsnap;CloudService;fmxobj;bindcompvclsmp;FMXTee;soaprtl;soapserver;FireDACIBDriver;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + Debug + true + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + $(BDS)\bin\default_app.manifest + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png + $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png + + + DEBUG;$(DCC_Define) + true + false + true + true + true + true + true + + + false + PerMonitorV2 + + + PerMonitorV2 + true + 1033 + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + PerMonitorV2 + + + PerMonitorV2 + + + + MainSource + + +
MainForm
+ fmx +
+ + + + Base + + + Cfg_1 + Base + + + Cfg_2 + Base + +
+ + Delphi.Personality.12 + Application + + + + BlocklyTest.dpr + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + + + true + + + + + true + + + + + true + + + + + .\ + true + + + + + BlocklyTest.exe + true + + + + + BlocklyTest.rsm + true + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + res\xml + 1 + + + res\xml + 1 + + + + + library\lib\armeabi + 1 + + + library\lib\armeabi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\mips + 1 + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-v21 + 1 + + + res\values-v21 + 1 + + + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\values-v35 + 1 + + + res\values-v35 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-mdpi + 1 + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + res\drawable-xhdpi + 1 + + + + + res\drawable-xxhdpi + 1 + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-xxxhdpi + 1 + + + res\drawable-xxxhdpi + 1 + + + + + res\drawable-small + 1 + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + res\drawable-xlarge + 1 + + + + + res\values + 1 + + + res\values + 1 + + + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + + + + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + Contents\MacOS + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + Contents\MacOS + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + Contents\Resources\StartUp\ + 0 + + + 0 + + + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + Contents + 1 + + + Contents + 1 + + + Contents + 1 + + + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + library\lib\arm64-v8a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + Contents\MacOS + 1 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + ..\ + 1 + + + ..\ + 1 + + + ..\ + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).launchscreen + 64 + + + ..\$(PROJECTNAME).launchscreen + 64 + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset + 1 + + + + + + + + + + + + + + + + + True + True + + + 12 + + + + + + + False + + False + copy /Y "C:\Program Files (x86)\Embarcadero\Studio\23.0\Redist\win64\WebView2Loader.dll" $(OUTPUTDIR) + False + + + + False + + False + copy /Y "C:\Program Files (x86)\Embarcadero\Studio\23.0\Redist\win64\WebView2Loader.dll" $(OUTPUTDIR) + False + + + + False + + False + copy /Y "C:\Program Files (x86)\Embarcadero\Studio\23.0\Redist\win64\WebView2Loader.dll" $(OUTPUTDIR) + False + + + + False + + False + copy /Y "C:\Program Files (x86)\Embarcadero\Studio\23.0\Redist\win64\WebView2Loader.dll" $(OUTPUTDIR) + False + +
diff --git a/Blockly/Delphi/BlocklyTest.res b/Blockly/Delphi/BlocklyTest.res new file mode 100644 index 0000000000000000000000000000000000000000..25c74b4b3d1208d63b186ee6c3352c3bba8cd986 GIT binary patch literal 154804 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 Y84SQ(zliH2I^&Z*_`}?fas$)<1NeQ+UjP6A literal 0 HcmV?d00001 diff --git a/Blockly/Delphi/LLVM.Runner.pas b/Blockly/Delphi/LLVM.Runner.pas new file mode 100644 index 0000000..923780e --- /dev/null +++ b/Blockly/Delphi/LLVM.Runner.pas @@ -0,0 +1,68 @@ +unit LLVM.Runner; + +interface + +uses + System.SysUtils, Winapi.Windows, System.Classes; + +type + // Callback-Prozedur, die von der DLL aufgerufen wird + TLogIntegerCallback = procedure( AValue: Integer ); stdcall; + + // Signatur der exportierten DLL-Funktion + TStarteLogikProc = procedure( ALogCallback: TLogIntegerCallback ); stdcall; + +type + TLLVMRunner = class + private + FModule: HMODULE; + FStarteLogik: TStarteLogikProc; + class var + FLog: TStrings; + class procedure LogInteger( AValue: Integer ); static; stdcall; + public + constructor Create(const ADLLPath: string); + destructor Destroy; override; + procedure Execute; + class property Log: TStrings read FLog write FLog; + end; + +implementation + +{ TLLVMRunner } + +constructor TLLVMRunner.Create(const ADLLPath: string); +begin + inherited Create; + FModule := LoadLibrary( PChar( ADLLPath ) ); + if FModule = 0 then + raise Exception.Create( 'Failed to load DLL.' ); + + FStarteLogik := GetProcAddress( FModule, 'StarteLogik' ); + if not Assigned( FStarteLogik ) then + raise Exception.Create( 'Procedure "StarteLogik" not found in DLL.' ); +end; + +destructor TLLVMRunner.Destroy; +begin + if FModule <> 0 then + FreeLibrary( FModule ); + inherited; +end; + +procedure TLLVMRunner.Execute; +begin + if Assigned( FStarteLogik ) then + // Führe die DLL-Funktion aus und übergebe unsere Callback-Methode + FStarteLogik( LogInteger ); +end; + +// Dies ist die Methode, die die DLL aufruft. +// Sie muss "static" (class procedure) sein, um eine feste Adresse zu haben. +class procedure TLLVMRunner.LogInteger( AValue: Integer ); +begin + if Assigned( FLOg ) then + FLog.Add( Format( 'DLL logged integer: %d', [AValue] ) ); +end; + +end. diff --git a/Blockly/Delphi/MainUnit.fmx b/Blockly/Delphi/MainUnit.fmx new file mode 100644 index 0000000..81ddf10 --- /dev/null +++ b/Blockly/Delphi/MainUnit.fmx @@ -0,0 +1,68 @@ +object MainForm: TMainForm + Left = 0 + Top = 0 + Caption = 'Form1' + ClientHeight = 872 + ClientWidth = 1010 + FormFactor.Width = 320 + FormFactor.Height = 480 + FormFactor.Devices = [Desktop] + OnCreate = FormCreate + OnDestroy = FormDestroy + DesignerMasterStyle = 0 + object WebBrowser1: TWebBrowser + Align = Top + Anchors = [akLeft, akTop, akRight, akBottom] + Size.Width = 1010.000000000000000000 + Size.Height = 633.000000000000000000 + Size.PlatformDefault = False + WindowsEngine = EdgeOnly + OnDidFinishLoad = WebBrowser1DidFinishLoad + end + object LauchSiteButton: TButton + Anchors = [akLeft, akBottom] + Position.X = 24.000000000000000000 + Position.Y = 744.000000000000000000 + TabOrder = 1 + Text = 'Lauch Site' + TextSettings.Trimming = None + OnClick = LauchSiteButtonClick + end + object SaveWorkspaceButton: TButton + Anchors = [akLeft, akBottom] + Position.X = 24.000000000000000000 + Position.Y = 774.000000000000000000 + Size.Width = 97.000000000000000000 + Size.Height = 22.000000000000000000 + Size.PlatformDefault = False + TabOrder = 2 + Text = 'Save Workspace' + TextSettings.Trimming = None + OnClick = SaveWorkspaceButtonClick + end + object GenerateCodeButton: TButton + Anchors = [akLeft, akBottom] + Position.X = 24.000000000000000000 + Position.Y = 804.000000000000000000 + Size.Width = 97.000000000000000000 + Size.Height = 22.000000000000000000 + Size.PlatformDefault = False + TabOrder = 3 + Text = 'Generate Code' + TextSettings.Trimming = None + OnClick = GenerateCodeButtonClick + end + object Memo: TMemo + Touch.InteractiveGestures = [Pan, LongTap, DoubleTap] + DataDetectorTypes = [] + Anchors = [akRight, akBottom] + Position.X = 144.000000000000000000 + Position.Y = 641.000000000000000000 + Size.Width = 841.000000000000000000 + Size.Height = 223.000000000000000000 + Size.PlatformDefault = False + TabOrder = 4 + Viewport.Width = 837.000000000000000000 + Viewport.Height = 219.000000000000000000 + end +end diff --git a/Blockly/Delphi/MainUnit.pas b/Blockly/Delphi/MainUnit.pas new file mode 100644 index 0000000..9717d48 --- /dev/null +++ b/Blockly/Delphi/MainUnit.pas @@ -0,0 +1,314 @@ +unit MainUnit; + +interface + +uses + System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, + FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Controls.Presentation, FMX.StdCtrls, FMX.WebBrowser, + Winapi.WebView2, FMX.Memo.Types, FMX.ScrollBox, FMX.Memo, + // Korrekte und vollständige Units + System.IOUtils, System.Threading, System.Diagnostics, Winapi.Windows, LLVM.Runner; + +const + // Pfad zur HTML-Datei + PATH_BLOCKLY = 'T:\Myc\Blockly\blockly_LLVM.html'; + + // Pfade zu den LLVM-Werkzeugen + CLANG_PATH = 'clang.exe'; + LLD_PATH = 'lld-link.exe'; + +type + TMainForm = class( TForm ) + WebBrowser1: TWebBrowser; + LauchSiteButton: TButton; + SaveWorkspaceButton: TButton; + GenerateCodeButton: TButton; + Memo: TMemo; + procedure FormCreate( Sender: TObject ); + procedure FormDestroy( Sender: TObject ); + procedure LauchSiteButtonClick( Sender: TObject ); + procedure SaveWorkspaceButtonClick( Sender: TObject ); + procedure GenerateCodeButtonClick( Sender: TObject ); + procedure WebBrowser1DidFinishLoad( ASender: TObject ); + private + { Private declarations } + FWebView: ICoreWebView2; + FWebMessageReceiver: ICoreWebView2WebMessageReceivedEventHandler; + FWebMessageReceivedToken: EventRegistrationToken; + procedure HandleWebMessage( const AMessage: string ); + function ExecuteProcess( const ACommand: string; const AParameters: string ): string; + public + { Public declarations } + end; + +var + MainForm: TMainForm; + +implementation + +{$R *.fmx} + + +type + TWebMessageReceiver = class( TInterfacedObject, ICoreWebView2WebMessageReceivedEventHandler ) + private + FOwner: TMainForm; + public + constructor Create( AOwner: TMainForm ); + function Invoke( const Sender: ICoreWebView2; const args: ICoreWebView2WebMessageReceivedEventArgs ): HResult; stdcall; + end; + +constructor TWebMessageReceiver.Create( AOwner: TMainForm ); +begin + inherited Create; + FOwner := AOwner; +end; + +function TWebMessageReceiver.Invoke( const Sender: ICoreWebView2; const args: ICoreWebView2WebMessageReceivedEventArgs ): HResult; +var + message: PWideChar; +begin + Result := args.TryGetWebMessageAsString( message ); + if Succeeded( Result ) then + begin + TThread.Queue( nil, + procedure + begin + FOwner.HandleWebMessage( string( message ) ); + end ); + end; + Result := S_OK; +end; + +procedure TMainForm.FormCreate( Sender: TObject ); +begin + TLLVMRunner.Log := Memo.Lines; +end; + +procedure TMainForm.FormDestroy( Sender: TObject ); +begin + TLLVMRunner.Log := nil; + if ( FWebView <> nil ) and ( FWebMessageReceivedToken.value <> 0 ) then + begin + FWebView.remove_WebMessageReceived( FWebMessageReceivedToken ); + end; +end; + +function TMainForm.ExecuteProcess( const ACommand: string; const AParameters: string ): string; +var + sa: TSecurityAttributes; + si: TStartupInfo; + pi: TProcessInformation; + stdOutRead, stdOutWrite: THandle; + success: Boolean; + cmdLine: string; + buffer: TBytes; + bytesRead: Cardinal; + output, errors: string; +begin + // Pipe für StdOut und StdErr erstellen + sa.nLength := SizeOf( TSecurityAttributes ); + sa.lpSecurityDescriptor := nil; + sa.bInheritHandle := True; + + // Für stdout und stderr wird dieselbe Pipe verwendet, da clang Fehler auf stdout ausgibt + if not CreatePipe( stdOutRead, stdOutWrite, @sa, 0 ) then + Exit( 'Error creating pipe.' ); + + try + // StartupInfo vorbereiten + FillChar( si, SizeOf( TStartupInfo ), 0 ); + si.cb := SizeOf( TStartupInfo ); + si.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW; + si.wShowWindow := SW_HIDE; // Fenster explizit verstecken + si.hStdInput := GetStdHandle( STD_INPUT_HANDLE ); + si.hStdOutput := stdOutWrite; + si.hStdError := stdOutWrite; // Leite stderr auf dieselbe Pipe wie stdout + + cmdLine := Format( '"%s" %s', [ACommand, AParameters] ); + + success := CreateProcess( + nil, + PChar( cmdLine ), + nil, + nil, + True, + CREATE_NO_WINDOW, + nil, + nil, + si, + pi + ); + + // Schreib-Handle der Pipe sofort schließen + CloseHandle( stdOutWrite ); + + if not success then + Exit( Format( 'CreateProcess failed. Code: %d', [GetLastError] ) ); + + try + output := ''; + // Warten, bis der Prozess fertig ist und alle Daten in die Pipe geschrieben hat + if WaitForSingleObject( pi.hProcess, 5000 ) = WAIT_TIMEOUT then // 5s Timeout + begin + TerminateProcess( pi.hProcess, 1 ); + Exit( 'Process timed out.' ); + end; + + // Bytes aus der Pipe lesen + repeat + SetLength( buffer, 1024 ); + bytesRead := 0; + if ReadFile( stdOutRead, buffer[0], Length( buffer ), bytesRead, nil ) and ( bytesRead > 0 ) then + begin + SetLength( buffer, bytesRead ); + // Gelesene Bytes mit dem Default-System-Encoding in einen String umwandeln + output := output + TEncoding.Default.GetString( buffer ); + end + else + begin + break; // Pipe ist leer oder Fehler + end; + until False; + + finally + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + end; + + Result := output; + + finally + CloseHandle( stdOutRead ); + end; +end; + +procedure TMainForm.LauchSiteButtonClick( Sender: TObject ); +begin + WebBrowser1.Navigate( PATH_BLOCKLY ); +end; + +procedure TMainForm.SaveWorkspaceButtonClick( Sender: TObject ); +begin + WebBrowser1.EvaluateJavaScript( 'saveWorkspace()' ); +end; + +procedure TMainForm.GenerateCodeButtonClick( Sender: TObject ); +begin + WebBrowser1.EvaluateJavaScript( 'generateAndPostCode()' ); +end; + +procedure TMainForm.HandleWebMessage( const AMessage: string ); +begin + Memo.Lines.Clear; + Memo.Lines.Add( 'LLVM-Code empfangen. Starte Kompilierung...' ); + Memo.Lines.Add( AMessage ); + Memo.Lines.Add( '--------------------' ); + + TTask.Run( + procedure + var + llFile, objFile, dllFile: string; + compilerOutput: string; + success: Boolean; + begin + llFile := TPath.Combine( TPath.GetTempPath, 'poc.ll' ); + objFile := TPath.ChangeExtension( llFile, '.obj' ); + dllFile := TPath.ChangeExtension( llFile, '.dll' ); + success := False; + + try + TFile.WriteAllText( llFile, AMessage ); + + TThread.Queue( nil, + procedure + begin + Memo.Lines.Add( 'Kompiliere zu Objektdatei...' ); + end ); + compilerOutput := ExecuteProcess( CLANG_PATH, Format( '-c "%s" -o "%s"', [llFile, objFile] ) ); + TThread.Queue( nil, + procedure + begin + Memo.Lines.Add( compilerOutput ); + end ); + + if not TFile.Exists( objFile ) then + begin + TThread.Queue( nil, + procedure + begin + Memo.Lines.Add( 'FEHLER: Kompilierung fehlgeschlagen. .obj-Datei nicht erstellt.' ); + end ); + Exit; + end; + + TThread.Queue( nil, + procedure + begin + Memo.Lines.Add( 'Linke zu DLL...' ); + end ); + compilerOutput := ExecuteProcess( LLD_PATH, Format( '/dll /noentry "%s" /out:"%s"', [objFile, dllFile] ) ); + TThread.Queue( nil, + procedure + begin + Memo.Lines.Add( compilerOutput ); + end ); + + if TFile.Exists( dllFile ) then + begin + success := True; + TThread.Queue( nil, + procedure + begin + Memo.Lines.Add( Format( 'ERFOLG: DLL wurde erstellt: %s', [dllFile] ) ); + end ); + end + else + begin + TThread.Queue( nil, + procedure + begin + Memo.Lines.Add( 'FEHLER: Linken fehlgeschlagen. .dll-Datei nicht erstellt.' ); + end ); + end; + + finally + if TFile.Exists( llFile ) then + TFile.Delete( llFile ); + if TFile.Exists( objFile ) then + TFile.Delete( objFile ); + if not success and TFile.Exists( dllFile ) then + TFile.Delete( dllFile ); + end; + + Memo.Lines.Add( '---------------------------------------------------------' ); + Memo.Lines.Add( 'DLL wird aufgerufen:' ); + + if TFile.Exists( dllFile ) then + begin + var + Runner := TLLVMRunner.Create( dllFile ); + try + Runner.Execute; + finally + Runner.Free; + end; + end; + end ); + + Memo.Lines.Add( 'DLL beendet.' ); +end; + +procedure TMainForm.WebBrowser1DidFinishLoad( ASender: TObject ); +begin + if Assigned( FWebMessageReceiver ) then + Exit; + + if Supports( WebBrowser1, ICoreWebView2, FWebView ) then + begin + FWebMessageReceiver := TWebMessageReceiver.Create( Self ); + FWebView.add_WebMessageReceived( FWebMessageReceiver, FWebMessageReceivedToken ); + end; +end; + +end. diff --git a/Blockly/Readme.txt b/Blockly/Readme.txt new file mode 100644 index 0000000..c73d618 --- /dev/null +++ b/Blockly/Readme.txt @@ -0,0 +1,74 @@ +Technische Dokumentation: Integration von Blockly in eine Delphi FireMonkey Anwendung via WebView2 +Datum: 10. Juni 2025 + +Autor: Gemini & ein sehr fähiger Delphi-Entwickler + +1. Zielsetzung +Ziel dieser Architektur ist die Erstellung einer Hybrid-Anwendung. Eine in Delphi (FireMonkey) entwickelte, native Desktop-Anwendung hostet eine webbasierte, visuelle Programmierumgebung (Blockly). Dies ermöglicht es Endanwendern, komplexe Logik visuell zu erstellen, während die Hauptanwendung die generierten Ergebnisse (z.B. Quellcode in einer Zielsprache) entgegennehmen und weiterverarbeiten kann. + +Diese Architektur ist ideal für die Erstellung von spezialisierten Entwicklungsumgebungen, Konfigurations-Tools oder Lernanwendungen. + +2. Kernkomponenten +Native Host-Anwendung: Eine Delphi FireMonkey (FMX) Anwendung, erstellt in RAD Studio (getestet mit Version 12). Dient als Hauptcontainer und steuert die native UI. +Browser-Komponente: Die FMX TWebBrowser-Komponente. Entscheidend ist die Konfiguration der Engine-Eigenschaft, um auf Windows die moderne Microsoft Edge WebView2-Engine zu nutzen. +Browser-Laufzeitumgebung: Die Microsoft Edge WebView2 Runtime. Diese muss auf dem Zielsystem des Endanwenders installiert sein. +Web-Anwendung (Frontend): Eine lokale, in sich geschlossene HTML-Datei (index.html), die die Blockly-Bibliothek lädt und den visuellen Editor initialisiert. +Benutzerdefinierter Generator: Ein in JavaScript geschriebener, benutzerdefinierter Blockly-Generator (in unserem Fall Blockly.Delphi), der die visuellen Blöcke in eine textbasierte Zielsprache übersetzt. +3. Architektur-Übersicht +Die Delphi-Anwendung fungiert als nativer Container. Beim Start lädt die TWebBrowser-Komponente die lokale index.html-Datei. Diese Datei enthält die gesamte Logik für den Blockly-Editor und den Code-Generator. Die Kommunikation zwischen der Delphi-Anwendung (Host) und der JavaScript-Anwendung (Gast) erfolgt über eine spezielle Schnittstelle, die von der WebView2-Engine bereitgestellt wird. + ++-------------------------------------------------+ +| Delphi FireMonkey Anwendung (MainForm.pas) | +| +---------------------------------------------+ | +| | TWebBrowser (Engine: Edge WebView2) | | +| | +-----------------------------------------+ | | +| | | Lokale index.html geladen | | | +| | | +-----------------+ +---------------+ | | | +| | | | Blockly | | Generator | | | | +| | | | Arbeitsbereich | | (JavaScript) | | | | +| | | +-----------------+ +---------------+ | | | +| | +-----------------------------------------+ | | +| +---------------------------------------------+ | +| ^ | | +| | Delphi -> JS (EvaluateJavaScript) | +| | JS -> Delphi (OnWebMessageReceived) | +| v | | +| +---------------------------------------------+ | +| | Native UI-Elemente (Buttons, TMemo etc.) | | +| +---------------------------------------------+ | ++-------------------------------------------------+ +4. Implementierungsschritte +4.1. Die Web-Anwendung (index.html) +Dies ist das Herzstück des Editors. Die Datei enthält die Blockly-Bibliotheken (von einem CDN oder lokal), den benutzerdefinierten Generator und den Initialisierungscode. + +Wichtige JavaScript-Funktionen in der index.html: + +Blockly.Delphi = new Blockly.Generator(...): Erstellt die Instanz unseres benutzerdefinierten Generators. +Blockly.Delphi.forBlock['block_type'] = function(...): Definiert die Übersetzungsregel für einen spezifischen Block-Typ. +Blockly.Delphi.workspaceToCode(...): Die Hauptfunktion, die den gesamten Arbeitsbereich in die Zielsprache übersetzt. In unserem Fall wurde diese überschrieben, um die Delphi-Unit-Struktur (Header, var-Sektion etc.) zu erzeugen. +window.saveWorkspace() & window.loadWorkspace(): Nutzen Blockly.serialization.workspaces und localStorage, um den Zustand des Editors zu speichern und wiederherzustellen. +window.generateAndPostCode(): Die Schlüsselfunktion für die Kommunikation. Sie generiert den Code und sendet ihn mittels window.chrome.webview.postMessage(code) an die Delphi-Host-Anwendung. +(Der vollständige, funktionierende Code für die index.html ist der aus unserer letzten erfolgreichen Iteration.) + +4.2. Die Delphi Host-Anwendung (FireMonkey) +Die FMX-Form enthält die TWebBrowser-Komponente und die nativen Steuerelemente. + +Wichtige Konfiguration und Code-Teile in der Delphi-Unit: + +Komponenten: Eine TWebBrowser (WebBrowser1), ein TMemo (Memo1) und mehrere TButton. +WebBrowser1.Engine Eigenschaft: Muss im Objektinspektor oder per Code auf EdgeIfAvailable gesetzt werden. +FormCreate: Lädt die lokale index.html-Datei mit WebBrowser1.Navigate('pfad/zur/index.html'). +WebBrowser1DidFinishLoad: In diesem Ereignis wird der Nachrichten-Empfänger (WebMessageReceived) registriert. Dies stellt sicher, dass die Webseite vollständig geladen ist, bevor die Kommunikation eingerichtet wird. Die Registrierung erfolgt über die ICoreWebView2-Schnittstelle. +TWebMessageReceiver-Klasse: Eine Hilfsklasse, die das ICoreWebView2WebMessageReceivedEventHandler-Interface implementiert. Ihre Invoke-Methode wird aufgerufen, wenn eine Nachricht von JavaScript eintrifft. +TThread.Queue: Wichtig innerhalb der Invoke-Methode, um die empfangene Nachricht sicher an den Haupt-GUI-Thread zu übergeben und UI-Komponenten (wie das TMemo) zu aktualisieren. +Button.OnClick-Ereignisse: Rufen WebBrowser1.EvaluateJavaScript('funktionsname()') auf, um JavaScript-Funktionen im WebView auszulösen. +(Der vollständige, funktionierende Code für die Delphi-Unit ist der, den Sie zuletzt bereitgestellt haben.) + +5. Deployment und Abhängigkeiten +Um die Anwendung an einen Endnutzer weiterzugeben, müssen folgende Komponenten verteilt werden: + +Ihre kompilierte .exe-Datei. +Ein Unterordner (z.B. web), der die index.html und alle zugehörigen JavaScript-Dateien enthält (falls sie nicht von einem CDN geladen werden). +Der Installer muss prüfen, ob die Microsoft Edge WebView2 Runtime vorhanden ist, und sie bei Bedarf herunterladen und installieren. Microsoft stellt dafür einen kleinen "Bootstrapper"-Installer bereit. +6. Fazit +Diese Hybrid-Architektur ist extrem leistungsfähig. Sie kombiniert die universelle Einsetzbarkeit und Flexibilität moderner Web-Technologien (HTML/JS/Blockly) für die Benutzeroberfläche des Editors mit der Stärke und Geschwindigkeit einer nativen Delphi-Anwendung für die Programmlogik, Dateiverarbeitung und die Integration in das Betriebssystem. Der TWebBrowser im Edge-Modus ist die entscheidende Brückentechnologie, die diesen Ansatz in FireMonkey modern und zukunftssicher macht. \ No newline at end of file diff --git a/Blockly/blockly_delphi_test.html b/Blockly/blockly_delphi_test.html new file mode 100644 index 0000000..88e49db --- /dev/null +++ b/Blockly/blockly_delphi_test.html @@ -0,0 +1,163 @@ + + + + + Blockly zu Delphi Unit - Final + + + + +

Mein Delphi-Unit-Generator

+

Bauen Sie links Ihre Blöcke. Rechts erscheint die kompilierbare Delphi-Unit.

+ +
+ + + +
+ +
+
+
+

Erzeugter Delphi-Code:

+ +
+
+ + + + + + + + + \ No newline at end of file diff --git a/Blockly/blockly_llvm.html b/Blockly/blockly_llvm.html new file mode 100644 index 0000000..854affb --- /dev/null +++ b/Blockly/blockly_llvm.html @@ -0,0 +1,192 @@ + + + + + Blockly zu LLVM IR - Final + + + + +

LLVM IR (.dll) Generator

+

Bauen Sie links Ihre Logik. Rechts erscheint der LLVM-Code, der zu einer 64-Bit DLL für Windows kompiliert werden kann.

+ +
+ + + +
+ +
+
+
+

Erzeugter LLVM-Code:

+ +
+
+ + + + + + + + +