Jump to content

Pat Foley

Members
  • Content Count

    367
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by Pat Foley


  1. I learned alot from Mike questions and answers.  Here's my stab at it.  

    program interSector;
    
    {$APPTYPE CONSOLE}
    {$R *.res}
    {$o+}
    
    uses
      System.SysUtils,
      System.Diagnostics,
      Classes;
    
    type
      // TsetOPs = (EditStr, ButtonStr, CheckStr, FormStr, FrameStr, ListBoxStr, PageControlStr, TabControlStr, RadioBtnStr, ComboBoxStr);
      TdbKey = (dateID, sqlID, CashID, EditID, ButtonID, CheckID, FormID, FrameID,
        ListBoxID, PageControlID, TabControlID, RadioBtnID, ComboBoxID);
      // : integer;
      TsetKeys = set of TdbKey;
    
    const
      cLoop = 100000000;
      cSet: TsetKeys = [dateID, CheckID, FrameID, ComboBoxID];
    
    var
      vSW: TStopwatch;
      vBool: boolean;
    
      procedure IsIntersected(const aID: integer; var aB: boolean);
      inline
      var
        Intersected: TsetKeys;
        Op: TdbKey;
      begin
        Intersected := [CheckID, FrameID, ButtonID] * cSet;
        aB := aB or (Intersected <> []);
        //for OPs in Intersected do to build relational DB
      end;
    
    begin
      vBool := false;
      vSW := TStopwatch.StartNew;
      var
        I: CppULongInt := 0;
    
      while I < cLoop do
      begin
        Inc(I);
        IsIntersected(I, vBool);
      end;
    
      Writeln(Format('IsIntersect = %5s', [vSW.ElapsedMilliseconds.ToString]));
    
      vBool := not vBool;
      readln;
    
    end.
    interSector.dpr.44: IsInterSected(I,VBool);
    000000000052B51F 89C1             mov ecx,eax
    000000000052B521 85C9             test ecx,ecx
    000000000052B523 7D05             jnl interSector + $6A
    000000000052B525 E8A611EEFF       call @BoundErr
    000000000052B52A 480FB70D1E010000 movzx rcx,word ptr [rel $0000011e]
    000000000052B532 66230D035B0200   and cx,[rel $00025b03]
    000000000052B539 803D5831030000   cmp byte ptr [rel $00033158],$00
    000000000052B540 750D             jnz interSector + $8F
    000000000052B542 663B0D09010000   cmp cx,[rel $00000109]
    000000000052B549 7504             jnz interSector + $8F
    000000000052B54B 33C9             xor ecx,ecx
    000000000052B54D EB02             jmp interSector + $91
    000000000052B54F B101             mov cl,$01
    000000000052B551 880D41310300     mov [rel $00033141],cl
    interSector.dpr.41: while I < cLoop do
    000000000052B557 81F800E1F505     cmp eax,$05f5e100
    000000000052B55D 72B6             jb interSector + $55
    000000000052B55F 90               nop

     

    • Like 3

  2. Use ActionManager as in design window and its property editors and sub editors adding stubs to be used like this to connect the events at runtime. 

     

    procedure TForm1.Button2Click(Sender: TObject);
    const
      popupmenuitemCaptions: array[0..1] of String=('Action4','frameAction1');
    var
      popupFrameCaption: string;
      I: Integer;
      A: TContainedAction;
    begin
      for popupFrameCaption in popupmenuitemCaptions do
    
        for I := 0 to ActionManager1.ActionCount - 1 do
        begin
          A := ActionManager1.Actions[I];
          if A.caption = popupFrameCaption then
          begin
            A.OnExecute := Frame11.PopupActionBar1.Items[0].OnClick;
            A.Execute;
            Break;
          end;
        end;
    
    end;
    object ActionManager1: TActionManager
      ActionBars = <
        item
          Items.CaptionOptions = coAll
          Items = <>
          ActionBar = ActionToolBar3
        end>
      LinkedActionLists = <
        item
          Caption = '(No Name)'
        end>
      Images = ImageList1 
      Left = 722
      Top = 172
      StyleName = 'Platform Default'
      object Action4: TAction
        Category = 'Frame'
        Caption = 'Action4'
        ImageIndex = 1
        OnExecute = Action4Execute
      end
      object DatasetFirst1: TDataSetFirst
        Category = 'Dataset'
        Caption = '&First'
        Hint = 'First'
        ImageIndex = 0
      end
    end

    Inspecting the object in design by copying it to notepad shows Images property to possibly set at runtime.  

     


  3. On 3/12/2022 at 2:08 AM, PaulD said:

    Basically, a user interface designed to launch a handful of applications such as a media player, map software, etc. It would use large buttons designed to be easy to use on a dash mounted touch-screen similar to a commercial car stereo.

    It would be easier to duct tape an iPad over the airbag and run the speakers thru blue tooth.

     

     

    Second way. third item.

    https://www.makeuseof.com/tag/projects-raspberry-pi-touchscreen-display/

     

    Third way. Delphi has a location demo for phone that works and ties into google maps.

    covers the map software.  25% of project would done.  Works on my present android phone.   

     

    Four.

    Finding screen size.

    https://stackoverflow.com/questions/1424920/how-do-i-get-the-usable-coordinates-of-the-screen-in-delphi

      

    to get the feel of embedded system Use the Task Manager to shut down Win Explorer.  You can restart from Task Manager using new task Explorer.

     

     

    • Haha 1

  4. 2 hours ago, Tom Chamberlain said:

    Maybe something to do with Marco's blog post from January 3rd, here.

    Actually Marco's post is between D11 to D10.4  PE flags updated to 6 to allow thinner borders and more margin.

     

    21 hours ago, perryhs said:

    window autosized perfectly to the size

    Try Autosizing False and Center True.  To center image on form set align = alClient.   That allows changing images readily.   


  5. If you stored the image in the image control.  Try this in 10.4

    • Select Image in Design window.
    • Bring up the Picture editor F11 for object inspector and click on ellipses ...
    • In the Picture editor save image as some thing else plus extension what it was.( .bmp .ping)
    • view the image with other app.
    • Other wise just delete the image control and install fresh one.

  6. Just as well run a Nick Hodges Nu 7 on it    Control-d  "to save time formatting"  if you spent the money for chain saw.

    procedure TForm1.serverExecute(AContext: TIdContext);
    var
      clients: tlist;
      i: integer;
      messaggioprelevato, FileName: string;
      FileStreamIn: TFileStream;
    begin
      messaggioprelevato := AContext.Connection.IOHandler.ReadLn;
      // send this magic string just before you send file stream
      if messaggioprelevato <> '!FILE#' then
      begin
        clients := Server.Contexts.LockList;
        try
          for i := 0 to connessi - 1 do
            TIdContext(clients.Items[i]).Connection.IOHandler.WriteLn
              (messaggioprelevato);
        finally
          Server.Contexts.UnlockList;
        end;
    
      end
      else
      begin
        // recv file stream
        TThread.Synchronize(nil,
          procedure
          begin
            showmessage('Arriva qualcosa...');
            FileName := 'C:' //suspect drive name in Windows
          end);
    
        FileStreamIn := TFileStream.Create(FileName, fmCreate);
        try
          AContext.Connection.IOHandler.ReadStream(aFileStreamIn);
        finally
          FileStreamIn.Free;
        end;
      end;
    end;

      

     

     


  7. What do the Objects look like IDE?

    Design copy from 10.4 

     

    // after fix

    object DateTimePicker1: TDateTimePicker
      Left = 280
      Top = 32
      Width = 186
      Height = 21
      Hint = 
        'Use<> arrow keys to select time field Up/Down arrow Keys to sele' +
        'ct new field value'
      Date = 44628.000000000000000000
      Format = 'dd/MMM/yyyy hh:mm:ss'
      Time = 0.690069409720308600
      DateFormat = dfLong
      ParentShowHint = False
      ShowHint = True
      TabOrder = 5
    end

     

    //Fresh

    object DateTimePicker2: TDateTimePicker
      Left = 64
      Top = 32
      Width = 186
      Height = 21
      Date = 44629.000000000000000000
      Time = 0.024456481478409840
      TabOrder = 6
    end


  8. Quote

    Give me six hours to chop down a tree and I will spend the first four sharpening the axe. Abe Lincoln

    That means to a painter read the directions on can One gallon to 100 square feet.  To a pilot ground school.  To a programmer a little knowledge is a dangerous thing--drink deep or drink not*. I try make a game of it, reading a chapter out of a book, write some code in notepad, and if runs without error I win big and even a few errors is a win when the coding structure is remembered readily. That how I sharpened my axe in the olden days now I use notepad++ 🙂    

     

    *A quote quoted in Pascal with Excellence.


  9. 59 minutes ago, MrCamarium said:

    procedure TForm1.serverExecute(AThread: TIdContext);

    Replace with magic overloaded procedure the compiler knows which to use with args passed.

    
    procedure serverExecute(AThread: TIdContext; const aFileName); overload;
    ...
    procedure TForm1.serverExecute(AThread: TIdContext; const aFileName);
    

    Add second overloaded procedure.

    59 minutes ago, MrCamarium said:
    
    /// in interface
    procedure ServerExecute(AContext: TIdContext; const AMessage: string); overload;
    ...
    Implementation
    procedure TForm1.ServerExecute(AContext: TIdContext; const AMessage: string);

     

     

    Never Merge when better to unravel!

     


  10. You are saying local variable names are prefixed with 'a' when your function is used?  That lets the person reading the code know what variables are to be touched outside the procedure.  That's better than marking the variables that are not touched outside a procedure with an L.    

     

    I think the Help insight control J s for summary is good.  It has better latency than the 

    Control Space business. 

     
     

        


  11. Just put the image you are using for the desktop into your program.

     

     

        double click on the form in the IDE to bring up FormCreate.

            set backgroundImage named imgAnimals with pix used for desktop image.

        

          You can use Panels for rendering your Boxes that have labels allready centered!

          

      imgAnimals := Timage.Create(Self)
      parent := Self;
      imgAnimals.align := alClient;
      imgAnimals.Picture.LoadFromFile(cAnimalPixPathed);
    
    
    (**above put this stuff.
    const
        cAnimalPixPathed = 'path and filename';
    var imganimals: TImage; //Put upstairs
      BoxLabels := TList<TPanel> **);
    
        {You move the panels in BoxLabels around with mouse then use show and hide as necessary.}  

     


  12. How about low code drap n drop using Delphi IDE and VCL.  

     

    Drop timage on the form

    Set the following form properties under F11 Key

      Color = clMoneyGreen
      TransparentColor = True
      TransparentColorValue = clMoneyGreen
     

    procedure TForm10.Timer1Timer(Sender: TObject);
    begin
      Image1.left := ScreenToClient(Mouse.CursorPos).X - Image1.width div 2;
      Image1.Top := ScreenToClient(Mouse.CursorPos).Y - Image1.Height div 2;
    end;

     

     


  13. How about mainunit and unit9 listing the DataModule named DM in this example.

     

    Button1Click in mainunit calls buildEmailList that has two tables as arguments. 

    Note in button1click the tables used are in DM.  

    in the buildEmaillList procedure only tables passed are used. 

     

    Button2Click should get you started. 🙂  

       

    //unit9
    //...
    //  TDM = class(TDataModule)
    //    MyTable: TFDMemTable;
    //    emailsTable: TFDMemTable;
    
    Uses unit9;
    
    procedure TForm8.buildEmailList(SourceTable, EmailTable: TfdmemTable);
    begin
      EmailTable.Open;
      SourceTable.Close;
    end;
    
    procedure TForm8.Button1Click(Sender: TObject);
    begin
      buildEmailList(DM.MyTable, DM.emailsTable);
    end;
    
    procedure TForm8.Button2Click(Sender: TObject);
    var
      bigtable: TFDMemTable;
      EmailsNeedtoSend: TFDMemTable;
    begin
      bigtable := DM.MyTable;
      EmailsNeedtoSend := DM.emailsTable;
    end;

     


  14. 56 minutes ago, Ian Branch said:

    Is it possible to create an alias for the datamodule/ttable?  i.e. instead of having to type 'Unit2.Mytable.FieldByName......' when calling it from Unit1, instead, something like 'U2MT.FieldByName.....'?

    Better to use reference...

    { Once instance is created you use references to it..
    
    procedure TForm5.Button1Click(Sender: TObject);
    var
      sourceDM: dm5.TDataModule6;
      dmLog: TStrings;
    begin
      dmLog := sourceDM.dm6log;
      //or just 
      dmLog := dm5.TDataModule6
      ...
    
    //in dm5's  TDataModule6 has stringlist for logging dm6log: Tstrings;

     


  15. Quote

    Not Found

    The requested URL /codeExamples/Sydney/en/DateUtils_(Delphi) was not found on this server.

     

     

    I guess 50% back.

     

    The accept cookie text should be another concern on viewing blog.  https://blogs.embarcadero.com/

     

    The cookie text reads 

    Quote

    We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept”, you consent to the use of ALL the cookies.

     

    Clicking on do not sell my personal information returns: "You really want to opt out."  Hopefully this is not implicit when using the help.   Since I have a subscription they have more personal information to sell. 

     

    • Like 1

  16. On 2/19/2022 at 11:59 AM, Dany Marmur said:

    function Name(const AArgument: TType); // Ouch!

    function Name(const aArgument: TType); // Yeah!!!

     

     

    Argument prefixed with vowel should be An if following an English style guide.

    I would use argArgument here.  Since argument is 3 syllable word passing

    3 syllable argument names help readability when procedure variables are not 3 syllable.

     

    L prefix or scoping would be used to avoid other similar named properties in UI. Like Width or Enabled.   

    Otherwise, L is not needed when arguments are prefixed with 'a' IMHO. 

     

    Short variable names. Longer Names
    input a,b,c.  Either preface with 'in', arguments allready done with arg.

    iterator i,j,k  Cap per current style.

    graphic w,h  scope with Rect

    output should be x,y,z; preface with 'out'.

     

     

     

     

      

     


  17. 12 hours ago, parallax said:

    But casting the output from MMFileToString using PAnsiChar, it worked fine, and I came down to 72 seconds on loading the big file.

    Not getting how that works?

     

    Using streaming appears to help reduce exe growth.

     

    // Lifted from Remy L DP post
    procedure TForm4.Button5Click(Sender: TObject);
    var
      //FS: TFileStream; //
      FS: TBufferedFileStream;  //saves a little
      Reader: TStreamReader;
      FN, data,
      s: string;
      eT, vLinesCounter: Int64;
    begin
      et := GetTickCount64;
      vLinesCounter:= 0;
      FN := 'C:\2022\2021VAERSData\2021VAERSDATAutf8.csv';   //lactually just changed all (?) to (') 87xxx of the things
      FS := TBufferedFileStream.Create(FN,fmOpenRead or fmShareDenyWrite);
      try
        Reader := TStreamReader.Create(FS);
        Try
          while not Reader.EndOfStream do
          begin
            StringGrid1.rows[vLinesCounter].StrictDelimiter := True;
            StringGrid1.rows[vLinesCounter].CommaText := Reader.ReadLine;
            Inc(vLinesCounter);
            if vLinesCounter mod 20000 = 0 then caption := vLinesCounter.tostring;
          end;
        Finally
          Reader.Free
        End;
      finally
        FS.Free;
      end;
      StringGrid1.rowcount := vLinesCounter + 3;
      eT := GetTickCount64 - eT;
      Caption := vLinesCounter.tostring + ' Records loaded to SG in ' + (eT/1000).tostring + ' seconds.';
    end;
    
    // For viewing cropped text in D
    procedure TForm4.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
    begin
      memo1.Lines.Text := StringGrid1.Cells[aCol, aRow];
    end;
    
    //New L code loads in 7 seconds
    procedure TForm1.Button3Click(Sender: TObject);
    var
      et: int64;
    begin
      if OpenDialog1.Execute then
        FN := OpenDialog1.FileName
      else
        exit;
      et := GetTickCount64;
      SG.LoadFromCSVFile(FN);   
      et := GetTickCount64 - eT;
      Memo1.lines.add(eT.tostring);
    end;

     

    va2022dataSGdx64.png


  18. Hey I had D in 32 platform switching up to 64 I able to load all data into StringGrid 🙂  

    You setting SG.rowcount to big Number.

     

    Running the L exe the UI hung at 300000 lines but kept going. Running the D64 exe it grew in size albeit slowly. 

     

    // D10.4.2 code runs 746,xxx in 42 seconds on i5 
    procedure TForm4.Button4Click(Sender: TObject);
    var
      FN: TextFile;
      Row: Integer;
      s: string;
      eT: int64;
    begin
      Row := 0;
      eT := GetTickCount64;
      AssignFile(FN, 'C:\2022\2021VAERSData\2021VAERSDATA.csv');
      Reset(FN);
      while not Eof(FN) do
      begin
        Readln(FN, s);
        StringGrid1.Rows[Row].StrictDelimiter := True;
        StringGrid1.Rows[Row].commaText := s;
        Inc(Row);
      end;
      eT := GetTickCount64 - eT;
      caption :=Row.tostring + 'records loaded in' + eT.ToString + ' Msecs';
    end;

     

     


  19. //Thanks to Ralph of team B old post
    function MMFileToString(const AFilename: string): string;
    var
      hFile:    THandle;
      hFileMap: THandle;
      hiSize:   DWORD;
      loSize:   DWORD;
      text:     string;
      view:     pointer;
    begin
      Result := '';
      if AFilename = '' then
        Exit;
      if not FileExists(AFilename) then
        Exit;
      // Open the file.
      hFile := CreateFile(PChar(AFilename),
                          GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL, 0);
      if hFile <> INVALID_HANDLE_VALUE then begin
        loSize := GetFileSize(hFile, @hiSize);
        // File was opened successfully, now map it:
        hFileMap := CreateFileMapping(hFile, nil, PAGE_READONLY, hiSize, loSize,
          'TextForString');
        if (hFileMap <> 0) then begin
          if (GetLastError() = ERROR_ALREADY_EXISTS) then begin
            MessageDlg('Mapping already exists - not created.', mtWarning, [mbOk], 0);
            CloseHandle(hFileMap)
          end
          else begin
            try
              // File mapped successfully, now
              // map a view of the file into the address space:
              view := MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
              if (view <> nil) then begin // View mapped successfully.
                CloseHandle(hFile); // Close file handle - as long is view is open it will persist.
                SetLength(Result, loSize);
                Move(view^, Result[1], loSize);
              end
              else
                MessageDlg('Unable to map view of file. ' +
                              SysErrorMessage(GetLastError),
                                 mtWarning, [mbOk], 0);
            finally
              UnmapViewOfFile(view); // Close view;
              CloseHandle(hFileMap); // Close mapping;
            end
          end
        end
        else begin
          MessageDlg('Unable to create file mapping. ' +
                       SysErrorMessage(GetLastError), mtWarning, [mbOk], 0);
        end;
      end
      else begin
        MessageDlg('Unable to open file. ' + SysErrorMessage(GetLastError),
                         mtWarning, [mbOk], 0);
      end;
    end;
    
    { TForm1 }
    //L has
    procedure TForm1.btnFixDateClick(Sender: TObject);
    var
      r, Cutoff: Integer;
      s: string;
    begin
      for r := 0 to sl.count - 1 do
      begin
        s := SG.Cells[1,r+1];
        Cutoff := length(s)-5;
        s := '2021/' + copy(s,1,Cutoff );
        SG.Cells[1,r+1] := s;
      end;
    end;
    
    //note need to set strictDelimiter each time. Delphi too.
    //for losing the "
    procedure TForm1.btnmapDataSGClick(Sender: TObject);
    var
      c,r,i: integer;
      et: int64;
    begin
      et := GetTickCount64;
      sl := TStringList.Create;
      sl.Capacity:= 750000;
      sl.text := MMFileToString('C:\2022\2021VAERSData\2021VAERSDATA.csv');
    
      c := sl.Count;
      for r := 0 to c -1 do
      begin
        SG.Rows[r].StrictDelimiter:= True;
        SG.rows[r].CommaText := sl[r];
        if r mod 5000 = 0 then btnmapDataSG.caption := 'r:' + r.ToString +  ' c:' + c.tostring;
      end;
      et := GetTickCount64 - et;
      memo1.lines[0] := format('done loading in %f',[et/1000]);
    end;
    //view cropped data in cell with memo. Delphi NA
    procedure TForm1.SGBeforeSelection(Sender: TObject; aCol, aRow: Integer);
    begin
      memo1.text := SG.Cells[aCol,aRow];
    end;

    Above is Lazarus code I was to only load 145000 lines in D or got 'out of memory errors' with bigger files 

    the L exe swells to 3500 when loading the data.  It loaded 748,xxx records in the SG in 12.78 seconds.   

     

    One could cut the file up with Notepad++ or excel 

    Or load a Tarray<recordwith38strings> reading the file in line by line. Making the commatext with arecord do format('%s1,...%38', [s1,..s38]); 

×