Jump to content

Serge_G

Members
  • Content Count

    311
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Serge_G


  1. On 7/25/2021 at 3:52 PM, Henry Olive said:

    I saw there are 2 grids (Grid,String Grid)  in Fmx, which one should i use instead of my vcl dbgrid ? 

    My preference goes to Grid rather than StringGrid, but I prefer a ListView 

     

    22 hours ago, sjordi said:

     If you VCL forms are very complex, I think you'd better off starting from fresh with an FMX clean form: that also could be a good opportunity to re-think your forms and GUI.

    Agree sjordi, VCL components are poor if you compare. i.e a VCL app use Tpanel,  a FMX app will use Layout or TRectangle  


  2. IMHO if your listview only have items not resized  you can use ScrollViewPos property and perhaps the ScrollViewChange event 

     

    var first, last : integer;
    begin
    first:=Trunc(listview1.ScrollViewPos/listview1.ItemAppearance.ItemHeight);
    Last:=First+Trunc(ListView1.Height/listview1.ItemAppearance.ItemHeight);
    memo1.lines.add(Format('First %d Last %d',[first,last]));

    If you have a TSearchbox visible I think it's easy to take care of it (using Searchbox unit to get the height)

     

    If you have groups or variable height items this should be harder but still using ScrollViewPos I think it's playable, you "just" have to calc from top, cumulate all  items height  till reaching ScrollViewPos for first and ScrollViewPos+ListView.Height for last


  3. Hi,

    Well, logic, yes.  

    Depending on the REST API server function. 

    On another side a TListview (livebinded) for only 10 records a VerticalScrollbox filled by code should be a good alternative,

    IMO getting previous page and next page (30 records) during thread process should be better

    • Like 1

  4. Hi

    Sorry but, I think we don't play in the same playground.

    For me, a TListView is used with Livebindings to fill it with data coming from a data source (table, query or list of Object). You use it like a TListBox!

    With a TListBox it's easy to put in a style whatever you want (in this case a text and a progress bar).

     

    By the way, your code is more for this kind of component,

    • Create a style (layout, ttext, progressbar)

    just to adapt your code in the    "for FR in FArray do" loop

    • set the style of the created item  item.stylelookup:='mystyleprogress'
    • insert an item.applystylelookup
    • change access to the objects of the item

     

     

    • Like 1
    • Thanks 1

  5. Hi, if you mean something like this

    image.thumb.png.b134d2bac71da5e025c9064e1bf7886f.png

     

    (my first try) I use this code
     

    unit UnitProgess;
    
    interface
    
    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes,
      System.Variants,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
      FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base,
      Data.Bind.GenData, System.Rtti, System.Bindings.Outputs, FMX.Bind.Editors,
      Data.Bind.EngExt, FMX.Bind.DBEngExt, Data.Bind.Components,
      Data.Bind.ObjectScope, FMX.ListView, Fmx.Bind.GenData;
    
    type
      TForm18 = class(TForm)
        ListView1: TListView;
        PrototypeBindSource1: TPrototypeBindSource;
        BindingsList1: TBindingsList;
        LinkListControlToField1: TLinkListControlToField;
        procedure ListView1UpdateObjects(const Sender: TObject;
          const AItem: TListViewItem);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
    
    var
      Form18: TForm18;
    
    implementation
    
    {$R *.fmx}
    
    procedure TForm18.ListView1UpdateObjects(const Sender: TObject;
      const AItem: TListViewItem);
    var
      pBitMap: TBitmap; // for further purpose
      pListItemImage : TListItemImage;
    begin
      if AItem.Purpose = TListItemPurpose.None then
      begin
        pListItemImage:=AItem.Objects.FindObjectT<TListItemImage>('ProgressBar');
        if assigned(pListItemImage) then
         begin
          pListItemImage.Bitmap.Width:=400-(abs(PrototypeBindSource1.DataGenerator.FindField('intfield1').GetTValue.AsInteger)*10);
          pListItemImage.Bitmap.Clear(Talphacolors.RED);
         end;
    end;
    
    end.

    Quick designed

    image.thumb.png.3f36fb3f28c416e308a3902bf300068d.png

     

    But I shall investigate more because this "version" need a link to (bitmap1 -> Item.ProgressBar)
    I was enabled to add a bitmap directly (PlistItemImage is unassigned if there is no link)

    • Thanks 1

  6. 45 minutes ago, Vandrovnik said:

    In design time: could you just copy whole imagelist and then delete unneeded images from it?

    Take in mind that in the another imagelist (let say the source one)  I have various images and the goal is to have the destination list filled with only one of these. 

    I found the problem deeply looking in the code used in the helper. (helper I merged) 

    uses FMX.MultiResBitmap;
    
    procedure TForm18.Button1Click(Sender: TObject);
    const
      SCALE = 1;
    var
      pBitmap : TBitmap;
      sbitmap : TCustomBitmapItem;
      vSource: TCustomSourceItem;
      vBitmapItem: TCustomBitmapItem;
      vDest: TCustomDestinationItem;
      vLayer: TLayer;
    begin
      Images.ClearCache;
      Images.BeginUpdate;
      if Images.Destination.Count > 0 then
        Images.Destination.Clear;
      vSource := ImageList1.Source.Items[0];
      sbitmap := vSource.MultiResBitmap.ItemByScale(SCALE, True, True);
      pbitmap:=TBitmap.Create(100,100);
      try
        for var l := 0 to 3 do
          for var c := 0 to 3 do
          begin
            var
              r: TRect := TRect.Create(100*c,100* l,
                                       100*c+100,100*l+100);
              pBitmap.CopyFromBitmap(sbitmap.Bitmap, r, 0, 0);
    
             // add source bitmap
              vSource := Images.Source.Add;
              vSource.MultiResBitmap.TransparentColor := TColorRec.Fuchsia;
              vSource.MultiResBitmap.SizeKind := TSizeKind.Source;
              vSource.MultiResBitmap.Width := Round(pBitmap.Width / SCALE);
              vSource.MultiResBitmap.Height := Round(pBitmap.Height / SCALE);
              vBitmapItem := vSource.MultiResBitmap.ItemByScale(SCALE, True, True);
              if vBitmapItem = nil then
              begin
                vBitmapItem := vSource.MultiResBitmap.Add;
                vBitmapItem.SCALE := SCALE;
              end;
              vBitmapItem.Bitmap.Assign(pBitmap);
    
              vDest := Images.Destination.Add;
              vLayer := vDest.Layers.Add;
              vLayer.SourceRect.Rect := TRectF.Create(TPoint.Zero,
                vSource.MultiResBitmap.Width, vSource.MultiResBitmap.Height);
              vLayer.Name := vSource.Name;
          end;
      finally
        pBitmap.Free;
      end;
      Images.EndUpdate;
    end;

    And now I can play

    Capture.PNG

    • Thanks 1

  7. Hi

    I am trying to split an Image stored in a first TImageList into a second TImageList

     

    all my attempts to access a multiresbitmap contained in a TImagelist show an error on program exit

      TImageListHelper = class helper for TImageList
        function Add(aBitmap: TBitmap): integer;
      end;
    
    var
      Form18: TForm18;
    
    implementation
    
    {$R *.fmx}
    
    uses FMX.MultiResBitmap;
    
    procedure TForm18.Button1Click(Sender: TObject);
    var
      sbitmap, pBitmap: TBitmap;
      vSource: TCustomSourceItem;
      vBitmapItem: TCustomBitmapItem;
      vDest: TCustomDestinationItem;
    
    begin
      Images.ClearCache;
      Images.BeginUpdate;
      if Images.Destination.Count > 0 then
        Images.Destination.Clear;
      vSource := ImageList1.Source.Items[1];
      vBitmapItem := vSource.MultiResBitmap.ItemByScale(1, True, True);
      sbitmap := vBitmapItem.Bitmap;
      pBitmap := TBitmap.Create(100, 100);
      try
        for var l := 0 to 3 do
          for var c := 0 to 3 do
          begin
            var
              r: TRect := TRect.Create(pBitmap.Width * c, pBitmap.Height * l,
                pBitmap.Width * c + pBitmap.Width, pBitmap.Height * l +
                pBitmap.Height);
            pBitmap.CopyFromBitmap(sbitmap, r, 0, 0);
            Images.Add(pBitmap);
          end;
      finally
        pBitmap := nil;  // if not an EAccessViolation exception raised when program close
        pBitmap.Free;
      end;
      Images.EndUpdate;
    
    end;
    
    
    { TImageListHelper }
    
    function TImageListHelper.Add(aBitmap: TBitmap): integer;
    const
      SCALE = 1;
    var
      vSource: TCustomSourceItem;
      vBitmapItem: TCustomBitmapItem;
      vDest: TCustomDestinationItem;
      vLayer: TLayer;
    begin
      result := -1;
      if (aBitmap.Width = 0) or (aBitmap.Height = 0) then
        exit;
    
      // add source bitmap
      vSource := Source.Add;
      vSource.MultiResBitmap.TransparentColor := TColorRec.Fuchsia;
      vSource.MultiResBitmap.SizeKind := TSizeKind.Source;
      vSource.MultiResBitmap.Width := Round(aBitmap.Width / SCALE);
      vSource.MultiResBitmap.Height := Round(aBitmap.Height / SCALE);
      vBitmapItem := vSource.MultiResBitmap.ItemByScale(SCALE, True, True);
      if vBitmapItem = nil then
      begin
        vBitmapItem := vSource.MultiResBitmap.Add;
        vBitmapItem.SCALE := SCALE;
      end;
      vBitmapItem.Bitmap.Assign(aBitmap);
    
      vDest := Destination.Add;
      vLayer := vDest.Layers.Add;
      vLayer.SourceRect.Rect := TRectF.Create(TPoint.Zero,
        vSource.MultiResBitmap.Width, vSource.MultiResBitmap.Height);
      vLayer.Name := vSource.Name;
      result := vDest.Index;
    end;

    AccessViolation if pbitmap:=nil is omitted

    >>EAccessViolation exception in module taKinFMX.exe in 00008338

    >>Violation of access to the address 00408338 in the module 'taKinFMX.exe'. Reading of the address FFFFFFFC.

    ...
    >> The instruction at 0x0000000000408338 uses the memory address 0x00000000FFFFFFFC. Memory state cannot be read.

     

     

    and cause Unexpected Memory Leaks
    An unexpected memory leak has occurred. The unexpected small block leaks are:

     

    29 - 36 bytes: TD2DBitmapHandle x 1, TBitmapImage x 1

    45 - 52 bytes: TBitmap x 1

    61 - 68 bytes: Unknown x 1

     

    Where does I go wrong ?

    Is there another way to split (like during design time) an image ?


  8. 8 minutes ago, EdwardG said:

    Thank you for your information. I also reported it as a bug yesterday. Did not notice it was an old one.

     

    Good thing to report it another time because I don't know if EMB report RSP of a version to another one (hope so but ...), even if you should have a "closed : duplicate case" (I'm used to this kind of response  when I report one):classic_wacko:
     

    Quote

    You know, I found Delphi is a little buggy right now. IDE crashes or AV sometimes. 

    Yes, there are quite some but decreasing (even if I don't use 10.4 for production, I should make another try with 10.4.2 when I'll be a little less busy).

    My idea for IDE crashes : LSP is a good thing but need memory, more than 4Mo I recommend 8 minima (I will soon make my HP laptop open-heart surgery to 16 I think)

    Quote

    It was my favorite years ago.

    Still mine, and now I am a FMX, LiveBindings fan, all my new desktop pro applications (even if Windows only) are FMX, but the first steps were hard!  

     


  9. Hi,

    For me, filter expressions complies only with the old LocalSQL of BDE so no STARTS nor CONTAINING.

    Usually, I don't use tables, only querys to avoid this problem, and some Query data components have the good idea to offer macros to manage this sort of case    


  10. I should not be so affirmative. 

    @MarkShark it's a FMX.TListView not a VCL one.

    @Michele If you think : style of an item like for a FMX.TListBox, yes you can't  change Item style. You can only change Appearance and only use one for all the list, The Dynamic appearance is one of the most adaptable.

    if you think : changing background colors you can

    image.thumb.png.194916b3d4a6ed916981102ab9d402ae.png

     

    You can see above a personalized style, quick done, I only change itembackground.Color and buttontext.Color (listviewappearance = ImageListItemRightButton)

     


  11. 22 minutes ago, Mikheil said:

    Where / how to I put the TQuery? On the Form or in the DataModule?

    It's a "business layer" so I should say DataModule and perhaps TDataSource on Form

    Agree with haentschman but "Like" can't be "parametrized".


    Anyway you have the macro solution https://www.devart.com/mydac/docs/devart.dac.tcustomdadataset.macros.htm

    So your query should be like this Select * from <tablename> &where

    and the code

    and this should respond your second interrogation (you can even use a macro for table name :classic_wink:

    22 minutes ago, Mikheil said:

    The next thing is how to allow the user to select which field(s) to query, so that I can construct the SQL? 

    Query.SQl.Text := 'select Bla from Bubb &where'
    Query.MacroByName('where').AsString := Format('WHERE FIELD1 LIKE %s AND FIELD2 LIKE %s',[QuotedStr('%'+value1+'%'),QuotedStr('%'+value2+'%')]);
    Query.Open;

  12. 10 hours ago, TELOS KIM said:

    When you set up live binding on the grid, set up the column header portion of the design, and compile Android, the column header option is not saved in the design.Request confirmation.

    Hi,

    I was afraid of, but no, I wrote a quick test (I don't use Grid  often) and my conclusion is : no problem found.

     


  13. 11 hours ago, Dany Marmur said:

     And Emba has announced that FireDAC will be "Enterprice" exclusive in the future (please correct me if i am wrong, you all).

    Really ? IMHO, This would be a bad idea, if Firedac was not with Pro and Community (with no source is acceptable).

    Another pack of free component is ZEOSLIB (also named ZEOSDBO), also BDE Like, can be installed on Community Edition  


  14. 3 hours ago, jdg said:

    Firstly - I would appreciate any recommendations on books that do a good job explaining how to use the database components in 10.4 please.

    The best book I think about is Delphi in Depth : Firedac by Cary Jensen

     

    3 hours ago, jdg said:

    Secondly - what are your preferred database components?  I've been experimenting with IB components. 

    If your aim is FireBird don't use IB Components, well and even for Interbase Firedac is better.

    Firedac is BDE like so the step between D4 and D10.4 is not so large (for this point and with Firedac)

    3 hours ago, jdg said:

    At this time I'm primarily interested in local client data interface

    Ok, so in this case, should I suggest to use SQLite and a GUI like SQLite Studio

     


  15. 3 hours ago, emailx45 said:

    another thing, DONT FORGET OF "RE-MAP" by FireDAC options!

    there, you can do it too!

    Include the definition have an "inherit" "VERTICAL", or be, definining on FDManager -> FDConnection -> FDQuery ... and so!

    Then, you can re-map a Field on FDConnection, and all FDQuerys/FDDatasets will inherit it 

    try this.

     

    image.png.13009ad3b3edd8353cf4aad1f9b02a3a.png

     

    hug

    I try this before Dmitry response, but does not work at design time for declaring fields (keep in mind : Livebindings)

    Thanks anyway.

     

    Is there anyway to flag discussion as solved on this forum?

    • Like 1

  16. Well, I was thinking it was a sort of VCL vs FMX thing but no.

    If I look at your grid I see that resultmult column is as string (align left)

    Like me have a widestringfield

        object FDQuery1MNT: TWideStringField
          AutoGenerateValue = arDefault
          FieldName = 'MNT'
          Origin = 'MNT'
          ProviderFlags = []
          ReadOnly = True
          Size = 32767
        end

    And this is my problem, if you use Livebindings a real one at design time!

     

    A note for this function

    // Select id,montant,sens,
    // testmnt(sens,montant) as MNT, --  function1
    // asIntvalue(sens) as IntSens, -- function2   
    // montant*asIntvalue(sens) MNTBIS from ecritures
    
    procedure TForm11.FDSQLiteFunction2Calculate(AFunc: TSQLiteFunctionInstance;
      AInputs: TSQLiteInputs; AOutput: TSQLiteOutput; var AUserData: TObject);
    begin
    try
    if AInputs[0].AsString='+'
      then AOutput.AsInteger:=1
      else AOutput.AsInteger:=-1;
    except
      Aoutput.AsInteger:=0;
    end;
    end;

    if you declare fields at design time you have a widestringfield, no fields declared it is a largeint value and MNTBIS a currency value

    image.png.50b11012dfb184252e0c1ae75d2f1ca1.png


  17.  

     

    48 minutes ago, emailx45 said:

    why convert the Float in Str, and Str in Float again?

    Well, there was a mistake in the database :classic_blush: , column  aInput[0] is a string in French format so with " ," as decimal point

    aInput[1] if a char '+' or '-'. Don't fire at the pianist, that's not my database!

     

     In the same way, the format of the date

    vDate:=EncodeDate(StrToInt(Copy(vsdate,1,4)),
                      StrToInt(Copy(vsdate,5,2)),
                      StrToInt(Copy(vsdate,7,2)));

    I am in doubt because of base 0,1 string and, yes, I forgot the StrToDateTimeDef

    but problem remains.

    I exposed my problem with the first fuction

    procedure TDM.FDSQLiteFunction1Calculate(AFunc: TSQLiteFunctionInstance;
      AInputs: TSQLiteInputs; AOutput: TSQLiteOutput; var AUserData: TObject);
    begin
    // from sample  
    AOutput.AsCurrency := AInputs[0].AsCurrency * AInputs[1].AsInteger;
    end;

    And this one, see second picture, give me a widestring not a currency field

     


  18. Hi,

    I am surely doing something wrong there, but I can't understand where.

     

    I wrote a FDSQLiteFunction (well more than one)

    image.png.7b8011fa775a515f3c9cc02c5ee22094.png

    All of these return me widestrings, I was expecting  Currency, Date, Currency. 

    Note, first one came from help http://docwiki.embarcadero.com/CodeExamples/Sydney/en/FireDAC.SQLite_Sample

    procedure TDM.FDSQLiteFunction1Calculate(AFunc: TSQLiteFunctionInstance;
      AInputs: TSQLiteInputs; AOutput: TSQLiteOutput; var AUserData: TObject);
    begin
    // from sample  
    AOutput.AsCurrency := AInputs[0].AsCurrency * AInputs[1].AsInteger;
    end;
    
    procedure TDM.FDSQLiteFunctionAAAAMMJJ2DateCalculate(
      AFunc: TSQLiteFunctionInstance; AInputs: TSQLiteInputs;
      AOutput: TSQLiteOutput; var AUserData: TObject);
    var vSDate : String;
        vDate : TDate;
    begin
    vsDate:=AInputs[0].AsString;
    vDate:=EncodeDate(StrToInt(Copy(vsdate,1,4)),
                      StrToInt(Copy(vsdate,5,2)),
                      StrToInt(Copy(vsdate,7,2)));
    AOutput.AsDate:=vDate;
    end;
    
    procedure TDM.FDSQLiteFunctionMontantCalculate(
      AFunc: TSQLiteFunctionInstance; AInputs: TSQLiteInputs;
      AOutput: TSQLiteOutput; var AUserData: TObject);
    var vMontant : Currency;
        IMontant : String;
    begin
     IMontant:=AInputs[0].AsString;
     Vmontant:=StrToFloat(IMontant);
     if Ainputs[1].AsString='-'
        then vMontant:=Vmontant * -1;
     AOutput.AsCurrency:=vMontant;
    end;

    image.png.2abf4b0ab66c2ddc47a486d54c8f62e2.png

     

    Don't understand why! Ok, it's at design time, but I think that matters.


  19. Hi,

     

    This one

    UPDATE CUSTOMER SET COUNTRY =
      Case
         When COUNTRY='USA' then :MYCOUNTRY
         When COUNTRY <> 'USA' then COUNTRY
      End

    should be replaced by

    UPDATE CUSTOMER SET COUNTRY='USA' WHERE COUNTRY=:MYCOUNTRY;

     

    And this

    UPDATE EMPLOYEE SET TAXBASE=
        Case 
          When SHAREHOLDER='Y' then (BRUTSALARY * :EMPPORTION /100) * :TMONTH
    
       End                             
    end 

    by

    UPDATE EMPLOYEE E SET E.TAXBASE=E.BRUTSALARY*:EMPORTION/100)*:TMONTH WHERE E.SHAREHOLDER='Y';

     

×