Menu

maxbox_mainwiki

maXbox MediaWiki has been successfully installed.

Consult the User's Guide for information on using the wiki software.

Getting started with maXbox - Precompiled Object Based Scripting Tool (POBST)




Roadmap for maXbox to 2012/13/14/15/16/17/18/19/20/21/22 (roadmaX)

  • Top Version: Win V4.7.6.10 - V3.9.9.195 - Linux V3.8.2 - Mac V1.2.9.5
  • Screenshots and History
  • GUI and maXbox Form and the new mX3.9 GUI
  • Release available:
  • mX3 available!
  • V3.0.1 January 2011 Service Pack 1
  • V3.2.1 April 2011 Interface, Webservices
  • V3.3.0 Juli 2011: DBX, ADO, Jedi, Grid, Printer, MediaPlayer, SQL, Dataset & Database Support
  • V3.5.0 September 2011: Types, BigInteger, Containers, Conversions, 220 Examples
  • V3.6.1 October 2011: DBClient; DBPlatform; Provider; FMTBcd; DBCGrids; 240 Examples
  • V3.6.2 October 2011: CDSUtil/Borland MIDAS API; VarHlpr/Delphi RTL; ExtDlgs/Delphi VCL;
  • V3.7.1 December 2011: HTTPApp; WideStrUtils RTL; GraphUtil VCL; TypeTrans API, DBWeb
  • V3.8.0 December 2011: Upgrade of mX4 compiler, Unit support, Boot-Loader Scripting
  • V3.8.1 January 2012: Tested mX4 compiler, JclGraphUtils (OpenGL), JclSysInfo, IdUserAccounts more
  • V3.8.4 March 2012: CryptoBox, Crypto Units of LockBox3, JvVCLUtils, Function pdf
  • V3.8.5 April 2012: Serial Interface, Add-ons, more Units, Objects and Functions
  • V3.8.6 Mai 2012: JBL (JediBaseLibrary), Variants, GenetiX Algorithms, Turtle, Threads, Workbench
  • V3.9.1 June 2012: DB Functions, WinAPI, Activity-Diagram, SysTools4 by TurboPower
  • V3.9.2 September 2012: maXcalc, Parallels, SyncObj, Extended FPU, plus Win API
  • V3.9.4 October 2012: COM Port cPort, Arduino Scripts, HTTPServer, Boldutils, LAN Manager
  • V3.9.6.3 November 2012: PCRE RegEx, MemoryLeakReport, ADO SQL
  • V3.9.7.1 December 2012: extRTL, Graphics32, FundamentalsTLS, DMath, Intf Navigator
  • V3.9.7.4 January 2013: SimLogicPac, MIDI, APPInst, more Dialogs, Intf Navigator2, FullTextFinder2
  • V3.9.7.5 February 2013: more 12 Units, forensic functions, add Blix the Programmer
  • V3.9.8.6 April 2013: more Form/Control events, Widget Lib, JvChart, Indy IOHandler, CodeSearch, ExtCtrls2, JvPaintFX
  • V3.9.8.8 Mai 2013: 7 Units, Compress-Decompress Zip, Services Tutorial22, Synopse framework, PFDLib
  • V3.9.8.9 June 2013: SynEdit API, macro, Object Shell, Config Tutorial 25, more Units
  • V3.9.9.1 July 2013: Bookmarks, 12 Units, additional OpenTools API
  • V3.9.9.6 August 2013: REST/XML, Astro & Barcode Package, Addon Units, DevCUnits
  • V3.9.9.7 September 2013: 12 Units, DCOM, MDAC, MIDI, TLS support
  • V3.9.9.16 September 2013: WebServices, SQL Interrogator, Addon Docu more Units and Tutorials
  • V3.9.9.20 October 2013: SQL ADO, Tools Package, Richedit, 25 Units
  • V3.9.9.80 November 2013: more Indy, Form Prototyping, Bold Package, TypeSetKit and Tutorials
  • V3.9.9.81 December 2013: more Indy, Othello, GOL, Geometry OpenGL Demo
  • V3.9.9.82 January 2014: InterBase Package, 31 units, Refactoring

  • V3.9.9.85 January 2014: add 72 units, memcached DB,autobookmark,Alcinoe PAC,IPCLib,GSM Module, CGI

  • V3.9.9.86 February 2014: Orpheus, Alcinoe PAC, AsyncFree Lib, advapi32, Firebird Exp+MySQL units

  • V3.9.9.88 March 2014: 2 Tutorials 30 Units add, VCL constructors, controls+, unit list

  • V3.9.9.91 March 2014: 2 Tutorials 42 Units add, Synapse V40, LDAP, OpenSSL, AVScan

  • V3.9.9.94 April 2014: 1 DLL Report, UML Tutor, 34 Units add, DBCtrls, Stream+, IRadio, Wininet

  • V3.9.9.95 Mai 2014: Oscilloscope V4, Mixer, 7 Units add, URLMon, Form properties+

  • V3.9.9.96 June 2014: SendBuffer,ComboSet,SetPrivilege, WakeOnLAN ParaDice 3D Cube Polygraph, OCR, GPS, 20 Units add

  • V3.9.9.98 September 2014: Add 36 Units, Wav res, RoundTo, OpenOffice, Pipes, GSM2, TFixedCriticalSection, XPlatform beta, GCC Command Pipe, Unittesting, VfW(Video), FindFirst3, ResFiler,AssemblyCache, maXring

  • V3.9.9.101 November 2014: Add 27 Units, 1 Tutor, maXmap, OpenStreetView, MAPX, timers
    Function Menu/View/GEO Map View, DownloadFile, wgetX, sensors, StreamUtils, IDL Syntax, OpenStreetMap, OpenMapX, LPT1, LazDOM, ByteCode2, runByteCode, sensors, CGI-Powtils, IPUtils2, GPS_2
  • V3.9.9.120 December 2014: ByteCode2, STExpressions, Tutors,Units, Stream++, OpenStreetMap, MAPX
  • V3.9.9.160 January 2015: Add 9 Units, 2 Slides 1 Tutor, CLXUp, ExampleEdition, UnitConverter
  • V3.9.9.180 February 2015: Add 6 Units, 1 Tutor, Big Numbers 2, ExecuteMultiProcessor
  • V3.9.9.190 March 2015: Add 18 Units, 1 Tutor, COMUtils, WebServiceUtils
  • V3.9.9.195 May 2015: 36 Units, OLEUtils2, ACM2, CDS, Terminal, XML Transform
  • V4.2.0.10 March 2016: FPC, WideString, REST, Classes & Class Diagram
  • V4.2.2.90 April 2016: Add 15 Units, 1 Tutor, Pipe Libraray2, KLog, FPlot42, KGraphics
  • V4.2.2.98 Mai 2016: Add 21 Units, 1 Tutor, Pipe Libraray2, KLog, FPlot42, Kronos, KMemo
  • V4.2.4.25 June 2016: Add 16 Units, 2 Tutors (43+44), ASN1+, IdNNTPServer, UtilsMax5
  • V4.2.4.80 October 2016: 16 units + 420 functions- WMI Script Type Library - webbox, UtilsMax6
  • V4.2.5.10 Feb 2017: 6 units + 328 funcs HugeInt-HugeWord Library - SimpleTCP
  • V4.2.8.10 Oct 2017: 18 units +560 functions SHA256 -StreamStorage -WMI, XMLDoc, ADO4
  • V4.5.8.10 Dez 2017: 26 units , Indent Guidelines, StreamStore2 -WMI+, XMLDoc+, ADO4+
  • V4.6.2.10 Jan 2018: Tutor 56 Neural Network -Python Checker- 3 more Units PascalCoin
  • V4.7.1.10 Sep 2019:Tutor 57-70, VState Machine, CGI,MachineLearning +20 Units +Tensorflow dll
  • V4.7.1.20 Nov 2019:Tutor 70-72, EKON 23 Fixing, WebSockets, DRBOBCGI, 5+ overbyte Units
  • V4.7.1.82 Dec 2019:Tutor 70-72, EKON23 Fixing, WebSockets/Spider, PHP_CGI,JS, OpenOffice,7+overbyte Units
  • V4.7.4.64 June 2020: EKON24 Fixing, uPSI_SimpleRSS, Json Base Prometheus, neural CAI, Dendron
  • V4.7.5.20 Jan 2021: few Fundamentals 5.00, JCL fixes, GraphMathLibrary, StringBuilder
    V4.7.5.80 July 2021: RSS+, WDCC, P4D_Beta (Python4Delphi), Wininet Threads
    V4.7.5.90 October 2021: FLC Vectors, CAI Neuralnet, SingleListClass
    V4.7.6.10 August 2022: Threadslist, CAI Neuralnet3, P4D+, EKON25 fixing, klib

(V5.0.1 2018: MAC Version, FPC, (64-bit), Android and Arduino Dump, Unicode, Classes / Class Diagram)

Click on the following image to upload a new version of the PNG logo image for your project:


Discussion

  • Max Kleiner

    Max Kleiner - 2014-06-18

    maXbox is a free programming tool with an inbuilt delphi engine in one exe! It is designed for teaching, test and analyze methods and algorithms for Win and Linux (CLX). maXbox is built on RemObjects PascalScript, the smart evolution of programming. Scripting in the box has a main advantage: An open script means you can look at the code, see how it works, change it so it works better for you and run it once again in the box. If it fits your idea give your changes of the script back to the community and reuse as you can.

    by the way: files and shuffle mode is close behind, the best shuffle code is from Don Knuth (elegant and efficient):

     procedure Shuffle(vQ: TStringList);
     var j, k: integer;
         tmp: String;
     begin  
       randomize;
       for j:= vQ.count -1 downto 0 do begin
         k:= Random(j+1);
         tmp:= (vQ[j]);
         vQ[j]:= vQ[k];
         vQ[k]:= tmp;
       end;
     end;
    
    
     procedure bitmapPower;
      var mymap: TBitmap;
      begin
        mymap:= TBitmap.Create;
        mymap:= CaptureScreen1(Rect(150,150,600,600));
        with mymap do begin
          saveToFile(exepath+'screenmap.bmp');
          Free;
        end;           
        writeln('filesize bmp '+intToStr(GetFileSize(exepath+'screenmap.bmp')));
        ConvertImage(exepath+'screenmap.bmp',exepath+'screenmap.png');
        writeln('filesize png '+intToStr(GetFileSize(exepath+'screenmap.png')));
        OpenFile(exepath+'screenmap.png'); 
        //CaptureScreenFormat(exepath+'screenmapdirect','.png');
      end;
    

    Contents

    <script type="text/javascript"> if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } </script>

    Current Development to mX3 V3.1

    Just converted and registered TStringGrid/TDrawGrid (Grid/QGrid) for the proof of Concept Memory Game with a Grid of bitmaps. also TPrinter and TMediaPlayer for more output DBCommon, DBTypes and DBTables in Progress, not all finished but DBX in V3.2 possible, for now in V3.1 for e.g.:


    const SQLQuery = 'select * from customer where company like "%SCUBA%";


    procedure DoQuery(aDB: TDataBase); var i: integer;

       dQuery: TQuery;
    

    begin

      dQuery:= TQuery.create(self); 
      with dQuery do begin
      DatabaseName:= aDB.DataBaseName;
        try
           //openDataBase; or Close;
           //GetQuery(SQLQuery, dQuery)
           SQL.Clear;
           //SQL.Text:= 'select * from customer';
           SQL.Text:= SQLQuery;
           Open;
           Writeln(inttostr(RecordCount)+' Records found: ')
           for i:= 0 to RecordCount - 1 do begin
             Writeln(intToStr(i)+' '+fieldbyname('Company').asString)
             Next;
           end;  
           //ExecSQL;
          finally
            Close;
            Free;
            CloseDataBase(aDB)
          end;
       end   
    

    end;

    A big example of 3 ways (DBX, BDE, ADO-OLEDB (ODBC)) to connect a Firebird/Interbase DB shows script

    http://www.softwareschule.ch/examples/301_SQL_DBfirebird3.htm

    CodeHunter

    Just build the StreamDream in comming soon mX 3.0

    procedure getHTTP_PNG(vimage: TImage); var

     idHTTP: TIDHTTP;
     //mpng: TPNGGraphic;
     pngStream: TMemoryStream;
    

    begin

     myURL:= 'http://www.softwareschule.ch/images/maxboxgui29.png';
     with TLinearBitmap.Create do
     try
       idHTTP:= TIdHTTP.Create(NIL)
       pngStream:= TMemoryStream.create;
       //OptimizeMem
       idHTTP.Get1(myURL, pngStream)
       pngStream.Position:= 0;
       LoadFromStream2(pngstream, 'PNG');
       myimage.Picture:= NIL;
       AssignTo(myimage.Picture.Bitmap);
     finally
       Dispose;
       Free;
       idHTTP.Free
       pngStream.Free;
     end; 
    

    end;

    // my favor to mX3.2 convert an image as easy as that:

    procedure ConvertImage(vsource, vdestination: string); begin

     with TLinearBitmap.Create do
     try
       LoadFromFile(vsource);
       //Assign(Bmp);
       SaveToFile(vdestination);
     finally
       Dispose;
       Free;
     end;
    

    end;


    The same goes for a script loader with a ScriptStream!:

    Procedure GetScriptAndRun; var

     scriptStream: TFileStream;
     idHTTP: TIDHTTP;
     myURL, ascript: string;
    

    begin

     ascript:= '210_public_private_cryptosystem.txt';
     myURL:= 'http://www.softwareschule.ch/download/'+ascript;
     if not FileExists(ExePath+ascript) then begin
       scriptStream:= TFileStream.create(ExePath+'examples/'+ascript, fmCreate)
       idHTTP:= TIdHTTP.create(NIL)
       try
         idHTTP.Get1(myURL, scriptStream)
       finally
         idHTTP.Free
         scriptStream.Free;
         maxform1.color:= clRed;
       end;
     end;      
     Showmessage('Script will be loaded and executed in another box!');
     ExecuteShell(ExePath+'maxbox3.exe','"'+ExePath+'examples\'+ascript+'"');
     //playMP3(ExePath+mp3song);
    

    end;



    function ExtractUrlPath1(const FileName: string): string; var I: Integer; begin

    I:= LastDelimiter('/:', FileName);
    Result:= Copy(FileName, 1, I);
    

    end;

    function ExtractUrlName1(const FileName: string): string; var I: Integer; begin

    I:= LastDelimiter('/:', FileName);
    Result:= Copy(FileName, I + 1, 255);
    

    end;

    writeln(extractUrlPath1('http://www.softwareschule.ch/maxbox.htm')) result: http://www.softwareschule.ch/ writeln(extractUrlName1('http://www.softwareschule.ch/maxbox.htm')) result: maxbox.htm


    Change a Row in a StringGrid

    tmp:= TStringList.Create;
    with sGrid1 do begin
      tmp.Assign(rows[5]);
      rows[5].Assign(rows[6]);
      rows[6].Assign(tmp);
    end;
    tmp.Free;
    

    case CreateMessageDialog('Text the maXbox', mtWarning,[mbYes,mbNo,mbCancel]).ShowModal

             of  mrYes: ShowMessage('Yes');
                 mrNo: ShowMessage('No');
                 mrCancel: ShowMessage('Cancel');
             end;
    

    3 Steps of Clear Code Test:

    Step 1: Exchange

    procedure exchange(var a,b: integer); begin

     a:= a+b;
     b:= a-b;
     a:= a-b;
    

    end;


    Step 2: TimesTable Solution

    Function TimesTable2(row,col: integer; tab: byte):string;

    var i,j: integer; 
    begin
      for i:= 1 to row do
       for j:= 1 to col do begin
         result:= result+ Format('%-*.3d',[tab,i*j])
         if j=col then result:= result+#13#10;
       end;
    end; 
    

    Step 3: Tokenizer

    Procedure strTokenizer(const S: string; Delims:TSysCharSet; Results:TStrings); var i,j: integer; tmp: string; begin

     i:= 1; j:= 1;
     while true do begin
       writeln('this is s2 part '+intToStr(i)); //debug
       while (i <= Length(S)-1) And Not (S[i] in Delims) do
         Inc(i);
       tmp:= trim(Copy(S,j,i-j));
       if tmp <>  then
         Results.Add(tmp);
       if (i <= Length(S)) And (S[i] in Delims) then
         Inc(i); //skip the delimiter
       j:= i;
       if i >= Length(S) then Break;
     end;
    

    end;


    Test Function Overall

    function Average(a,b,c: Extended): Extended;

    begin
      //returns the average of 3 passed numbers
      Result:= Mean([a, b, c]);
    end;
    
    ShowMessageFmt('Average of 2, 13 and 56 = %f',[Average(2,13,56)]);
     Assert(Format('%.2f',[average(2,13,56)])='23.67','must be 23.67');
    


    Education Recursion

     function rectestWord(ac: string; n: byte): bool;
     begin
       if n < length(ac) then
         rectestWord(ac,n+1);
       write(ac[n]);   //rec back
     end;  
    
    function faculty(n: integer): integer;
    begin
     if n < 2 then 
       result:= 1 else
       result:= n * faculty(n-1);
     end;
    


    Palindrome Checker (RegEx and Recursion in One) //***************************************maXbox

    procedure palindromeTest(asc: string; out sout: string; n: byte);
    begin
      if n <= length(asc) then begin
        palindromeTest(asc,sout,n+1);
        sout:= sout+ asc[n];
      end;
    end;  
    
    function PalindromeChecker(asc: string): boolean;
    var tmpstr: string;
    begin
      result:= false;
      asc:= ReplaceRegExpr('[^a-zA-Z]',asc,,true);
      palindromeTest(asc,tmpstr, 1);
      if CompareText(DelSpace(asc),DelSpace(tmpstr))= 0 then
        result:= true;
    end;    
    

    //****************************************


    function PalindromeChecker2(asc: string): boolean;

    begin
      result:= false;
      asc:= ReplaceRegExpr('[^a-zA-Z]',asc,,true);
      if CompareText(asc,ReverseString(asc))=0 then
        result:= true;
    end;    
    


    Josephus Problem and 3 Solutions!

    function josephus(n,k: byte): integer;

      var r,i: integer;
      begin
      r:= 0
      i:= 2
      while i <= n do begin
        r:= (r + k) mod i;
        i:= i+ 1
        write(intToStr(r)+ ' ');  //debug
      end;  
      result:= r+1;
     end;
    


    function josephus2(n,k: byte): integer;
      var r,i: integer;
      begin
      r:= 0 i:= 2
      while i <= n do begin
        r:= (r+k) mod i;
        inc(i)
      end;  
      result:= r+1
     end; 
    
     function josephus_rec(n,k: byte): integer;
      begin
      if n = 1 then
        result:= 1
      else
        result:= (josephus_rec(n-1,k) +k-1) mod n+1
      end;
    


     function josephusProblem_Function(n,k: integer): integer;
     var i,p,kt: smallint;
       aist: array of char;
     begin
      SetArrayLength(aist,n);
      kt:= 2;
      p:= 0;
      for i:= 0 to length(aist)-1 do aist[i]:= '1';//init array
      while kt <= length(aist) do begin    
        for i:= 0 to length(aist)-1 do begin
          if aist[i]= '1' then inc(p);
          if p = k then begin
            aist[i]:= 'X';
            inc(kt);
            p:= 0;
          end;
        end;
      end; 
      for i:= 0 to length(aist)-1 do  //solution out
        if aist[i]= '1' then result:= (i+1);
    end;
    


     procedure josephusProblem_Graphic(n,k: integer);
     var i,p,kt: smallint;
       aist: array of char;
     begin
      SetArrayLength(aist,n);
      kt:= 2;
      p:= 0;
      for i:= 0 to length(aist)-1 do aist[i]:= '1';//init array
      while kt <= length(aist) do begin    
        for i:= 0 to length(aist)-1 do begin
          if aist[i]= '1' then inc(p);
          if p = k then begin
            aist[i]:= 'X';
            inc(kt);
            p:= 0;
          end;
        end;
        for i:= 0 to length(aist)-1 do  //line out
          write(aist[i]+' ');
        writeln();
      end; 
      for i:= 0 to length(aist) -1 do  //solution out
        if aist[i]= '1' then writeln('Survived '+inttoStr(i+1));
    end;
    

    //******************************* CoCreate Object (without constructor)

    {Function CaptureScreen : TBitmap;
     Function CaptureScreen1( Rec : TRect) : TBitmap;}
    
     var mbit: TBitmap; 
    
     mbit:= captureScreen;
     mbit.SaveToFile(exepath+'co_objscreen.bmp');
     searchandOpenDoc(exepath+'co_objscreen.bmp');
     mbit.Free;   
    


    //******************************* StrToWord with StrtoInt (StrtoWord is buggy)

      htimes:= '12';
      Ahour:= strtoInt(htimes);
      DecodeTime(Now, AMin, AMin, ASec, AMSec);
      PrintF(' %0.2d : %0.2d', [AHour, AMin]);
    

    Example of the month:

    Richter Generator to show:

    http://www.softwareschule.ch/examples/069_Richter_MATRIX.TXT


    Input Query and RegEx PathFinder to show:

    http://www.softwareschule.ch/examples/480_regex_pathfinder.txt


    Input Query and RegEx PathFinder to show:

    http://www.softwareschule.ch/examples/480_regex_pathfinder.txt


    Clever Function Copy2SymbDel

     mystr:= 'this is the m@x that rocks';
     writeln('Copy2SymbDel1: '+Copy2SymbDel(mystr, '@'));
     writeln('Copy2SymbDel2: '+mystr);
    
        >Copy2SymbDel1: this is the m
        >Copy2SymbDel2: @x that rocks
    

    Magic Card Trick

    Due to recent advances, it's now possible to sense the vibrations caused by the human voice as the sound impacts the speakers attached to your PC!?!.

    http://www.softwareschule.ch/examples/471_cardmagic2.txt

    or just ALL cards to show:

    http://www.softwareschule.ch/examples/472_allcards.txt


    maXbox to Excel Export (maXcel)

    function SaveAsExcelFile(AGrid: TStringGrid; aSheetName, aFileName: string): Boolean;

    var

     XLApp, Sheet: OLEVariant;
     i, j: Integer;
    

    begin

     // Create Excel-OLE Object
     Result:= False;
     XLApp:= CreateOleObject('Excel.Application');
     try
       // Hide or show Excel
       XLApp.Visible:= true;
       // Add new Workbook
       XLApp.Workbooks.Add(xlWBatWorkSheet);
       Sheet:= XLApp.Workbooks[1].WorkSheets[1];
       Sheet.Name:= aSheetName;
     for i:= 0 to AGrid.ColCount -1 do
       for j:= 0 to AGrid.RowCount -1 do 
          XLApp.Cells[i+2,j+1]:= agrid.cells[i,j]; //direct fill
       try  // Save Worksheet
         XLApp.Workbooks[1].SaveAs(aFileName);
         Result:= True;
       except
         Msg('maxcel export error'); // Error ?
       end;
     finally   // Quit Excel
       if not VarIsEmpty(XLApp) then begin
         XLApp.DisplayAlerts:= False;
         XLApp.Quit;
         XLAPP:= Unassigned;
         Sheet:= Unassigned;
       end;
     end;
    

    end;

    call:

     myst:= TStringGrid.create(self)  //fill with data
    
    if SaveAsExcelFileDirect(myst, 'maxceltestmap',Exepath+'maxceltest3.xls')
                 then msg('maxcel export success');
    
    

    more on script: 318_excel_export.txt



    Multitask enabled Delay

    procedure Delay2(msecs: integer); var

     FirstTickCount: longint;
    

    begin

     FirstTickCount:= GetTickCount;
     repeat
       Application.ProcessMessages; {allowing access to other
                                         controls, widgets, etc.}
     until ((GetTickCount-FirstTickCount) >= Longint(msecs));
    

    end;

    Test it with:

     with TStopWatch.create do begin
       start
         Delay2(500)
       stop
       writeln(getValueStr)
     end;    
    

    procedure DB_XML_AliasConverter; //uses

       //Classes, SysUtils, DB, DBTables, Provider, DBClient;
    

    var

      i: Integer;
      BDEAlias: string;
      abase, abasepath: string;
      aParams, TableNames: TStringList;
      aDataSetProvider: TDataSetProvider;
      CDataSet: TClientDataSet;
      Table: TTable;
    

    begin

     BDEAlias:= 'DBDEMOS';
     TableNames:= TStringList.Create;
     AParams:= TStringList.Create; 
     with TSession.Create(NIL) do try
       //AutoSessionName := True;
       SessionName:= 'MainSession3'; 
       GetAliasParams(BDEAlias, AParams); 
       OpenDatabase(BDEAlias); 
       abasepath:= aParams[0];
       Delete(abasepath,1,7)
       GetTableNames(abasepath,, True, False, TableNames);
     finally
       Close;
       Free;
     end {TSession};
     Table:= TTable.Create(NIL);
     aDataSetProvider:= TDataSetProvider.Create(NIL);
     CDataSet:= TClientDataSet.Create(NIL);
     try
       Table.DatabaseName:=  BDEAlias; //tablenames[2];
       //Table.Params.Assign(AParams); 
       Writeln('base name '+Table.DatabaseName);
       for i:= 0 to Pred(TableNames.Count) do begin
         Table.TableName:= TableNames[i];
         writeln('table to XML '+Table.Tablename)
         Table.Open;
         aDataSetProvider.DataSet:= Table;
         CDataSet.SetProvider(TComponent(aDataSetProvider));
         CDataSet.Open;
         CDataSet.SaveToFile(ExePath+'crypt\'+
                              ChangeFileExt(Table.TableName,'.xml'),dfXMLUTF8);
         CDataSet.Close;
         Table.Close
       end;
       CreateDBGridForm(tableNames);
     finally
       Table.Free;
       CdataSet.Free;
       aDataSetProvider.Free; 
       //ASession.Free;  
       AParams.Free;
       tableNames.Free;
     end;
    

    end;



    Recursive Select Statement

    Select to_char(id)||chr(9)||rtrim(lpad(' ',2*(level-1)) || bez,' ')||

    chr(9)||rtrim(ueberschrift,' ')||chr(9)||rtrim(text,' ') from knoten

    start with id=69 connect by prior id=parent



    SHL EXponent:

    var i: int64;

    for i:= 1 to 32 do
        printF('Bin exponent with SHL: 2^%d = %d',[i, i SHL i DIV i]);
    

    bin exp with SHL: 2^1 = 2 bin exp with SHL: 2^2 = 4 bin exp with SHL: 2^3 = 8 bin exp with SHL: 2^4 = 16 bin exp with SHL: 2^5 = 32.........



    Minesweeper Game, January 2013:

    http://www.softwareschule.ch/examples/285_minesweeper2.htm



    Working with BigIntegers:

    function BigMulu2(aone, atwo: string): string; var bigint, bigint1, bigintres: TXRTLInteger; begin

     XRTLFromString(aone, bigint, 10);
     XRTLFromString(atwo, bigint1, 10);
     XRTLMul(bigint,bigint1,bigintres);
     result:= XRTLToString(bigintres,10,10);
    

    end;

    function BigExp2(aone, atwo: string): string; var bigint, bigint1, bigintres: TXRTLInteger; begin

     XRTLFromString(aone, bigint, 10);
     XRTLFromString(atwo, bigint1, 10);
     XRTLExp(bigint,bigint1,bigintres);
     result:= XRTLToString(bigintres,10,10);
    

    end;

    writeln(BigMulu2('123456789','123456789'));
    maXcalcF('123456789*123456789');
    
    //Environment Info:
    SaveString(ExePath+'\Examples\envinfo.txt',GetEnvironmentString);   
    OpenFile(ExePath+'\Examples\envinfo.txt');
    


    Generate QRCode


    {This is using the Google Charts API, but it does demonstrate a quick and easy way to get QR barcodes in a maXbox, Delphi or Lazarus/FreePascal application.

    Const

      UrlGoogleQrCode='http://chart.apis.google.com/chart?chs=%dx%d&cht=qr&chld=%s&chl=%s';
    

    var

      QrImgCorrStr : array [0..3] of string; // =('L','M','Q','H');
    


    procedure GetQrCode(Width,Height: Word; Correct_Level: string; const Data:string); var

     encodedURL: string;
     idhttp: TIdHttp;// THTTPSend;
     png: TLinearBitmap;//TPNGObject;
     pngStream: TMemoryStream;
    

    begin

     encodedURL:= Format(UrlGoogleQrCode,[Width,Height, Correct_Level, HTTPEncode(Data)]);
     //WinInet_HttpGet(EncodedURL,StreamImage);
     idHTTP:= TIdHTTP.Create(NIL)
     pngStream:= TMemoryStream.create;
     with TLinearBitmap.Create do try
       idHTTP.Get1(EncodedURL, pngStream)
       pngStream.Position:= 0;
       LoadFromStream2(pngStream,'PNG');
       FImage.Picture:= NIL;
       AssignTo(FImage.picture.bitmap);
       SaveToFile(ExePath+'mX3QRCode.png');
       //OpenDoc(ExePath+'mX3QRCode.png');
     finally
       Dispose;
       Free;
       idHTTP.Free
       pngStream.Free;
     end;
    

    end;

    Call to invoke:

     GetQrCode(150,150,'Q', 'this is maXland on the maXbox');
    


    HTTP Download with MemoryStream and Progress:


    procedure GetFileDownloadProgress(myURL, myFile: string); var

     HttpClient: TIdHttp;
     aFileSize: Int64;
     aBuffer: TMemoryStream;
    

    begin

     HttpClient:= TIdHttp.Create(NIL);
     try
       //HttpClient.Head('http://somewhere.ch/somefile.pdf');
       HttpClient.Head(myURL);
       aFileSize := HttpClient.Response.ContentLength;
         Writeln('FileSize of MemStream Download: '+inttoStr(aFileSize));
       aBuffer:= TMemoryStream.Create;
       try
         while aBuffer.Size < aFileSize do begin
           HttpClient.Request.ContentRangeStart:= aBuffer.Size;
           if aBuffer.Size + RECV_BUFFER_SIZE < aFileSize then
             HttpClient.Request.ContentRangeEnd:= aBuffer.Size + RECV_BUFFER_SIZE - 1;
           writeln('file progress: '+inttostr(aBuffer.size));
           Application.ProcessMessages;
           HttpClient.Get1(myURL, aBuffer); // wait until done
           aBuffer.SaveToFile(Exepath+myFile);
         end;
         //HttpClient.OnWorkBegin:= @HttpWorkBegin;
         //HttpClient.OnWork:= @HttpWork;
         //HttpClient.OnWorkEnd:= @HttpWorkEnd;
       finally
         aBuffer.Free;
       end;
     finally
       HttpClient.Free;
     end;
    

    end;


    Third Law of Kepler to find the height of a Geostationary Satellite

    (1/27.5)^2 = (x/384000)^3 ca. 42000 km - 6300 ~ 36000 km

    the idea ist to get the moon as relation to the daly track around the earth 1/27 per day

    and the solve it with maXbox:

       maxCalcF('((1/27.32)^2)^(1/3)*384E3-6371');
       >>>35961.8421987704
    

    The Moon has an orbit radius of 3.8x108 m and a period of 27.3 days. Use this information to calculate the radius (RS) of the orbit of a geostationary satellite.

    Smart/Small Manual for maXbox

    25 User Tips for mX3 3.9.9


    - Install: just save your maxboxdef.ini before and then extract the zip file!

    - Toolbar: Click on the red maXbox Sign (right on top) opens your work directory or jump to <Help>

    - Menu: With <F2> you check syntax with <F8> you debug and <F9> you compile!

    - Menu: With <Crtl><F3> you can search for code on examples

    - Menu: Open in menu Output a new instance <F4> of the box to compare or prepare your scripts

    - Menu: Set Interface Naviagator in menu /View/Intf Navigator

    - Menu: Switch or toogle between the last 2 scripts in menu File/LoadLast (History is set to 9 files)

    - Inifile: Set memory report in ini: MEMORYREPORT=Y :report on memory leaks on shutdown by dialog

    - Context Menu: You can printout your scripts as a pdf-file or html-export

    - Context: You do have a context menu with the right mouse click

    - Menu: With the UseCase Editor you can convert graphic formats too.

    - Menu: On menu Options you find Addons as compiled scripts

    - IDE: You don't need a mouse to handle maXbox, use shortcuts

    - Menu: Check Options/ProcessMessages! if something is wrong or you can't see graphics in a time

    - IDE: Drag n' drop your scripts in the box or the model in use case editor (Cut,Copy,Paste always available)

    - Editor: You can get templates as code completion with <ctrl j> in editor like classp or iinterface or ttimer (you type classp and then CTRL J),or you type tstringlist and <Ctrl><J>

    - Menu: In menu output (console) you can set output menu in edit mode by unchecking <read only output>

    - Editor: After the end. you can write or copy notes or descriptions concerning the app or code

    - Code: If you code a loop till key-pressed use function: isKeyPressed;

    - Code: Macro set the macros #name, #date, #host, #path, #file, #head #sign, see Tutorial maxbox_starter25.pdf

    - Editor: - Dbl Click on Word in Editor search amount of words with highlighting, Dbl Click on Bookmarks to delete and Click and mark to drag a bookmark

    - Menu: To start handling from CD-ROM (read only mode) uncheck in Menu /Options/Save before Compile

    - IDE: A file info with system and script information you find in menu Program/Information

    - IDE: Make a screenshot of the content and environment in menu Output/Save Screenshot

    - IDE: Use a boot loader script 'maxbootscript.txt' (as auto start) to change the box each time you start it.

    - IDE: With escape or <Ctrl> Q you can also leave the box or stop a script in menu program - stop program

    Current Development to mX4 V4.0

    Switch between Pascal and C = PasCal

      float convertToF(float temperatureC)
       {
        return (temperatureC * 9.0 / 5.0) + 32.0;
       }
    
      function convertToF(temperatureC: float): float;
      begin
        result:= (temperatureC * 9.0/5.0) + 32.0;
      end;
    

    In the version 3.8 we upgrade from mX3 (delphi2007) to mX4 compiler (delphi2009) A Unit support, Boot-Loader Scripting and Version Check routine is already workable The idea of a BOOTSCRIPT is before start the maXbox you can alter, init or change functions or features of the OpenTools API in maXbox, so the bootscript is named maxbootscript.txt and all those routines will be executed by starting the box. For example you change the buttons or color options of the editor or you set some monitor or processing functions valid for all scripts to be executed.

    With mX4 we do have full decompile or debug possibility of the scripts, mX3 < 3.6 had some trouble with event handler in it.

    Type Conversion like floatToString are with implicit or explicit type casts, so an error is shown but the script runs anyway. The full variant support depends on a compiler directive in pascalscript.inc

    With the CPort as a Serial Component we now have support for Arduino, see Tutorial 18 The new Package/Component Model Viewer is included, see menu /Debug/Units Explorer

    RegEX PCRE Lib integration finished in 3.9.6:

    //I have the following REGEX: //^(\[[A-Za-z0-9,]+\])?([A-Za-z0-9]+:)?([A-Za-z]+)\(?([^\)]*)\)?$ (*When presented with Set(ID,99) Perl returns: 1:[], 2:[], 3:[Set], 4:[ID,99] - as I expected

    Delphi's Reg ex returns:

    Group 1:[] Group 2:[] Group 3:[Set] Group 4:[ID,99]

    procedure DelphiCoreCodeRegEx; var

     regEx: TPerlRegEx;
     i: integer;
    

    begin

     try
       { TODO -oUser -cConsole Main : Insert code here }
       regEx:= TPerlRegEx.Create;
       try
         regEx.RegEx := '^(\[[A-Za-z0-9,]+\])?([A-Za-z0-9]+:)?([A-Za-z]+)\(?([^\)]*)\)?$';
         regEx.Subject := 'Set(ID,99)';
         WriteLn('Regex: '+regEx.RegEx);
         WriteLn('Subject:'+regEx.Subject);
         WriteLn();
         if regEx.Match then begin
             for i:= 1 to 4 do
               WriteLn(Format('Group %d:[%s]',[i,regEx.Groups[i]]));
           end
         else
           WriteLn('Subject did not match the regular expression');
         ReadLn();
       finally
         regEx.Free;
       end;
     except
       //on E: Exception do
         Writeln('E.ClassName'+ ': '+ E.Message);
     end;
    end;
    

    Profiler and QueryByExample (QBE) is done by Jedi and implemented in maXbox:

    QBEQuery1:= TJvQBEQuery.create(self);
       with QBEQuery1 do begin
         //parent
         DatabaseName:= 'DBDEMOS'
         with QBE do begin
           add('Query')
           add();
           add('SORT: EMPLOYEE.DB->"LastName", EMPLOYEE.DB->"FirstName"');
           add();
           add('EMPLOYEE.DB | EmpNo  | LastName | FirstName | PhoneExt |');
           add('            | Check  | Check    | Check     | Check    |');
           add();
           add('EndQuery');
         end;
         Active:= True;
         for i:= 0 to Recordcount - 1 do begin
           for z:= 0 to Fieldcount - 1 do 
             Write((Fields[z].asString)+'  ');
           Writeln(#13#10)
           Next;
         end;
       //StmtHandle
       //StartParam:= '<>'; //Params:= '<>';
       //ParamData:= <>
       Close;
       Free;
     end;
    
    

    http://www.softwareschule.ch/examples/332_jprofiler_form2.txt http://www.softwareschule.ch/examples/332_jprofiler_form2.htm http://www.softwareschule.ch/examples/333_querybyexample.txt

    Another Cool Feature is the TCustomImageList:

    //////////////////// digi clock rock procedure DigiTForm1_FormActivate(Sender: TObject); //Startinit on Form var i,t: integer; begin

     pb[1]:=pb1; pb[2]:=pb2; pb[3]:=pb3;
     pb[4]:=pb4; pb[5]:=pb5; pb[6]:=pb6;
     for i:= 1 to 6 do zeit[i]:= 0;
     imgL:= TCustomImageList.Create(self);
     ReadComponentResFile(ExePath+picpath+'MyImageClockList7Segment.dat', imgl);
     with imgL do begin
       //@Bitmap.DrawMode:= dmBlend  //assign; setbounds
        Height:= 50;
        Width:= 30;
       {for t:= 0 to 9 do //image, mask
          Add(getbmp(exePath+picpath+'7seg'+inttostr(t)+'.bmp'),
                       getbmp(exePath+picpath+'7segaus.bmp'));} 
     end;
     WriteComponentResFile(ExePath+picpath+'MyImageClockList7Segment.dat', imgL);
    

    end;


    procedure DigiTForm1_TimerTimer(Sender: TObject); var i: integer;

       s,s1: String;
       t: TDateTime;
    

    begin

     t:= Now;
     //Formate, 6-parts of s
     DateTimeToString(s,'hhmmss',t);
     //Number assign and draw
     for i:= 1 to 6 do begin
       s1:= MidStr(s,i,1);
       zeit[i]:= strToInt(s1);
       imgL.Draw(pb[i].Canvas,1,1,zeit[i],true);
     end;
    

    end;

    http://www.softwareschule.ch/examples/336_digiclock2.htm http://www.softwareschule.ch/examples/336_digiclock2.txt

    For a 64 version a way to query the env. is:

    bstr:= ifThen(IsWow64, 'maxbox3_64.exe','maxbox3.exe');
     if Winexec32(Format(ExePath+'%s',[bstr]),SW_Show) then 
          writeln('EXE '+bstr+' is running');
    


    JVChart, CodeSearchEngine and BigInteger has been finished

    Exception Handling with decompile address out: for example you set a function with false type:

    function HexToStr(Value: string): string;

    and then you mistaken the para type integer instead of string, but it will compile, the registration is a literal in addfunction:

    Sender.AddFunction(@HexToStr, 'function HexToStr(Value: integer): string;');

    but at runtime you get

    Exception: Access violation at address 004069A0 in module 'maxbox3_9.exe'. Read of address 00000F98 at 0.3461

    So you can find the error at 0.3461 with the decompiler:

    [3450] PUSHVAR Base[1] // 3
    [3456] CALL 165
    [3461] POP // 2
    [3462] POP // 1
    

    then you go to CALL 165 and you see the miserable function: Proc [165]: External Decl: \01\00 HEXTOSTR


    Design Mind Mapping of the 4.0 IDE >> To help prioritize and design them, I'd like to better understand the >> various requests for editor improvements (e.g. auto-complete, better >> syntax highlighting). What are the user experience problems you're >> trying to solve? For who? (Please be more specific than "making >> maXbox more like other IDEs". If that's the goal, I think we're >> better off making it easier to let you use those other IDEs.) >> >> Anything that requires heuristic parsing of incomplete / invalid code >> (e.g. because you're in the middle of typing it) is probably beyond >> the scope of what we can reasonably do (unless there's a great >> library or example to draw on). That is, I don't think we're going >> to be able to do things like dynamically parse the user sketch as >> it's being typed, extract the names of functions defined in the >> sketch, and provide dynamic syntax highlighting / command completion >> for calls to those functions elsewhere in the sketch. On the other >> hand, looking for a known string like PrintF() to appear in >> your script and dropping down a list of arguments doesn't seem so unrealistic. >> >> The overall point is that, for each feature request, we're trying to >> balance the degree to which we can improve the user experience with >> the feasibility / difficulty of implementation. Keep that in mind as >> we discuss improvements to the IDE.

    Just a glance for an app:

    • [File:MX_screenshotwin8.png Preview]

    MemoryStream overloading

    As no direct overloading is possible, we do it by name conventions:

    For example a write to buffer with an dynamic array of byte is WriteBufferABD:

    procedure CreateEmptyZipFile; var i: integer;

     zipfile: wideString;
     //ezip: TByteArray; =(80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
     ezip: TByteDynArray;
     ms: TMemoryStream;
    

    begin

     SetLength(ezip, 25);   //for ZIP Header
       ezip[0]:=80; ezip[1]:=75; ezip[2]:=5; ezip[3]:=6; 
       for i:= 4 to 23 do ezip[i]:= 0; 
    
     zipfile:= exepath+'examples\'+AZIPFILE;
     // create a new empty ZIP file
     ms:= TMemoryStream.Create;
     writeln(ObjectToStr(ms));  //debug pointer
     try
       //ms.WriteBuffer array of byte of dynamic size;
       ms.WriteBufferABD(ezip, length(ezip));
       ms.SaveToFile(Zipfile);
     finally
       ms.Free;
     end;
    

    end;

    Tower of Hanoi Decoded

    PROGRAM Tower_of_Hanoi_Steps_SolutionSequence; //Uses Crt; {

    **************************************************************************
    solution of the tower of hanoi with a codelist, double recursion!,
    codelist with 12 patterns of 4 steps, codesequence in 24 solution steps!
     loc's= 134, ex. _80ff
    try to program it with a canvas object to visualize
    ************************************************************************** }
    

    //uses crt;

    Const SOLUTIONFILE = 'hanoilist.txt';

    Type

       TPatterns=  array[1..12] of shortstring;
    

    var answer: string;

       steps, step4, i: integer;
       patt: shortstring;
       varray: TPatterns;
       pattlst, seqlist: TStringlist;
    
    

    //The 12 Main Step Patterns!

    procedure initPatternArray; //codelist begin

     varray[1]:=   'a to b a to c b to c a to b ';
     varray[2]:=   'a to b a to c b to c b to a ';
     varray[3]:=   'a to c a to b c to b a to c ';
     varray[4]:=   'a to c a to b c to b c to a ';
     varray[5]:=   'b to a b to c a to c b to a ';
     varray[6]:=   'b to a b to c a to c a to b ';
     varray[7]:=   'b to c b to a c to a b to c ';
     varray[8]:=   'b to c b to a c to a c to b ';
     varray[9]:=   'c to a c to b a to b c to a ';
     varray[10]:=  'c to a c to b a to b a to c ';
     varray[11]:=  'c to b c to a b to a c to b ';
     varray[12]:=  'c to b c to a b to a b to c ';
    

    end;


    procedure Search_Write_Codes; var vs, tmp: shortstring;

      i,k, found: integer;
    

    begin

     found:= 0;
     writeln('pattern codes ---------- for solution: '+answer);
     for i:= 0 to pattlst.count - 1 do begin
       vs:= pattlst.strings[i]
       for k:= 1 to high(varray) do
         if vs = varray[k] then begin
           //writeln('patt code: '+inttostr(k));
           inc(found)
           tmp:= tmp +(inttostr(k)+'-')
           //write(inttostr(k)+'-');               //-fast
           //if found mod 32 = 0 then writeln(); //-fast
         if found mod 24 = 0 then begin 
           seqlist.add(tmp);
           tmp:= ;
         end; 
       end;    
     end;
     seqlist.add(tmp) //last/first segment
     writeln('Nr of codes: ' +inttostr(found))
    

    end;


    procedure move(high: integer; a,c,b: char); begin

     if high > 1 then begin
       move(high-1,a,b,c);
       //writeln(a+' to '+c);   //-fast
       inc(step4)
       patt:= patt+a+' to '+c+' ';
       if step4 mod 4 = 0 then begin
         pattlst.add(patt)
         patt:= ;
       end;   
       move(high-1,b,c,a);
       inc(steps)
     end else begin
       //writeln(a+' to '+c)   //-fast
       inc(step4)
       patt:= patt+a +' to '+c+' ';
       if step4 mod 4 = 0 then begin
         pattlst.add(patt)
         patt:= ;
       end;   
       inc(steps)
     end; 
     //writeln(' very last test') 
    

    end;

    begin //main

     steps:= 0;
     step4:= 0;
     initPatternArray;
     pattlst:= TStringlist.create;
     seqlist:= TStringlist.create;
     answer:= readln('How much on a pile ?');
     Writeln('Pile solution of: '+(answer))
     move(strtoInt(answer),'a','b','c');
     Writeln('had total '+inttoStr(steps)+ ' steps');
     for i:= 0 to pattlst.count - 1 do      //-fast
       writeln(pattlst.strings[i]);
     Search_Write_Codes; 
     writeln('Nr of codelines: '+inttostr(seqlist.count)+ ' in file '+SOLUTIONFILE)
     seqlist.savetoFile(exepath+'examples\'+SOLUTIONFILE)
     seqlist.Free; 
     pattlst.Free;
    
     {Writeln('or '+chr(bintoint(inttobin(ord('A') OR ord('B')))))
     Writeln('xor '+chr(ord('A') XOR ord('B')))
     Writeln('and '+chr(ord('A') AND ord('B')))
     Writeln('not and'+chr((NOT ord('A') AND ord('B'))))}
    

    End.



    The 12 Main Step Patterns! --1-------2-------3-------4------- A 1,2,3,4 a to b a to b a to c a to c a to c a to c a to b a to b b to c b to c c to b c to b a to b b to a a to c c to a --5-------6--------7-------8------ B 5,6,7,8 b to a b to a b to c b to c b to c b to c b to a b to a a to c a to c c to a c to a b to a a to b b to c c to b --9-------10-------11------12----- C 9,10,11,12 c to a c to a c to b c to b c to b c to b c to a c to a a to b a to b b to a b to a c to a a to c c to b b to c




    //***************************************************************

    This is the solution code sequence for all even piles! repeat n/24:

    3-6-11-3-5-12-3-(5/6)-11-4-5-11-3-6-11-(3/4)-5-12-3-5-11-4-5-(11/12)

    This is the solution code sequence for all odd piles!:

    1-10-7-1-9-8-1-(9/10)-7-2-9-7-1-10-7-(1/2)-9-8-1-9-7-2-9-(7/8)

    //***************************************************************

    www.softwareschule.ch/examples/080_pas_hanoi2_file.txt

    Closures, RegEx and Threads

    And the story goes on: A Function containing at least one free variable is called an Open Term. In order to get to a fully functional Function, all free variables have to be bound (turning that open term into a closed term). For this to be done, the compiler reaches out to the so called lexical environment, in which that Function was defined and tries to find a binding. This process is called closing over which results in a closed expression or – for short – a Closure.

    Before I get into closures, I want to address the constant use of the word as a misnomer. The term Closures is very frequently treated as a synonym for the term anonymous methods. Though closures are specific to anonymous methods, they are not the same concept. Anonymous methods are possible without closures. Do not use the terms interchangeably.

     function belowFirst(const xs: array of Integer): array of Integer;
     var i: Integer;
     begin
       for i:= 1 to high(xs) do
         if xs[i] < xs[0] then 
           result[i]:= xs[i]
     end;
    
     main: setlength(mba,10)
     mba:= belowFirst([5,1,7,4,9,11,3]);     //Open Array Constructor
     for i:= 1 to 9 do write(intToStr(mba[i]));
    
    

    the same in Scala: 01 val belowFirst = ( xs : List[Int] ) => { 02 03 val first = xs( 0 ) 05 val isBelow = ( y : Int ) => y < first 07 for( x <- xs; if( isBelow( x ) ) yield x 08 } 10 ... 11 belowFirst( List( 5, 1, 7, 4, 9, 11, 3 ) ) // => List( 1, 4, 3 )


    //Avoid globals and various lines with a strategy pattern:


    function loadPForm(vx, vy: integer): TForm; var psize: integer;

       ppform: TForm;
    

    begin

     psize:= vx*vy
     //constructor
     ppform:= TForm.Create(self);
     with ppform do begin
       caption:= 'LEDBOX, click to edit, dblclick write out pattern'+
                    ' Press <Return> to run the Sentence';  
       width:= (vx*psize)+ 10 + 300;
       height:= (vy*psize)+ 30;
       BorderStyle:= bsDialog;
       Position:= poScreenCenter;
       //onKeyPress:= @FormKeyPress
       //OnClick:= @Label1Click;
       //OnClose:= @closeForm;
       Show;
     end;
     result:= ppform;  
    

    end;

    procedure LetBitmaponForm(aform: TForm); var mbitmap: TBitMap; begin

     mbitmap:= TBitmap.Create;
     try
       mbitmap.LoadFromFile(Exepath+BITMAP);
       aform.Canvas.Draw(370,170, mbitmap);
     finally
       //aForm.Free;
       mbitmap.Free;
     end;
    

    end;


    Call: LetBitmaponForm(loadPForm(8,8));


    Closure Pattern with procedure type:

    type TProc = procedure(VAR x: single);

        TProc2 = procedure();
        TPredicate = function(const x: integer): bool; 
    
    procedure ShowHourGlass(aProc: TProc2);
    var OldCursor: TCursor; 
    begin 
     OldCursor := Screen.Cursor; 
     Screen.Cursor := crHourGlass; 
     try 
      //aProc(x); 
       aProc(); 
       showmessage('^fct2 after');
     finally 
      Screen.Cursor := OldCursor 
     end; 
    end;
    
    PROCEDURE fct2; //as closure
     var i: integer;
     BEGIN  
       for i:= 1 to 99996666 do 
         Sin(i);
       sleep(4000)
       showmessage('^fct2 in');
     END;
    

    Call:

      ShowHourGlass(@fct2);
    

    RegEx in maxbox has some components one is the RegExp Studio it goes like this:

     email:= 'max@kleiner.com';
     rex:= '[\w\d\-\.]+@[\w\d\-]+(\.[\w\d\-]+)+';
    
     writeln('email is: '+booleanToString(ExecRegExpr(rex, email)))
    


    How do I get the last term in URL between slashes ie 'last' using regex?

     myURL = 'http://www.kleiner.ch/kleiner/download/G9_japan.mp3';
    
     mp3song1:= ReplaceRegExpr('([^/]+)/?$',myurl,',true); //show all except last
     -->http://www.kleiner.ch/kleiner/download/
    
     mp3song1:= ReplaceRegExpr('([^/]+)?/',myurl,',true); //show only last extract
     -->G9_japan.mp3
    
     writeln('regex extract test: '+mp3song1)
    
    Test also with:
    mp3song1:= ExtractWord(5,myurl,['/']);
    

    Pascal Parser Regex

    function ParseReturnType(const AText: string): string;

     Parser.Pattern := '((\w+)\.)*\w+';
    

    function ParseDefaultValue(const AText: string): string;

     Parser.Pattern := '\s*\=\s*(.*|\w+|(\+|\-)?\d+\.\d+)';
    

    function ParseTypeName(const AText: string): string;

     Parser.Pattern := '(?:\s*\:\s*)&?(((\w+)\.)*(\w+))';
    

    procedure ParseParamNames(Routine: TRoutineDeclaration; const AText: string);

     Parser.Pattern := '&?(((\w+)\.)*\w+)(?:\s*,|:)';
    

    function ParseSingleDeclaration(Routine: TRoutineDeclaration; const AText: string): TParamType;

     Parser.Pattern := '((const|var|out)?(?:\s)*&?(\w+)(\s*,\s*\w+)*(?:\s*\:\s*)&?((\w+)\.)*(\w+)(\s*\=\s*(.*|\w+|\d+))?)';
    

    function ParseTypeDeclaration(Routine: TRoutineDeclaration; const AText: string): TParamType;

     Parser.Pattern := '([^;]*)(\;)?';
    

    API Code

    Window Themes and Color

    To set a color in a Panel or to override themes two ways are possible: - controlstyle set - parentbackground

     with mypanel do begin
        caption:= '********maXboxMP3********';  
        controlstyle:= controlstyle - [csParentBackground,csOpaque];
    
     mypanel:= TPanel.Create(self)
        with mypanel do begin
        ParentBackground:= false;
        color:= clyellow;
    

    Error Handling

     Forget the FormatMessage() take the sysErrorMessage!
     Convert the OS Error Code into a User Friendly Message
     trying to remove a non existing folder or RemoveDir deletes an existing empty directory. 
    
     RemoveDir('k:\NoSuchFolder') ;
     ShowMessage('System Error Message: '+ SysErrorMessage(GetLastError)) ;
     >System Error Message: The system cannot find the file specified
    

    Service, App or Session?

     function isService: boolean;
     begin
       result:= NOT(Application is TApplication);
       {result:= Application is TServiceApplication;}
     end;  
    
     function isApplication: boolean;
     begin
       result:= Application is TApplication;
     end;  
    
     //SM_REMOTESESSION = $1000
     function isTerminalSession: boolean;
     begin
       result:= GetSystemMetrics(SM_REMOTESESSION) > 0;
     end;  
    


    function GetShortPathName(lname, sname: pchar; mpath: longint): bool;

     external 'GetShortPathNameW@kernel32.dll stdcall';
    

    //undocumented !

    function MessageBoxTimeOut(hWnd: HWND; lpText: PChar; lpCaption: PChar; uType: UINT;

    wLanguageId: WORD; dwMilliseconds: DWORD): Integer; external 'MessageBoxTimeoutA@user32.dll stdcall';
    
     iFlags:= $0 or $00010000 or $00000040;
        iResult:= MessageBoxTimeout(Application.Handle,
            'Test a timeout of 2 seconds.','MessageBoxTimeout Test',iFlags,0,2000);
    


    BitBlt: Own Mouse Moving Pic Cursor

    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer); //var FOldRect: TRect; //makes a blur and zoom effect begin

     //firsttime:= true;   //move tester
     { 1) Restore Form1: copy storage onto Form1 at its old location }
     //FOldRect:= Rect(280, 200, X , Y);
     if FirstTime then FirstTime:= False
       else BitBlt(bfrm.Canvas.Handle, FOldRect.Left, FOldRect.Top,
        FPic.Width,FPic.Height, FStorage.Canvas.Handle,0,0,SRCCOPY);
     { save old location }
     FNewRect:= Rect(X, Y, X + FPic.Width, Y + FPic.Height);
     FOldRect:= FNewRect;
     { 2) Save copy: copy rectangle from Form1 to storage at new location.}
     BitBlt(FStorage.Canvas.Handle,0,0, FPic.Width, FPic.Height,
            bfrm.Canvas.Handle, FNewRect.Left, FNewRect.Top,  SRCCOPY);
     { 3) copy the image to Form1 using SRCINVERT }
     BitBlt(bfrm.Canvas.Handle, FNewRect.Left, FNewRect.Top, FPic.Width, FPic.Height,
            FPic.Canvas.Handle,0,0, SRCAND);
    

    end;

    function NumProcessThreads2: integer; var

     hsnapshot: THandle;
     Te32: TTHREADENTRY32;
     proch: dWord;
    

    begin

     Result:= 0;
     proch:= GetCurrentProcessID;
     hSnapShot:= CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    
     Te32.dwSize:= sizeof(Te32);
     if Thread32First(hSnapShot, Te32) then begin
       if Te32.th32OwnerProcessID = proch then
         inc(Result);
       while Thread32Next(hSnapShot, Te32) do begin
         if Te32.th32OwnerProcessID = proch then
           inc(Result);
       end;
     end;
     CloseHandle(hSnapShot);
     writeln('WinDir '+getwindir);
     writeln('SysDir '+getsysdir);
     //getsystempath
    

    end;

    For example, the thread queues are more than lists of messages--they also maintain some state information. Some messages (like WM_PAINT) aren't really queued, but synthesized from the additional state information when you query the queue and it's empty. Messages sent to windows owned by other threads are actually posted to the receiver's queue rather than being processed directly, but the system makes it appear like a regular blocking send from the caller's point of view; this can cause deadlock (because of circular sends back to the original thread).


    function FileTimeGMT2 (FileName: STRING): TDateTime;

            // Returns the Date and Time of the last modification of the given File
            // The Result is zero if the file could not be found
            // The Result is given in UTC (GMT) time zone
    

    VAR

     Handle         : THandle;
     FindData       : TWin32FindData;
     SystemFileTime : TSystemTime;
     mf: TFileTime;
    

    begin

     Result := 0.0;
     Handle := FindFirstFile (PChar (FileName), FindData);
     IF Handle <> INVALID_HANDLE_VALUE THEN BEGIN
       WFindClose (Handle);
       IF (FindData.dwFileAttributes AND FILE_ATTRIBUTE_DIRECTORY) = 0 THEN
         // FileTimeToSystemTime(FindData.ftLastWriteTime, SystemFileTime); 
         IF FileTimeToSystemTime(FindData.ftLastWriteTime, SystemFileTime) THEN BEGIN
           with SystemFileTime do begin
             if messagebeep(4) then 
               Result:= EncodeDate (wYear, wMonth, wDay) +
             EncodeTime (wHour, wMinute, wSecond, wMilliseconds);
           end;
         END;
       END;
    

    END;


    procedure OpenIEURL(aURL:string); var sz: string; begin

     Application.ProcessMessages;
     aURL:= trim(aURL);
     if aURL= then Exit;
     with TRegistry.Create do try
        rootkey:= HKey_Classes_Root;
        OpenKey('\htmlfile\shell\open\command',false);
        try 
          sz:= ReadString();
          writeln('test of IE readkey '+sz) 
        except
          sz:= ; 
        end;
        CloseKey;
     finally
         Free;
     end;
     if sz= then Exit;
     sz:= copy(sz, pos('"',sz)+1, length(sz));
     sz:= copy(sz, 1, pos('"',sz)-1);
     if pos('http://',aURL)<>1 then aURL:='http://'+aURL;
     //ShellExecute(0,'open',PChar(z), PChar(aURL), nil, sw_ShowNormal); 
     //ShellExecute(0,'open', PChar(aURL), nil, nil, sw_Show);
    

    end;


    Procedure HideWindowForSecondsT(secs: integer);

    Var T : tdateTime; begin

     ShowWindow(Self.Handle, SW_Hide);
     ShowWindow(Application.Handle, SW_Hide);
     T:= Time;
     Repeat
       Application.ProcessMessages;
     Until Time - T > secs / 24 / 3600;
     ShowWindow(Self.Handle, SW_Show);
     ShowWindow(Application.Handle, SW_Show);
    

    end;


    //if IsTCPPortOpen(8080,getIP('127.0.0.1')) then
      if IsTCPPortOpen(9000,getIP(getHostName)) then
          writeln('Port Open Started') else 
          writeln('Port not open');
    

    DataBase Init

    procedure newDBTableScript; begin

     with TTable.Create(self) do begin
       Active:= false;
       databasename:= 'DBDEMOS';
       //databasename:= 'knabe';
       tablename:= 'maxtable3';
       tabletype:= ttparadox;
       with fielddefs do begin
         Clear;
         add('field1',ftinteger,0,false)
         add('field2',ftinteger,0,false)
         add('field3',ftfloat,0,false)
       end;
       CreateTable; 
       active:= true;
       Insert;
        FieldbyName('field1').value:= 44;
        FieldbyName('field2').value:= 55;
        FieldbyName('field3').value:= 3.1415;
       Post;
       Close;  
     end;
    

    end;

    Create a Table with Index procedure CreateATable(DBName, TblName : String); //Path Alias & Table Name to Create var tbl: TTable; begin

     tbl:= TTable.Create(self);
     with tbl do begin
       Active:= False;
       DatabaseName:= DBName;
       TableName:= TblName;
       TableType:= ttParadox;
       with FieldDefs do begin
         Clear;
         Add('LastName', ftString, 30, False);
         Add('FirstName', ftString, 30, False);
         Add('Address1', ftString, 40, False);
         Add('Address2', ftString, 40, False);
         Add('City', ftString, 30, False);
         Add('ST', ftString, 2, False);
         Add('Zip', ftString, 10, False);
         Add('ZipCode', ftInteger, 0, False);
       end;
       {Add a Primary Key to the table}
       with IndexDefs do begin
         Clear;
         Add('Field1Index2', 'LastName;FirstName', [ixPrimary,IxUnique]);
       end;
       CreateTable; {Make the table}
     end;
    

    end;

    procedure addRecord(DBName, TblName : String); begin

     with TTable.Create(self) do begin
       Active:= false;
       databasename:= DBName;
       tablename:= TblName;
       active:= true;
       Insert;
         FieldbyName('LastName').value:= getRandomString(28);
         FieldbyName('FirstName').value:= getRandomString(15);
         FieldbyName('Address1').value:= getRandomString(39);
         FieldbyName('Address2').value:= 'milkywaymax 42';
         FieldbyName('City').value:= 'Randomia';
         FieldbyName('ST').value:= '19';
         FieldbyName('Zip').asString:= getrandomString(9);
         FieldbyName('ZipCode').asInteger:= random(1000);
       Post;
       Close;  
     end;
    

    end;

    Firebird 2.5.2

    Released November 06, 2012. Updated March 24, 2013. Works well with 301_SQL_DBfirebird4.txt

    CONNECTSTRING = 'Provider=MSDASQL;DSN=mxfirebird;Uid=sysdba;Pwd=masterkey'; $Provider=MSDASQL.1;Persist Security Info=False;Data Source=mxfirebird

    * Purpose  : Demonstrates 3 ways Queries in Datasets (DBX, BDE, ADO(ODBC)) on 64bit!
    * History  : TSQLConnection, TSQLDataSet, TSQLQuery
    

    http://www.softwareschule.ch/examples/301_SQL_DBfirebird5.txt

     procedure ConnectFireBird(const aDBname: string);
      var
        connect: TSQLConnection;
        DataSet: TSQLDataSet;
        dataQuery: TSQLQuery;
     begin
     connect:= TSQLConnection.Create(NIL);
     try
       with connect do begin
         ConnectionName:= 'VCLScanner';
         DriverName:= 'Firebird';//'INTERBASE';   //or Firebird
         LibraryName:= 'dbxint30.dll';
         VendorLib:= 'GDS32.DLL';
         GetDriverFunc:= 'getSQLDriverINTERBASE';
         Params.Add('User_Name=SYSDBA');
         Params.Add('Password=masterkey');
         Params.Add('Database='+ADBNAME);
         LoginPrompt:= false;
         Open;
         dataQuery:= SQLReturn(connect)
         dataSet:= DataSetQuery(connect) 
         //finalize objects 
         if Connected then begin
           DataSet.Close;
           DataSet.Free;
           dataQuery.Close;
           dataQuery.Free;
           Close; //connect
           Free;
         end; 
       end;  //with
     except
       E:= Exception.Create('SQL Connect Exception: ');
       Showmessage(E.message+'SQL or connect missing')
     end;
     end;
    
    
     procedure BDEDataBaseConnect;
     var aParams, aTblNames: TStringList;
       aSession: TSession;
       dbMain: TDatabase;
       i: integer;
    

    begin

     AParams:= TStringList.Create;  
     aTblNames:= TStringList.Create; 
     //create a session to get alias parameters list 
     ASession:= TSession.Create(NIL);  
     ASession.SessionName:= 'Session4';  
     dbMain:= TDatabase.Create(NIL);  
     try  
       ASession.GetAliasParams(BDEAlias, AParams);
       for i:= 0 to aparams.count -1 do 
         writeln(aParams[i]);
       with dbMain do begin  
         Params.Assign(AParams);  
         dbMain:= ASession.OpenDatabase(BDEAlias);
         Writeln('Database is: '+dbMain.DataBaseName)
         KeepConnection:= True;
         GetTableNames(aTblNames, false)
         Writeln('Tables are: ');
         for i:= 0 to atblNames.count-1 do 
           Write(atblnames[i]+' ');
         doQuery(dbMain);
       end;
     finally  
       DBMain.Free;
       ASession.Free;  
       AParams.Free;
       aTblNames.Free;
     end;  
    

    end;

     Procedure SetADOSETAccess2;
     var i,z: integer;
          ws: TWideStrings;
     begin  
     with TAdoDataSet.Create(self) do begin
       cachesize:= 500;
       commandText:= SQLQUERY;
       //String:= 'Provider=MSDASQL;DSN=mx3base;Uid=sa;Pwd=admin';
       connectionString:= CONNECTSTRING;
       //try
       Open;
       //except   
       Writeln(intToStr(Recordcount)+' records found:')
       //end;
       for i:= 0 to Recordcount - 1 do begin
         for z:= 0 to Fieldcount - 1 do 
           Write((Fields[z].asString)+'  ');
         Writeln(#13#10)
         Next;
       end;
       Close;
       Free;        
     end; //TAdoDataSet
     Writeln('List Provider Names: ')
     ws:= TWideStringList.Create;
     getProviderNames(ws)
     for i:= 1 to ws.Count-1 do 
       writeln(inttostr(i) +' '+ws.strings[i]);
     ws.free;  
     end;
    

    Floating Point Test Routine

    By comparing a float point result like a double or extended type delivers a reference value is needed. Second a loop or iteration is needed to prove the approximation of the lasting result. I got the idea to make it with a well known series. There are several well-known proofs of the divergence of the harmonic series. Two of them are given below but one is chosen, cause it converges to ln(2) as our reference point. The series

       sum_{n = 1}^\infty \frac{(-1)^{n + 1}}{n} \;
       = 1 - {1}/{2}+{1}/{3}-{1}/{4}-{1}/{5}.... = ln(2)
    

    is known as the alternating harmonic series. This series converges by the alternating series test.

    In particular, the sum is equal to the natural logarithm of 2!:
    

    for i:= 1 to 50000000 do begin //zeta: double or extended;

        if i mod 2 = 0 then
            zeta:= zeta - 1/i else
            zeta:= zeta + 1/i;
        end; 
    

    50000 = 0.693137180659968 100000 = 0.693142180584982 500000 = 0.693146180561005 10^6 = 0.693146680560255 5*10^6 = 0.693147080560068 50*10^6= 0.693147170560399


    ln(2) = 0.693147180559945


    Leibniz formula:

        zeta:= 0;
        tac:= true;
        for i:= 1 to 50000 do 
          if NOT (i mod 2 = 0) then begin 
            tac:= not tac;
            if tac then
              zeta:= zeta - 1/i else
            zeta:= zeta + 1/i;
          end;  
    
          writeln('harmonic alternate leibniz formula to PI/4: '+floatToStr(zeta))  
          writeln(floatToStr(maxcalc('PI/4')))
          writeln(floatToStr(PIOn4))
    



    did some test routines from fundamentals4

     SelftestPEM;
     SelfTestCFundamentUtils;
     SelfTestCFileUtils;
     SelfTestCDateTime;
     SelfTestCTimer;
     SelfTestCRandom;
    

    also

     A:= EncodeDateTime(2001, 09, 02, 12, 11, 10, 0);
     Assert2(Month(A) = 9, 'EncodeDateTime');
     S:= GMTTimeToRFC1123TimeA(A, True);
     Assert2(S = '12:11:10 GMT','GMT');
     S:= GMTDateTimeToRFC1123DateTimeA(A, True);
     Assert2(S = 'Sun, 02 Sep 2001 12:11:10 GMT', 'GMTDateTimeToRFC1123DateTime');
    

    Boolean Logic

    with the so called double implication you can switch a light from 2 different points in distance and the logic table is this:

    0 0: 1 
    0 1: 0 
    1 0: 0 
    1 1: 1 
    

    in code they said a biconditional goes like this:

    function biImplicationtoMuch(a,b: boolean): boolean;
     begin
       result:= (NOT a OR b) AND (NOT b or a);
     end;  
    

    BUT its easier like this:

     function biImplication(a,b: boolean): boolean;
     begin
       result:= NOT(a XOR b);
     end;  
    
     for i:= 0 to 1 do
       for l:= 0 to 1 do
         printF(' %d %d: %d ',[i,l,biImplication(bool(i),bool(l))]);
    
    0 0: 1 
    0 1: 0 
    1 0: 0 
    1 1: 1
    

    see example of all boolean functions:

    http://www.softwareschule.ch/examples/308_bitbox3.htm

    http://www.softwareschule.ch/examples/308_bitbox3.txt

    Proposal for Abbreviation Symbol

     01 FALSE    //Contradiction
     02 AND      //Conjunction x*y
     03 INHIB    //Inhibition x*^y
     04 PRAEP    //Prependence x
     05 PRAE     //Presection ^x*y
     06 POST     //Postpendence y
     07 XOR      //Exclusive OR x*^y+^x*y
     08 OR       //Disjunction OR = x+y
     09 NOR      //Rejection
     10 AEQ      //Equivalence x<-->y, ^x*^y+x*y
     11 NEGY     //Y Negation ^y
     12 IMPY     //Y Implication y-->x; x+^y
     13 NEGX     //X Negation ^x
     14 IMPX     //X Implication x-->y; ^x+y
     15 NAND     //Exclusion
     16 TRUE     //TRUE Tautology
    

    Boolean Laws Proof

    procedure letBooleanLaws(a,b,c: boolean);
     begin
      // bool laws in one line
       writeln('distributiv and: '+booltostr(a and(b or c) = a and b or a and c,true));
       writeln('distributiv or  : '+booltostr(a or b and c = (a or b) and (a or c),true));
       writeln('associativ and: '+booltostr(a and (b and c) = a and b and c, true));
       writeln('associativ or  : '+booltostr(a or (b or c) = (a or b) or c, true));
     end;
    


       for i:= 0 to 1 do 
         for k:= 0 to 1 do 
           for t:= 0 to 1 do begin
             a:= boolean(i); b:= boolean(k); c:= boolean(t);
             printF('Boolean Law: %d%d%d',[a,b,c]);
             letBooleanLaws(a,b,c);
           end;
    

    Teaching for Proof:

       // AB=(A'+B')'
       writeln('mutata: '+boolToStr(a AND b = not(not a OR not b),true));
       // A'B'=(A+B)'
       writeln('mutatb: '+boolToStr(not a AND not b = not(a OR b),true));
       // (A'B')'=A+B
       writeln('mutatc: '+boolToStr(not(not a AND not b)=(a OR b),true));
    
         for i:= 0 to 1 do 
           for k:= 0 to 1 do begin
             a:= boolean(i); b:= boolean(k);
             printF('Boolean Mutater Law: %d%d',[a,b]);
             letMutaterLaws(a,b);
           end; 
       or letMutaterLawsBin(10,12);
    


     //Proof A XOR B = NOT(A=B)
       for i:= 0 to 1 do 
          for k:= 0 to 1 do begin
            A:= bool(i); B:= bool(k);
            writeln(booleanToString(A XOR B = NOT(A=B)))
          end;
      //shorter 
      for i:= 0 to 1 do 
        for k:= 0 to 1 do 
          PrintF('BinSet: %d%d = %d',[i,k,bool(i XOR k) = NOT bool(i=k)])
    

    Big Int Numbers or Big Decimals

    function BigMulu2(aone, atwo: string): string; var bigint, bigint1, bigintres: TXRTLInteger; begin

     XRTLFromString(aone, bigint, 10);
     XRTLFromString(atwo, bigint1, 10);
     XRTLMul(bigint,bigint1,bigintres);
     result:= XRTLToString(bigintres,10,10);
    

    end;

    function BigExp2(aone, atwo: string): string; var bigint, bigint1, bigintres: TXRTLInteger; begin

     XRTLFromString(aone, bigint, 10);
     XRTLFromString(atwo, bigint1, 10);
     XRTLExp(bigint,bigint1,bigintres);
     result:= XRTLToString(bigintres,10,10);
    

    end;


       writeln(BigMulu('123456789','123456789'));   //intern
       writeln(BigMulu2('123456789','123456789'));
       maXcalcF('123456789*123456789');
        //writeln(BigExp2('12','1000'));
       maXcalcF('12^1000');
       writeln(BigExp('12','1000'));
    

    Entropy Mystery

    HUMAT: Entropy form: SIGMASUM j=1 to n (pj * log 1 / pj).

    SIGMASUMpj * log(1 / pj)

    The implicit unpredictability or randomness of a propabilitiy p can be measured by the extent to which it ist possible to compress data like a tar or zip archive:

    much compressible -> less random -> more predictable

    This is the entropy, a measure of how much randomness (unpredictable) it contains.

    To explain entropy with a coin goes like this: E.g. a fair coin has two outcomes, each with a probability of 1/2 so the entropy is

    1/2 log 2 + 1/2 log 2 = 1

    PrintF('max. Entropy of coin 0.5p: %f',[0.5*log2(2)+0.5*log2(2)]); 
    > max. Entropy of coin 0.5p: 1.00
    

    This is sort of logic, the coin flip contains one bit of randomness, but what if the coin is not fair (manipulated), if it has a 3/4 chance of turning up heads:

    3/4 log 4/3 + 1/4 log 4 = 0.81

    PrintF('div. Entropy of coin 0.75p+0.25p: %.2f',[0.75*log2(4/3)+0.25*log2(4)]);
    > div. Entropy of coin 0.75p+0.25p: 0.81
    


     maXcalcF('0.5*log(2)/log(2)+0.5*log(2)/log(2)')  
     > 1
     maXcalcF('0.75*log(4/3)/log(2)+0.25*log(4)/log(2)')  
     > 0.81
    

    unit StEclpse;

     TStEclipseType = (etLunarPenumbral, etLunarPartial, etLunarTotal,
                       etSolarPartial, etSolarAnnular, etSolarTotal,
                       etSolarAnnularTotal);
    
     TStContactTimes = packed record
       UT1,                         {start of lunar penumbral phase}
       UT2,                         {end of lunar penumbral phase}
       FirstContact,                {start of partial eclipse}
       SecondContact,               {start of totality}
       MidEclipse,                  {mid-eclipse}
       ThirdContact,                {end of totality}
       FourthContact   : TDateTime; {end of partial phase}
     end;
    

    Helmholtz Function

    Big increase Entropy in the beginning then decreases away to zero

      fct_table(40, 150, 20, clblue, fct4x, 'Helmholtz(x)');
    
      procedure fct4e(var x: single);
      begin
        x:= -150*(power(x,2)/(power(30+power(x,2),2)));
      end;
    

    Entropy and Cryptography

    HUMAT: you cant compress a strong cipher (output of a cryptographic function), cause it has high entropy (randomness).

    less compressible -> most random -> not predictable


    To explain entropy with a coin goes like this:

    PrintF('max. Entropy of coin 0.5p: %f',[0.5*log2(2)+0.5*log2(2)]); 
    
    PrintF('div. Entropy of coin 0.75p+0.25p: %.2f',[0.75*log2(4/3)+0.25*log2(4)]);
    

    SHA1 with Indy

    function Indy_SHA1Hash(apath: string): string; var

     idsha1: TIdHashSHA1;  //shaback: T5x4LongWordRecord;
     shaStream: TMemoryStream;
    

    begin

      idsha1:= TIDHashsha1.Create;
      shaStream:= TMemoryStream.Create;
      try
        shaStream.Position:= 0;
        shaStream.LoadFromFile(ExePath+'maxbox3.exe');
        //writeln('Indy SHA1 Proof: '+idsha1.asHEX(shaback)); debug
        result:= idsha1.AsHEX(idsha1.HashValue(shaStream));
      finally  
        idsha1.free;
        shaStream.Free;
      end;
    

    end;

    Object Oriented

    A with statement with type casting

     with TClientSocket.create(self) do begin
         //writeln(TClientSocket(socket).host);
         writeln('TCustomWinSocket host: '+TCustomWinSocket(Socket).remotehost);
         writeln('TCustomWinSocket port: '+intToStr(TCustomWinSocket(Socket).remoteport));
         Free
       end; 
    

    cause of

    public
       constructor Create(AOwner: TComponent); override;
       destructor Destroy; override;
       property Socket: TClientWinSocket read FClientSocket;
    
     TClientWinSocket = class(TCustomWinSocket)
     private
       FClientType: TClientType;
     protected
       procedure SetClientType(Value: TClientType);
     public
       procedure Connect(Socket: TSocket); override;
       property ClientType: TClientType read FClientType write SetClientType;
     end;
    


    ShowModal shows a window and waits until it is closed. Until closing, you can't interact with any other form of the application. What many do not know: You can define a result value on events of the ShowModal Form, which you can use very clean in your program. For example to check which date a user has clicked.

     procedure TdbOpenDlg_Button1Click(Sender: TObject);
     begin
       dbOpenDlg.ModalResult:= mrOK;
     end;
    
     procedure TdbOpenDlg_CalBtnFromClick(Sender: TObject);
     begin
     dbOpenDlg:= TdbOpenDlg.create(self)
     with dbOpenDlg do begin
       setbounds(0,0,400,400)
       //showmodal later
     end;
      with TButton.create(dbopenDlg) do begin
        parent:= dbopenDlg;
        setbounds(20,200,100,40)
        caption:= 'OK Date';
        onclick:= @TdbOpenDlg_Button1Click;
      end;  
     try
      with TDateTimePicker.create(dbopenDlg) do begin
        parent:= dbopenDlg;
        SetBounds(20,20,100,100);
        if dbopenDlg.showModal = mrOK then
          BeginDate:= Datetime;
        writeln('date with time: '+datetimetostr(Datetime));
      end;
       writeln('get date back '+datetostr(begindate));   //debug
     finally
       dbopenDlg.Free;
     end;
     end;
    

    Arduino

    Open a COM Port and use Arduino as Timer:

     const COMPORT ='COM12';
       var cPort: TComPort;
    
     procedure InitCreateComPort(Sender: TObject);
     begin
       cPort:= TComPort.Create(self);
         with cPort do begin
         BaudRate:= br9600;
         Port:= COMPORT;
         Parity.Bits:= prNone;
         StopBits:= sbOneStopBit;
         DataBits:= dbEight;
       end;
     end; 
    


    procedure SetArduinoTime(Sender: TObject);

      var arduinoTime,aout: shortstring;
      begin
      arduinoTime:= FormatDatetime('HHmmssddMMyyyy',Now)
      //+intToStr(DayOfWeek(Now-1)); 
      //formatdatetime('"stop is:" hh:mm:ss:zzz', time)) 
      WriteLn(arduinoTime);
      //pass the time to COM port
      try
        cPort.Open;
      except 
        writeln(' No free com port found! ');
        //cPort.Free;
      end;      
      cPort.WriteStr(arduinoTime)
      //while (true) do 
      repeat
        aout:=;
        cport.ReadStr(aout, 21)
            //if aout <>  then
        WriteLn('From Arduino: ' + aout);
        sleep(1000)
      until iskeyPressed;  
      cPort.Close;    
      cPort.Free;    
    end;
    


    Save Space with Function Chaining

     For example you want to replace chars in a file A and save it to a file B:
       //fst:= '<contains name="uPSDisassembly"/> <contains name="uPSComponent_COM"/>' and so on
       //e.g. we want to add a CR LF to a XML file with no CRLF before
    
       fst:= fileToString('..\'+'containstest.txt');   
       afst2:= ReplaceString(fst,'"/> ','"/>'+CRLF);
       stringToFile('..\'+'containstest2.txt',afst2,true);  
    

    Second you can save fst on var with parameter passing

       afst2:= ReplaceString(filetostring('..\'+'containstest.txt'),'"/> ','"/>'+CRLF);
       Stringtofile('..\'+'containstest3.txt',afst2,true);   
    
    

    Third you can pass all vars by a one liner (not so maintainable):

       StringTofile('..\'+'contain2.txt',ReplaceString(fileToString('..\'+'contain.txt'),'"/> ','"/>'+CRLF),true);   
    
       OpenDoc('..\'+'contain2.txt');
    

    Bugs

    1. COM Port Information:

      Defect: When using the menu/ Program/Information and you don't have a COM Port in use the window will fail
      Propose: Avoid the Information window when loading multiple scripts
      Cause: while query available COM Ports an out of index exception occurs
      State: Solved
    

    2. Streams with File/Memory Stream:

      Defect: When using an array of byte an abstract error occurs
      Propose: Avoid the TStream as parameter, use TFileStream direct
      Cause: no overloading possible so the names are different - 
             procedure ReadAB(Buffer: TByteArray;Count:LongInt)');
             procedure WriteAB(Buffer: TByteArray;Count:LongInt)');
      State: Open
    

    3. Full Text Finder:

      Defect: When using on 64bit 120 dots per inch resolution the form is not size able
      Propose: Move the splitter up or down to size the window
      Cause: Panels are fix
      State: Open
    

    4. Button Set

      Defect: When using buttonset you have to name it each one
      Propose: Name the real set name
      Cause: sets are limited
      State: Open
    
      will not work: case CreateMessageDialog('Text the maXbox', mtWarning,[mbYesNoCancel]).ShowModal 
      works: case CreateMessageDialog('Text the maXbox', mtWarning,[mbYes,mbNo,mbCancel]).ShowModal 
               of  mrYes: ShowMessage('Yes');
                   mrNo: ShowMessage('No');
                   mrCancel: ShowMessage('Cancel');
               end;
    

    5. File Stream Buffer

      Defect: When using filestream buffer read/write (fs.WriteBufferInt(v, 2);)
      Propose: use string or FileS.WriteInt(Buff,1);
      Cause: Exception: Stream write error.
      State: Open
    

    6. High() of Enumerator and Set

      Defect: When using high(set) its always 255
      Propose: use 1 to n instead;
      Cause: invalid type cast
      State: Open
    
        suit:TShortSuit;   // TShortSuit=(CardS,CardD,CardC,CardH);
        for suit1:= low(TShortSuit) to high(TShortSuit) do  won't work
        for suit1:= 0 to 3 do begin
          cards0[4*(i-11)+suit1]:= TForm1_makecard(startx,starty,i,TShortSuit(suit1));
    

    7. Themes Color in Panel, Label, Bars etc.

      Defect: When set color in panel it inherits the parent color
      Propose: use controlstyle
      Cause: themes override the color
      State: Solved (with property ParentBackground)
    
      To set a color in a Panel or to override themes two ways are possible: - controlstyle set - 
      parentbackground:
      with mypanel do begin
         caption:= '********maXboxMP3********';  
         controlstyle:= controlstyle - [csParentBackground,csOpaque];
      mypanel:= TPanel.Create(self)
         with mypanel do begin
         ParentBackground:= false;
         color:= clyellow;
    

    8. Open other files with maXbox (Open with...)

      Defect: When you set maXbox as process to open a file with another extension it cant find it
      Propose: drag and drop the file you want to open
      Cause: it want to open and run the file at the same time
      State: In Work
    

    Performance

    Performance is dark chapter cause maXbox is an interpreter But it does have more functions precompiled than interpreted!

    As a comparison take the EightQueens Problem [8*8] You had to set 8 queens on a chessboard without collision {recursive solution to the Eight Queens problem} As a long time runner I set it to 14 Queens:

    \examples\044_pas_14queens_solwith14.txt

    Take the following reference implemantation for measures:

    http://www.softwareschule.ch/examples/044_queens_performer2.txt

    http://www.softwareschule.ch/examples/044_queens_performer2.htm

    Result: 365596 solutions Time: start is: 21:30:32:233 all codestrings of solutions stop is: 23:19:44:183 1 h run time: 49:11:950 mX3 executed: 23.05.2014 23:19:44 Runtime: 1:49:13.10 Memoryload: 52% use

    file in editor: 6215131 lines Very slow but all solutions are painted in a file (94.7 MB (99'331'007 Bytes)) , e.g. the last solution one:

    365596

    XXXXXXXXXXXXXQ XXXXXXXXXXXQXX XXXXXXXXXQXXXX XXXXXXXQXXXXXX XXQXXXXXXXXXXX XXXXQXXXXXXXXX XQXXXXXXXXXXXX XXXXXXXXXXQXXX QXXXXXXXXXXXXX XXXXXQXXXXXXXX XXXXXXXXXXXXQX XXXXXXXXQXXXXX XXXXXXQXXXXXXX XXXQXXXXXXXXXX

    solution string: 14/12/10/8/3/5/2/11/1/6/13/9/7/4


    08 Queens: 92 solutions: 0 h run time: 00:00:376

    09 Queens: 352 solutions: 0 h run time: 00:01:493

    10 Queens: 724 solutions: 0 h run time: 00:06:460

    11 Queens: 2680 solutions: 0 h run time: 00:32:107

    12 Queens: 14200 solutions: 0 h run time: 02:58:011

    13 Queens: 73712 solutions: 0 h run time: 17:24:995

    Compiled solution with 14 Queens (365596 solutions) Intel Core 2 Quad (Q9559, 2.83 GHz) 9712ms!

    Tuning

    To speed up a script has following rules:

    1. Set the Application.ProcessMessages OFF:

    in menu Options/ProcessMessages

    or in code with processMessagesOFF; //more speed

    2. use internal functions instead of script functions:

    e.g. FileSearch('firstdemo.txt',exepath))

    3. Start a seconde instance of maXbox with F4

    Current Development to mX3 V3.0

    V3.0 supports more graphic formats, I work with

    ImageFileLibBCB for Delphi/BCB on sourceforge

    which supports many formats, with this library, Delphi programs can read and write BMP, ICO, CUR, PNG, MNG, PCX, TIFF and JPEG 2000 bitmaps. RAS, PNM, PGM, PPM, HIPS images can be loaded, but not created.

    Concerning Indy, the SMPT, IdDayTime, hashCRC and message support is going on, maXbox becomes a simple mailbox too, also the Indy globals with a lot of network functions like to get the hostname is under way

    The conversion of the TPSImport_StrUtils is already done, soundex and much string functions will be possible

    a lot of delphi (sysutils, system) and indy functions (indy globals) are now going to convert to the box, by end of september a beta will be available to get first impressions of maXbox3

    Also mX3 on Linux is on the way, ported Indy 9 to Kylix3 so graphics and math functions too. Release date for mX3 win and mX3 linux will be the January 31th on 2011.

    Improvments of 64Bit, PNG, and Ansi/WideStrings are done, Dialogs and Plugins are under way (e.g. MP3-Player and POP3-Mail Function) From October to February time will spent on tuning, testing, tutorials and a list of all functions in mX3 Sysutils.converted and a thread function (casting&converting) has done, now I'm updating all the examples from _1 to _150 in categories base, math, graphic, statistic, system, net and internet.

    >>>Release Date for mX3 (Win and Linux) will be the 31.th of January 2011!

    Function CharToBin(_Chr: Char): String; Var

      i: Integer;
    

    Begin

      For i:= SizeOf(_Chr) * 8 - 1 Downto 0 Do
    

    Result:= Format('%s%d', [Result, Byte((Ord(_Chr) And (1 Shl i))

    Select to_char(id)||chr(9)||rtrim(lpad(' ',2*(level-1)) || bez,' ')||
    
    chr(9)||rtrim(ueberschrift,' ')||chr(9)||rtrim(text,' ') from knoten
    
    start with id=69 connect by prior id=parent
    

    SHL EXponent:

    var i: int64;

    for i:= 1 to 32 do
        printF('Bin exponent with SHL: 2^%d = %d',[i, i SHL i DIV i]);
    

    bin exp with SHL: 2^1 = 2 bin exp with SHL: 2^2 = 4 bin exp with SHL: 2^3 = 8 bin exp with SHL: 2^4 = 16 bin exp with SHL: 2^5 = 32.........


    Minesweeper Game, January 2013:

    http://www.softwareschule.ch/examples/285_minesweeper2.htm


    Working with BigIntegers:

    function BigMulu2(aone, atwo: string): string; var bigint, bigint1, bigintres: TXRTLInteger; begin

     XRTLFromString(aone, bigint, 10);
     XRTLFromString(atwo, bigint1, 10);
     XRTLMul(bigint,bigint1,bigintres);
     result:= XRTLToString(bigintres,10,10);
    

    end;

    function BigExp2(aone, atwo: string): string; var bigint, bigint1, bigintres: TXRTLInteger; begin

     XRTLFromString(aone, bigint, 10);
     XRTLFromString(atwo, bigint1, 10);
     XRTLExp(bigint,bigint1,bigintres);
     result:= XRTLToString(bigintres,10,10);
    

    end;

    writeln(BigMulu2('123456789','123456789'));
    maXcalcF('123456789*123456789');
    
    
    //Environment Info:
    SaveString(ExePath+'\Examples\envinfo.txt',GetEnvironmentString);   
    OpenFile(ExePath+'\Examples\envinfo.txt');
    

    Generate QRCode


    {This is using the Google Charts API, but it does demonstrate a quick and easy way to get QR barcodes in a maXbox, Delphi or Lazarus/FreePascal application.

    Const

      UrlGoogleQrCode='http://chart.apis.google.com/chart?chs=%dx%d&cht=qr&chld=%s&chl=%s';
    

    var

      QrImgCorrStr : array [0..3] of string; // =('L','M','Q','H');
    

    procedure GetQrCode(Width,Height: Word; Correct_Level: string; const Data:string); var

     encodedURL: string;
     idhttp: TIdHttp;// THTTPSend;
     png: TLinearBitmap;//TPNGObject;
     pngStream: TMemoryStream;
    

    begin

     encodedURL:= Format(UrlGoogleQrCode,[Width,Height, Correct_Level, HTTPEncode(Data)]);
     //WinInet_HttpGet(EncodedURL,StreamImage);
     idHTTP:= TIdHTTP.Create(NIL)
     pngStream:= TMemoryStream.create;
     with TLinearBitmap.Create do try
       idHTTP.Get1(EncodedURL, pngStream)
       pngStream.Position:= 0;
       LoadFromStream2(pngStream,'PNG');
       FImage.Picture:= NIL;
       AssignTo(FImage.picture.bitmap);
       SaveToFile(ExePath+'mX3QRCode.png');
       //OpenDoc(ExePath+'mX3QRCode.png');
     finally
       Dispose;
       Free;
       idHTTP.Free
       pngStream.Free;
     end;
    

    end;

    Call to invoke:

     GetQrCode(150,150,'Q', 'this is maXland on the maXbox');
    

    HTTP Download with MemoryStream and Progress:

    procedure GetFileDownloadProgress(myURL, myFile: string); var

     HttpClient: TIdHttp;
     aFileSize: Int64;
     aBuffer: TMemoryStream;
    

    begin

     HttpClient:= TIdHttp.Create(NIL);
     try
       //HttpClient.Head('http://somewhere.ch/somefile.pdf');
       HttpClient.Head(myURL);
       aFileSize := HttpClient.Response.ContentLength;
         Writeln('FileSize of MemStream Download: '+inttoStr(aFileSize));
       aBuffer:= TMemoryStream.Create;
       try
         while aBuffer.Size &lt;Help&gt;
    

    - Menu: With <F2> you check syntax with <F8> you debug and <F9> you compile!

    - Menu: With <Crtl><F3> you can search for code on examples

    - Menu: Open in menu Output a new instance <F4> of the box to compare or prepare your scripts

    - Menu: Set Interface Naviagator in menu /View/Intf Navigator

    - Menu: Switch or toogle between the last 2 scripts in menu File/LoadLast (History is set to 9 files)

    - Inifile: Set memory report in ini: MEMORYREPORT=Y :report on memory leaks on shutdown by dialog

    - Context Menu: You can printout your scripts as a pdf-file or html-export

    - Context: You do have a context menu with the right mouse click

    - Menu: With the UseCase Editor you can convert graphic formats too.

    - Menu: On menu Options you find Addons as compiled scripts

    - IDE: You don't need a mouse to handle maXbox, use shortcuts

    - Menu: Check Options/ProcessMessages! if something is wrong or you can't see graphics in a time

    - IDE: Drag n' drop your scripts in the box or the model in use case editor (Cut,Copy,Paste always available)

    - Editor: You can get templates as code completion with <ctrl j> in editor like classp or iinterface or ttimer (you type classp and then CTRL J),or you type tstringlist and <Ctrl><J>

    - Menu: In menu output (console) you can set output menu in edit mode by unchecking <read only output>

    - Editor: After the end. you can write or copy notes or descriptions concerning the app or code

    - Code: If you code a loop till key-pressed use function: isKeyPressed;

    - Code: Macro set the macros #name, #date, #host, #path, #file, #head #sign, see Tutorial maxbox_starter25.pdf

    - Editor: - Dbl Click on Word in Editor search amount of words with highlighting, Dbl Click on Bookmarks to delete and Click and mark to drag a bookmark

    - Menu: To start handling from CD-ROM (read only mode) uncheck in Menu /Options/Save before Compile

    - IDE: A file info with system and script information you find in menu Program/Information

    - IDE: Make a screenshot of the content and environment in menu Output/Save Screenshot

    - IDE: Use a boot loader script 'maxbootscript.txt' (as auto start) to change the box each time you start it.

    - IDE: With escape or <Ctrl> Q you can also leave the box or stop a script in menu program - stop program

    Current Development to mX4 V4.0

    Switch between Pascal and C = PasCal

      float convertToF(float temperatureC)
       {
        return (temperatureC * 9.0 / 5.0) + 32.0;
       }
    
    
      function convertToF(temperatureC: float): float;
      begin
        result:= (temperatureC * 9.0/5.0) + 32.0;
      end;
    

    In the version 3.8 we upgrade from mX3 (delphi2007) to mX4 compiler (delphi2009) A Unit support, Boot-Loader Scripting and Version Check routine is already workable The idea of a BOOTSCRIPT is before start the maXbox you can alter, init or change functions or features of the OpenTools API in maXbox, so the bootscript is named maxbootscript.txt and all those routines will be executed by starting the box. For example you change the buttons or color options of the editor or you set some monitor or processing functions valid for all scripts to be executed.

    With mX4 we do have full decompile or debug possibility of the scripts, mX3 <Return> to run the Sentence';

       width:= (vx*psize)+ 10 + 300;
       height:= (vy*psize)+ 30;
       BorderStyle:= bsDialog;
       Position:= poScreenCenter;
       //onKeyPress:= @FormKeyPress
       //OnClick:= @Label1Click;
       //OnClose:= @closeForm;
       Show;
     end;
     result:= ppform;
    

    end;

    procedure LetBitmaponForm(aform: TForm); var mbitmap: TBitMap; begin

     mbitmap:= TBitmap.Create;
     try
       mbitmap.LoadFromFile(Exepath+BITMAP);
       aform.Canvas.Draw(370,170, mbitmap);
     finally
       //aForm.Free;
       mbitmap.Free;
     end;
    

    end;

    Call: LetBitmaponForm(loadPForm(8,8));

    Closure Pattern with procedure type:

    type TProc = procedure(VAR x: single); 
    
    TProc2 = procedure();
    TPredicate = function(const x: integer): bool; 
    
    procedure ShowHourGlass(aProc: TProc2);
    var OldCursor: TCursor; 
    begin 
     OldCursor := Screen.Cursor; 
     Screen.Cursor := crHourGlass; 
     try 
      //aProc(x); 
       aProc(); 
       showmessage('^fct2 after');
     finally 
      Screen.Cursor := OldCursor 
     end; 
    end;
    
    PROCEDURE fct2; //as closure
     var i: integer;
     BEGIN  
       for i:= 1 to 99996666 do 
         Sin(i);
       sleep(4000)
       showmessage('^fct2 in');
     END;
    

    Call:

      ShowHourGlass(@fct2);
    

    RegEx in maxbox has some components one is the RegExp Studio it goes like this:

     email:= 'max@kleiner.com';
     rex:= '[\w\d\-\.]+@[\w\d\-]+(\.[\w\d\-]+)+';
    
     writeln('email is: '+booleanToString(ExecRegExpr(rex, email)))
    

    How do I get the last term in URL between slashes ie 'last' using regex?

     myURL = 'http://www.kleiner.ch/kleiner/download/G9_japan.mp3';
    
    
     mp3song1:= ReplaceRegExpr('([^/]+)/?$',myurl,'**,true); //show all except last**
     --&gt;http://www.kleiner.ch/kleiner/download/
    
     mp3song1:= ReplaceRegExpr('([^/]+)?/',myurl,'**,true); //show only last extract**
     --&gt;G9_japan.mp3
    
    
     writeln('regex extract test: '+mp3song1)
    
    
    Test also with:
    mp3song1:= ExtractWord(5,myurl,['/']);
    

    Pascal Parser Regex

    function ParseReturnType(const AText: string): string;

     Parser.Pattern := '((\w+)\.)*\w+';
    

    function ParseDefaultValue(const AText: string): string;

     Parser.Pattern := '\s*\=\s*(_.*_|\w+|(\+|\-)?\d+\.\d+)';
    

    function ParseTypeName(const AText: string): string;

     Parser.Pattern := '(?:\s*\:\s*)&?(((\w+)\.)*(\w+))';
    

    procedure ParseParamNames(Routine: TRoutineDeclaration; const AText: string);

     Parser.Pattern := '&?(((\w+)\.)*\w+)(?:\s*,|:)';
    

    function ParseSingleDeclaration(Routine: TRoutineDeclaration; const AText: string): TParamType;

     Parser.Pattern := '((const|var|out)?(?:\s)*&?(\w+)(\s*,\s*\w+)*(?:\s*\:\s*)&?((\w+)\.)*(\w+)(\s*\=\s*(_.*_|\w+|\d+))?)';
    

    function ParseTypeDeclaration(Routine: TRoutineDeclaration; const AText: string): TParamType;

     Parser.Pattern := '([^;]*)(\;)?';
    

    API Code

    SendMessage Ex.:

    Procedure memoCaretPos(memo: TMemo; var col, row: integer);
    var i: integer;
    begin
      row:= SendMessage(memo.handle, EM_LINEFROMCHAR, -1, 0);
      writeln('rpw '+inttostr(row))
      col:= memo.Selstart;
      if row &gt; 0 then
      for i:= 0 to row-1 do
        col:= col - length(memo.lines[i])-2;
      Stat.simpletext:= selected+ ' caret has been set';
    end;
    

    Window Themes and Color

    To set a color in a Panel or to override themes two ways are possible: - controlstyle set - parentbackground

     with mypanel do begin
        caption:= '********maXboxMP3********';  
        controlstyle:= controlstyle - [csParentBackground,csOpaque];
    
    
     mypanel:= TPanel.Create(self)
        with mypanel do begin
        ParentBackground:= false;
        color:= clyellow;
    

    Error Handling

     Forget the FormatMessage() take the sysErrorMessage!
     Convert the OS Error Code into a User Friendly Message
     trying to remove a non existing folder or RemoveDir deletes an existing empty directory.
    
    
     RemoveDir('k:\NoSuchFolder') ;
     ShowMessage('System Error Message: '+ SysErrorMessage(GetLastError)) ;
     &gt;System Error Message: The system cannot find the file specified
    

    Service, App or Session?

     function isService: boolean;
     begin
       result:= NOT(Application is TApplication);
       {result:= Application is TServiceApplication;}
     end;
    
    
     function isApplication: boolean;
     begin
       result:= Application is TApplication;
     end;
    
    
     //SM_REMOTESESSION = $1000
     function isTerminalSession: boolean;
     begin
       result:= GetSystemMetrics(SM_REMOTESESSION) &gt; 0;
     end;
    

    function GetShortPathName(lname, sname: pchar; mpath: longint): bool;

     external 'GetShortPathNameW@kernel32.dll stdcall';
    

    //undocumented !

    function MessageBoxTimeOut(hWnd: HWND; lpText: PChar; lpCaption: PChar; uType: UINT;

    wLanguageId: WORD; dwMilliseconds: DWORD): Integer; external 'MessageBoxTimeoutA@user32.dll stdcall';
    
    
     iFlags:= $0 or $00010000 or $00000040;
        iResult:= MessageBoxTimeout(Application.Handle,
            'Test a timeout of 2 seconds.','MessageBoxTimeout Test',iFlags,0,2000);
    

    BitBlt: Own Mouse Moving Pic Cursor

    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer); //var FOldRect: TRect; //makes a blur and zoom effect begin

     //firsttime:= true;   //move tester
     { 1) Restore Form1: copy storage onto Form1 at its old location }
     //FOldRect:= Rect(280, 200, X , Y);
     if FirstTime then FirstTime:= False
       else BitBlt(bfrm.Canvas.Handle, FOldRect.Left, FOldRect.Top,
        FPic.Width,FPic.Height, FStorage.Canvas.Handle,0,0,SRCCOPY);
     { save old location }
     FNewRect:= Rect(X, Y, X + FPic.Width, Y + FPic.Height);
     FOldRect:= FNewRect;
     { 2) Save copy: copy rectangle from Form1 to storage at new location.}
     BitBlt(FStorage.Canvas.Handle,0,0, FPic.Width, FPic.Height,
            bfrm.Canvas.Handle, FNewRect.Left, FNewRect.Top,  SRCCOPY);
     { 3) copy the image to Form1 using SRCINVERT }
     BitBlt(bfrm.Canvas.Handle, FNewRect.Left, FNewRect.Top, FPic.Width, FPic.Height,
            FPic.Canvas.Handle,0,0, SRCAND);
    

    end;

    function NumProcessThreads2: integer; var

     hsnapshot: THandle;
     Te32: TTHREADENTRY32;
     proch: dWord;
    

    begin

     Result:= 0;
     proch:= GetCurrentProcessID;
     hSnapShot:= CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    
     Te32.dwSize:= sizeof(Te32);
     if Thread32First(hSnapShot, Te32) then begin
       if Te32.th32OwnerProcessID = proch then
         inc(Result);
       while Thread32Next(hSnapShot, Te32) do begin
         if Te32.th32OwnerProcessID = proch then
           inc(Result);
       end;
     end;
     CloseHandle(hSnapShot);
     writeln('WinDir '+getwindir);
     writeln('SysDir '+getsysdir);
     //getsystempath
    

    end;

    For example, the thread queues are more than lists of messages--they also maintain some state information. Some messages (like WM_PAINT) aren't really queued, but synthesized from the additional state information when you query the queue and it's empty. Messages sent to windows owned by other threads are actually posted to the receiver's queue rather than being processed directly, but the system makes it appear like a regular blocking send from the caller's point of view; this can cause deadlock (because of circular sends back to the original thread).

    function FileTimeGMT2 (FileName: STRING): TDateTime;

            // Returns the Date and Time of the last modification of the given File
            // The Result is zero if the file could not be found
            // The Result is given in UTC (GMT) time zone
    

    VAR

     Handle         : THandle;
     FindData       : TWin32FindData;
     SystemFileTime : TSystemTime;
     mf: TFileTime;
    

    begin

     Result := 0.0;
     Handle := FindFirstFile (PChar (FileName), FindData);
     IF Handle &lt;math&gt;SIGMASUM pj * log (1 / pj) &lt;/math&gt;
    

    The implicit unpredictability or randomness of a propabilitiy p can be measured by the extent to which it ist possible to compress data like a tar or zip archive:

    much compressible -> less random -> more predictable

    This is the entropy, a measure of how much randomness (unpredictable) it contains.

    To explain entropy with a coin goes like this: E.g. a fair coin has two outcomes, each with a probability of 1/2 so the entropy is

    1/2 log 2 + 1/2 log 2 = 1

    PrintF('max. Entropy of coin 0.5p: %f',[0.5*log2(2)+0.5*log2(2)]); 
    &gt; max. Entropy of coin 0.5p: 1.00
    

    This is sort of logic, the coin flip contains one bit of randomness, but what if the coin is not fair (manipulated), if it has a 3/4 chance of turning up heads:

    3/4 log 4/3 + 1/4 log 4 = 0.81

    PrintF('div. Entropy of coin 0.75p+0.25p: %.2f',[0.75*log2(4/3)+0.25*log2(4)]);
    &gt; div. Entropy of coin 0.75p+0.25p: 0.81
    
    
    
    
    
     maXcalcF('0.5*log(2)/log(2)+0.5*log(2)/log(2)')  
     &gt; 1
     maXcalcF('0.75*log(4/3)/log(2)+0.25*log(4)/log(2)')  
     &gt; 0.81
    

    unit StEclpse;

     TStEclipseType = (etLunarPenumbral, etLunarPartial, etLunarTotal,
                       etSolarPartial, etSolarAnnular, etSolarTotal,
                       etSolarAnnularTotal);
    
    
     TStContactTimes = packed record
       UT1,                         {start of lunar penumbral phase}
       UT2,                         {end of lunar penumbral phase}
       FirstContact,                {start of partial eclipse}
       SecondContact,               {start of totality}
       MidEclipse,                  {mid-eclipse}
       ThirdContact,                {end of totality}
       FourthContact   : TDateTime; {end of partial phase}
     end;
    

    Helmholtz Function

    Big increase Entropy in the beginning then decreases away to zero

      fct_table(40, 150, 20, clblue, fct4x, 'Helmholtz(x)');
    
    
      procedure fct4e(var x: single);
      begin
        x:= -150*(power(x,2)/(power(30+power(x,2),2)));
      end;
    

    Entropy and Cryptography

    HUMAT: you cant compress a strong cipher (output of a cryptographic function), cause it has high entropy (randomness).

    less compressible -> most random -> not predictable

    To explain entropy with a coin goes like this:

    PrintF('max. Entropy of coin 0.5p: %f',[0.5*log2(2)+0.5*log2(2)]);
    
    
    PrintF('div. Entropy of coin 0.75p+0.25p: %.2f',[0.75*log2(4/3)+0.25*log2(4)]);
    

    SHA1 with Indy

    function Indy_SHA1Hash(apath: string): string; var

     idsha1: TIdHashSHA1;  //shaback: T5x4LongWordRecord;
     shaStream: TMemoryStream;
    

    begin

      idsha1:= TIDHashsha1.Create;
      shaStream:= TMemoryStream.Create;
      try
        shaStream.Position:= 0;
        shaStream.LoadFromFile(ExePath+'maxbox3.exe');
        //writeln('Indy SHA1 Proof: '+idsha1.asHEX(shaback)); debug
        result:= idsha1.AsHEX(idsha1.HashValue(shaStream));
      finally  
        idsha1.free;
        shaStream.Free;
      end;
    

    end;

    Object Oriented

    A with statement with type casting

     with TClientSocket.create(self) do begin
         //writeln(TClientSocket(socket).host);
         writeln('TCustomWinSocket host: '+TCustomWinSocket(Socket).remotehost);
         writeln('TCustomWinSocket port: '+intToStr(TCustomWinSocket(Socket).remoteport));
         Free
       end;
    

    cause of

    public
       constructor Create(AOwner: TComponent); override;
       destructor Destroy; override;
       property Socket: TClientWinSocket read FClientSocket;
    
    
     TClientWinSocket = class(TCustomWinSocket)
     private
       FClientType: TClientType;
     protected
       procedure SetClientType(Value: TClientType);
     public
       procedure Connect(Socket: TSocket); override;
       property ClientType: TClientType read FClientType write SetClientType;
     end;
    

    ShowModal shows a window and waits until it is closed. Until closing, you can't interact with any other form of the application. What many do not know: You can define a result value on events of the ShowModal Form, which you can use very clean in your program. For example to check which date a user has clicked.

     procedure TdbOpenDlg_Button1Click(Sender: TObject);
     begin
       dbOpenDlg.ModalResult:= mrOK;
     end;
    
    
     procedure TdbOpenDlg_CalBtnFromClick(Sender: TObject);
     begin
     dbOpenDlg:= TdbOpenDlg.create(self)
     with dbOpenDlg do begin
       setbounds(0,0,400,400)
       //showmodal later
     end;
      with TButton.create(dbopenDlg) do begin
        parent:= dbopenDlg;
        setbounds(20,200,100,40)
        caption:= 'OK Date';
        onclick:= @TdbOpenDlg_Button1Click;
      end;  
     try
      with TDateTimePicker.create(dbopenDlg) do begin
        parent:= dbopenDlg;
        SetBounds(20,20,100,100);
        if dbopenDlg.showModal = mrOK then
          BeginDate:= Datetime;
        writeln('date with time: '+datetimetostr(Datetime));
      end;
       writeln('get date back '+datetostr(begindate));   //debug
     finally
       dbopenDlg.Free;
     end;
     end;
    

    Arduino

    Open a COM Port and use Arduino as Timer:

     const COMPORT ='COM12';
       var cPort: TComPort;
    
    
     procedure InitCreateComPort(Sender: TObject);
     begin
       cPort:= TComPort.Create(self);
         with cPort do begin
         BaudRate:= br9600;
         Port:= COMPORT;
         Parity.Bits:= prNone;
         StopBits:= sbOneStopBit;
         DataBits:= dbEight;
       end;
     end;
    

    procedure SetArduinoTime(Sender: TObject);

      var arduinoTime,aout: shortstring;
      begin
      arduinoTime:= FormatDatetime('HHmmssddMMyyyy',Now)
      //+intToStr(DayOfWeek(Now-1)); 
      //formatdatetime('"stop is:" hh:mm:ss:zzz', time)) 
      WriteLn(arduinoTime);
      //pass the time to COM port
      try
        cPort.Open;
      except 
        writeln(' No free com port found! ');
        //cPort.Free;
      end;      
      cPort.WriteStr(arduinoTime)
      //while (true) do 
      repeat
        aout:=_;_
        cport.ReadStr(aout, 21)
            //if aout &lt;contains name="uPSDisassembly"/&gt; &lt;contains name="uPSComponent_COM"/&gt;' and so on
       //e.g. we want to add a CR LF to a XML file with no CRLF before
    
       fst:= fileToString('..\'+'containstest.txt');   
       afst2:= ReplaceString(fst,'"/&gt; ','"/&gt;'+CRLF);
       stringToFile('..\'+'containstest2.txt',afst2,true);
    

    Second you can save fst on var with parameter passing

       afst2:= ReplaceString(filetostring('..\'+'containstest.txt'),'"/&gt; ','"/&gt;'+CRLF);
       Stringtofile('..\'+'containstest3.txt',afst2,true);
    

    Third you can pass all vars by a one liner (not so maintainable):

       StringTofile('..\'+'contain2.txt',ReplaceString(fileToString('..\'+'contain.txt'),'"/&gt; ','"/&gt;'+CRLF),true);
    
       OpenDoc('..\'+'contain2.txt');
    

    Bugs

    1. COM Port Information:

      Defect: When using the menu/ Program/Information and you don't have a COM Port in use the window will fail
      Propose: Avoid the Information window when loading multiple scripts
      Cause: while query available COM Ports an out of index exception occurs
      State: Solved
    

    2. Streams with File/Memory Stream:

      Defect: When using an array of byte an abstract error occurs
      Propose: Avoid the TStream as parameter, use TFileStream direct
      Cause: no overloading possible so the names are different - 
             procedure ReadAB(Buffer: TByteArray;Count:LongInt)');
             procedure WriteAB(Buffer: TByteArray;Count:LongInt)');
      State: Open
    

    3. Full Text Finder:

      Defect: When using on 64bit 120 dots per inch resolution the form is not size able
      Propose: Move the splitter up or down to size the window
      Cause: Panels are fix
      State: Open
    

    4. Button Set

      Defect: When using buttonset you have to name it each one
      Propose: Name the real set name
      Cause: sets are limited
      State: Open
    
      will not work: case CreateMessageDialog('Text the maXbox', mtWarning,[mbYesNoCancel]).ShowModal 
      works: case CreateMessageDialog('Text the maXbox', mtWarning,[mbYes,mbNo,mbCancel]).ShowModal 
               of  mrYes: ShowMessage('Yes');
                   mrNo: ShowMessage('No');
                   mrCancel: ShowMessage('Cancel');
               end;
    

    5. File Stream Buffer

      Defect: When using filestream buffer read/write (fs.WriteBufferInt(v, 2);)
      Propose: use string or FileS.WriteInt(Buff,1);
      Cause: Exception: Stream write error.
      State: Open
    

    6. High() of Enumerator and Set

      Defect: When using high(set) its always 255
      Propose: use 1 to n instead;
      Cause: invalid type cast
      State: Open
    
        suit:TShortSuit;   // TShortSuit=(CardS,CardD,CardC,CardH);
        for suit1:= low(TShortSuit) to high(TShortSuit) do  won't work
        for suit1:= 0 to 3 do begin
          cards0[4*(i-11)+suit1]:= TForm1_makecard(startx,starty,i,TShortSuit(suit1));
    

    7. Themes Color in Panel, Label, Bars etc.

      Defect: When set color in panel it inherits the parent color
      Propose: use controlstyle
      Cause: themes override the color
      State: Solved (with property ParentBackground)
    
    
      To set a color in a Panel or to override themes two ways are possible: - controlstyle set - 
      parentbackground:
      with mypanel do begin
         caption:= '********maXboxMP3********';  
         controlstyle:= controlstyle - [csParentBackground,csOpaque];
      mypanel:= TPanel.Create(self)
         with mypanel do begin
         ParentBackground:= false;
         color:= clyellow;
    

    8. Open other files with maXbox (Open with...)

      Defect: When you set maXbox as process to open a file with another extension it cant find it
      Propose: drag and drop the file you want to open
      Cause: it want to open and run the file at the same time
      State: In Work
    

    9. OpenProcessToken()

       if GetLastError = ERROR_NO_TOKEN then
            bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hAccessToken2);
      Defect: last parameter is not THandle
      Propose: set type of last parameter as DWord
      Cause: false interface
      State: In Work
    

    Performance

    Performance is dark chapter cause maXbox is an interpreter But it does have more functions precompiled than interpreted!

    As a comparison take the EightQueens Problem [8*8] You had to set 8 queens on a chessboard without collision {recursive solution to the Eight Queens problem} As a long time runner I set it to 14 Queens:

    \examples\044_pas_14queens_solwith14.txt

    Take the following reference implemantation for measures:

    http://www.softwareschule.ch/examples/044_queens_performer2.txt

    http://www.softwareschule.ch/examples/044_queens_performer2.htm

    Result: 365596 solutions Time: start is: 21:30:32:233 all codestrings of solutions stop is: 23:19:44:183 1 h run time: 49:11:950 � mX3 executed: 23.05.2014 23:19:44 Runtime: 1:49:13.10 Memoryload: 52% use

    file in editor: 6215131 lines Very slow but all solutions are painted in a file (94.7 MB (99'331'007 Bytes)) , e.g. the last solution one:

    365596

    XXXXXXXXXXXXXQ XXXXXXXXXXXQXX XXXXXXXXXQXXXX XXXXXXXQXXXXXX XXQXXXXXXXXXXX XXXXQXXXXXXXXX XQXXXXXXXXXXXX XXXXXXXXXXQXXX QXXXXXXXXXXXXX XXXXXQXXXXXXXX XXXXXXXXXXXXQX XXXXXXXXQXXXXX XXXXXXQXXXXXXX XXXQXXXXXXXXXX

    solution string: 14/12/10/8/3/5/2/11/1/6/13/9/7/4


    08 Queens: 92 solutions: 0 h run time: 00:00:376

    09 Queens: 352 solutions: 0 h run time: 00:01:493

    10 Queens: 724 solutions: 0 h run time: 00:06:460

    11 Queens: 2680 solutions: 0 h run time: 00:32:107

    12 Queens: 14200 solutions: 0 h run time: 02:58:011

    13 Queens: 73712 solutions: 0 h run time: 17:24:995

    Compiled solution with 14 Queens (365596 solutions) Intel Core 2 Quad (Q9559, 2.83 GHz) 9712ms!

    Tuning

    To speed up a script has following rules:

    1. Set the Application.ProcessMessages OFF:

    in menu Options/ProcessMessages

    or in code with processMessagesOFF; //more speed

    2. use internal functions instead of script functions:

    e.g. FileSearch('firstdemo.txt',exepath))

    3. Start a seconde instance of maXbox with F4

     

    Last edit: Max Kleiner 2017-03-20
  • Max Kleiner

    Max Kleiner - 2020-06-11

    Machine Learning Tutorials and Courses

    Learn Machine Learning online from the best machine learning courses/tutorials submitted & voted by the programming community.

     
  • Max Kleiner

    Max Kleiner - 2022-08-11

    Congratulations! maXbox has just been recognized with the following awards by SourceForge:

    Community Leader
    Open Source Excellence
    SourceForge Favorite

    These honors are awarded only to select projects that have reached significant milestones in terms of downloads and user engagement from the SourceForge community.

    This is a big achievement, as your project has qualified for these awards out of over 500,000 open source projects on SourceForge. SourceForge sees nearly 30 million users per month looking for, and developing, open source software. An award badge will now appear on your project page, and the award assets can be found in your project admin section.

    To recognize maXbox's achievement, we've awarded you with the aforementioned awards, which you can see below: Now that maXbox is an official winner of the these awards, you have express permission to use the award badges wherever you'd like.

    Feel free to proudly display the awards on your personal or organizational website, social media, or anywhere else you'd like.

     

Log in to post a comment.