Jump to content

Davide Angeli

Members
  • Content Count

    107
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by Davide Angeli


  1. 2 hours ago, programmerdelphi2k said:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      x: TMyThread;
    begin
      x := TMyThread.Create;
      try
        // x.Start; // if suspended...
      finally
        x.Free;
      end;
    end;

    You can't destroy the thread object until it's finished... It doesn't even have time to start.

     

    Maybe you have to do something like this:

     

    var
      x: TMyThread;
    begin
      x := TMyThread.Create(False);
      try
        // x.Start; // if suspended...
        WaitForSingleObject(X.Handle, INFINITE);
      finally
        x.Free;
      end;
    end;

     

     

     

    • Like 3
    • Thanks 1

  2. I used JSON superobject for a while and it's good but in cases like this I prefer the very good Delphi NEON library so I could deserialize the JSON directly to Delphi objects. With NEON in a case like yours I could do something like this:
     

    Type
      TVoice = record
      public
        Engine : String;
        VoiceId : String;
        VoiceGender : String;
        // .. other fields 
      end;
    
      TVoicesData = record
      public
        voices_list : TArray<TVoice>;
        count : Integer;
      end;
    
      TVoices = record
      public
        success : Boolean;
        data : TVoicesData;
      end;
    
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      var sJson:=
      '{'+
      '  "success": true,'+
      '  "data": {'+
      '      "voices_list": ['+
      '          {'+
      '              "Engine": "neural",'+
      '              "VoiceId": "ai2-Stacy",'+
      '              "VoiceGender": "Female",'+
      '              "VoiceWebname": "Stacy",'+
      '              "Country": "US",'+
      '              "Language": "en-US",'+
      '              "LanguageName": "English, US",'+
      '              "VoiceEffects": ['+
      '              ]'+
      '          },'+
      '          {'+
      '              "Engine": "neural",'+
      '              "VoiceId": "ai1-Matthew",'+
      '              "VoiceGender": "Male",'+
      '              "VoiceWebname": "Matthew",'+
      '              "Country": "US",'+
      '              "Language": "en-US",'+
      '              "LanguageName": "English, US",'+
      '              "VoiceEffects": ['+
      '                  "news"'+
      '              ]'+
      '          }'+
      '      ],'+
      '      "count": 50'+
      '  }'+
      '}';
    
      var Voices:=DeserializeValueTo<TVoices>(sJson);
      for var Voice in Voices.data.voices_list do
          ListBox1.Items.Add(Voice.Engine+' - '+Voice.VoiceGender);
    
    end;
    
    function TForm1.DeserializeValueTo<T>(const aJSON : String): T;
    begin
      if FNeonConfig=Nil then FNeonConfig:=TNeonConfiguration.Default;
      var LJSON := TJSONObject.ParseJSONValue(aJSON);
      try
        var LReader:=TNeonDeserializerJSON.Create(FNeonConfig);
        try
          var LValue:=LReader.JSONToTValue(LJSON, TRttiUtils.Context.GetType(TypeInfo(T)));
          Result:=LValue.AsType<T>;
        finally
          LReader.Free;
        end;
      finally
        LJSON.Free;
      end;
    end;

     

    • Like 2

  3. In my case 10.4 was terrible, fortunately 11.2 seems working well (I'm using only VCL win32 & win64).

     

    At the moment, I've not installed the patch 1.0 because after several years of frustration I've finally a stable environment and I'm terrified of breaking it again!


  4. 13 minutes ago, balabuev said:

    I cannot agree with that. Moreover, 10.4 has a way to disable LSP in favor of old code insight engine.

    LSP is the minor problem of 10.4, you can also disable it if you want. The fact of closing the IDE every 15 minutes, in my case, is due to the continuous internal errors, access violations in dcc32 and so on that were fixed in 11.2.


  5. As far as my usage context is concerned, version 11.2 is a big step up from 10.4. I'm switching from one to the other working on two different projects and 10.4 is truly absolute crap in terms of stability. 11.2 isn't perfect but it has improved a lot of things. In my case when LSP no longer works, now in 11.2 it is always a solution to switch from debug / release or from win32 / win64 (for me these workarounds don't work in 10.4 and the only solution remain close/reopen IDE).

     

    I've been using 11.2 for several weeks now and the IDE has crashed only a couple of times (a strange Access Violation and one internal error). For me it is a dream to be able to work even for 4 hours straight without crashing! When I come back to 10.4 I have to close and reopen the IDE at least once every 15 minutes and the LSP is totally unusable...


  6. 2 minutes ago, David Heffernan said:

    I though we were talking about the cause of the access violations in your code. But if I've misunderstood, I'm sorry. 

    No problem!

     

    Discover the cause of the acces violation could be maybe a good exercise for some Windows api guru. I've dedicated it some hours yesterday trying to change the way to declare the parameters of the api but I could not reach a solution. I've tried several combinations even going against what is stated in the api documentation. There is something strange tha I'm missing on that api because the totalentries out parameter is always a non sense value called in win64. In win32 works as apected. So maybe there is something not documented in the Windows api or maybe, as that api si considered very old, maybe the win64 part could be buggy (just a my guess) or maybe could be something wrong using it from a Delphi win64 program (I've tested it both 10.4.2 and 11.2 but the problem is the same).


  7. 2 hours ago, David Heffernan said:

    Perhaps somebody else wants to debug your large and complex code. But if you made a minimal reproduction and posted it here I'd expect a better chance of engagement. 

    I know that my english is terrible but I suppose you have misunderstood the reason of this topic. I'm not looking for someone to debug my super beatiful large and complex code written in the better way possible and bla bla... As I wrote, I've already solved the problem with the workaround that I have posted (it's not the best solution but it works) and now with @Lars Fosdal kind answers I also could try other modern ways to reach my goal (like AD apis).

     

    I wrote this topic if could help somebody having the same issue. If this kind of topics are not accepted here I'll be careful not to do it again. Sorry


  8. 3 hours ago, David Heffernan said:

    ResumeHandle should be PDWORD_PTR. Probably other types are declared incorrectly. Check all declarations against the header files. 

     

    Ask yourself which is more likely. Is it a bug in your code, or a bug in the Windows code? 

    1. The code I posted is not my code. I took that example on stackoverflow here: https://stackoverflow.com/questions/34870232/list-all-users-of-an-ad-group-in-delphi. I post it just to provide a quick example that leads to the same error that I'm eperiencing (that's the reason why I posted the zip file with the project ready to test...). My code is more complex (I need more information about that api so I used anoother data structure). In my project I'm using JclWin32 to call that api and there the function is declared like this:
      function NetGroupGetUsers(servername, groupname: LPCWSTR; level: DWORD; var bufptr: PByte; prefmaxlen: DWORD; entriesread, totalentries: LPDWORD; ResumeHandle: PDWORD_PTR: NET_API_STATUS;
      The result is the same.
       
    2. Are you so sure that Windows is bug free? My code run smootlhy for at least a couple of years on a Windows 2019 server with hundreds of domain users. On that server were locked the Windows updates for a while because one of them created problems accessing via RDP. Last week we unlock the updates and boom! That piece of code now raises the access violation for which we are discussing. Sure it could be a coincidence.
       
    3. According to Microsoft documentation the declaration of that api is this one (see more at https://learn.microsoft.com/en-us/windows/win32/api/lmaccess/nf-lmaccess-netgroupgetusers)
      NET_API_STATUS NET_API_FUNCTION NetGroupGetUsers(
        [in]      LPCWSTR    servername,
        [in]      LPCWSTR    groupname,
        [in]      DWORD      level,
        [out]     LPBYTE     *bufptr,
        [in]      DWORD      prefmaxlen,
        [out]     LPDWORD    entriesread,
        [out]     LPDWORD    totalentries,
        [in, out] PDWORD_PTR ResumeHandle
      );
      and JclWin32 declaration seems correct but compiling it Win64 raises that AV.
      So it's a bug of JclWin32 code or a bug in Windows? I dont know

     


  9. 12 minutes ago, Lars Fosdal said:

    The 64-bit simply refuses to run, unless I run it elevated.

    Then I get

    Yes I'm working as admin so I can run without elevation. I suppose you have several users in the domain so it need to call the api more than one time and on second call you get AV. It is the problem for which I started this topic. If you use the MAX_PREFERED_LENGHT version (comment/uncomment instructions)  does it work? For me yes and some weeks ago worked also the original version..


  10. 3 hours ago, Lars Fosdal said:

    Windows 10, 64-bit

    Compile to 32-bit target - runs as expected

    Compile to 64-bit target - unable to create process

    I'm compiling it both 32bit and 64bit and they work both here.

    I'm on Windows 10 64bit with Delphi 11.2.

     

    The 64bit compiled exe I've tested also on Win11 (22H1) and on WinServer 2019 and Winserver 2022 and it works everywhere.

     

     


  11. 3 hours ago, David Heffernan said:

    Would be nice to look at code directly in the post rather than have to download some ZIP file

    {$WARN SYMBOL_PLATFORM OFF}
    
    program DomainGroupGetUsersTest;
    
    {$APPTYPE CONSOLE}
    
    uses
      SysUtils, Windows, Classes;
    
    const
        netapi32lib = 'netapi32.dll';
    
    type
        PGroupUsersInfo0 = ^TGroupUsersInfo0;
        _GROUP_USERS_INFO_0 = record
          grui0_name: LPWSTR;
        end;
        TGroupUsersInfo0 = _GROUP_USERS_INFO_0;
        GROUP_USERS_INFO_0 = _GROUP_USERS_INFO_0;
    
        NET_API_STATUS = DWORD;
        LPBYTE = ^BYTE;
    
    function NetApiBufferFree (Buffer: Pointer): NET_API_STATUS; stdcall;
                                                               external netapi32lib;
    function NetGroupGetUsers (servername: LPCWSTR; groupname: LPCWSTR;
        level: DWORD; var bufptr: LPBYTE; prefmaxlen: DWORD; var entriesread: DWORD;
        var totalentries: DWORD; ResumeHandle: PDWORD): NET_API_STATUS; stdcall;
                                                               external netapi32lib;
    
    function DomainGroupGetUsers (const sGroup: WideString;
                                  const UserList: TStrings;
                                  const sLogonServer: WideString) : Boolean;
    { "sLogonServer" must be prefixed with "\\".
      "sGroup" must contain the group name only. }
    
    type
        TaUserGroup = array of TGroupUsersInfo0;
    
    const
        PREF_LEN = 1024;
    //    MAX_PREFERRED_LENGTH = DWORD(-1);
    
    var
        pBuffer : LPBYTE;
        i : Integer;
        Res : NET_API_STATUS;
        dwRead, dwTotal, hRes : DWord;
    
    begin
        Assert (sGroup <> '');
        Assert (sLogonServer <> '');
        Assert (UserList <> NIL);
    
        UserList.Clear;
        Result := true;
        hRes := 0;
    
        repeat
            writeln('hres = '+IntToStr(hRes));
    
    //        Res := NetGroupGetUsers (PWideChar (sLogonServer), PWideChar (sGroup),
    //                                 0, pBuffer, MAX_PREFERRED_LENGTH, dwRead, dwTotal,
    //                                 PDWord (@hRes));
            Res := NetGroupGetUsers (PWideChar (sLogonServer), PWideChar (sGroup),
                                     0, pBuffer, PREF_LEN, dwRead, dwTotal,
                                     PDWord (@hRes));
    
    
            writeln('dwRead = '+IntToStr(dwRead));
            writeln('dwTotal = '+IntToStr(dwTotal));
    
            if (Res = Error_Success) or (Res = ERROR_MORE_DATA) then
            begin
                if (dwRead > 0) then
                    for i := 0 to dwRead - 1 do
                        with TaUserGroup (pBuffer) [i] do
                            UserList.Add (grui0_name);
    
                NetApiBufferFree (pBuffer);
            end { if }
            else Result := false;
        until (Res <> ERROR_MORE_DATA);
    end; { DomainGroupGetUsers }
    
    
    var
        UserList : TStringList;
        iIndex : Integer;
    
    begin
        UserList := TStringList.Create;
    
        try
            DomainGroupGetUsers ('Domain Users', UserList,
                                 GetEnvironmentVariable ('LOGONSERVER'));
    
            for iIndex := 0 to UserList.Count - 1 do
                WriteLn (UserList [iIndex]);
    
        finally
            UserList.Free;
        end; { try / finally }
    
        if (DebugHook <> 0) then
        begin
            WriteLn;
            Write ('Press [Enter] to continue ...');
            ReadLn;
        end; { if }
    end.

     


  12. Hi all, this is not directly Delphi related, just want to share if anyone will experience something like this.

     

    I'm using NetGroupGetUser api (from netapi32.dll) to retrive names and data of the domain users. It worked well for a while, but now (maybe some recent Windows Updates), in win64 applications, it returns me strange results or access violations. Same code compiled in Win32 instead always worked fine. Attached is a sample that I've found online (stackoverflow) that I'm using to do some tests. The original program was designed to retrieve data in buffers (1024byte). Doing that, in my case, if users number exceeds the buffer, the second call of NetGroupGetUser raise an access violation in samlib.dll (running on a Windows 2019 server). I've solved calling the api once using MAX_PREFERRED_LENGTH (=DWORD(-1)) instead of the original 1024 byte buffer size. I could not find documentation about differences in declaring the api for win32 or win64... It seems some kind of mess with the api parameters in 64 bit or a bug of 64bit version of netapi32.dll.

    TestDomainUserConsole.zip


  13. I've installed 11.2 quite a few days ago upgraded from 11.1 (smooth upgrade without problems with web installer).

     

    Til now I have only recompiled/updated some of third party libriaries and do a little stuff for a couple of half days on the future release of my main app (in this moment I'm working heavily on the older project still on 10.4.2). 

     

    Til now I worked without IDE crashes and this is good news for me! On same project on 10.4.2 (but also with 11.0 and 11.1) the IDE crashes all time with various internal errors)! I'll stress the new IDE in the next days but in my way of use it seems definitly more stable.

    • Like 3

  14. On 9/14/2022 at 4:22 PM, Zoran Bonuš said:

    Should be fixed in 11.2 (I haven't tested yet)

    Hi, I've installed 11.2 quite a few days ago upgraded from 11.1 (smooth upgrade without problems with web installer).

     

    Til now I have only recompiled/updated some of third party libriaries and do a little stuff for a couple of half days on the future release of my main app (in this moment I'm working heavily on the older project still on 10.4.2). 

     

    I don't know if this issue is definitly solved but I worked without IDE crashes and this is good news for me (on same project on 10.4.2 the IDE crashes all time with this issue and other internal errors)! I know that it's not a complete/valide test. I'll stress the new IDE in the next days but it seems definitly more stable.


  15. Just update to 11.2 and also for me works as aspected.

    I experienced too this problem in some forms in the previous versions (very rare). When happen I cut/paste the event piece of source at the unit end, then save and the empty event disappear as aspected.


  16. 6 hours ago, Tom F said:

    What tools are you using to show the SVG files?

    As I wrote in the previous post, when I migrated to SVG there was no plenty of tools like now.

     

    I started with RiverSoftSVG component library and I based my internal libraries on that. In my applications, before SVG, I used PNG stored in resource files and loaded at runtime in TPngImageLists (it was all dinamic something like I'm doing now with SVG). To do a progressive migration I used RiverSoft to render SVG as PNG to mantain the same structure. RiverSoft was good enough to render material icons but has limitations on complex SVG so at the same time I used Delphi SVG (very good library it uses DirectX) to render complex logos and big SVG images. Now I've replaced Delphi SVG with Skia4Delphi and I'm planning to replace also RiverSoftSVG with it making Skia my internal reference for images and animations.

     

    Starting for scratch I think I will evaluate SVGIconImageList and maybe I will use it in the future because it has a similar approach to mine. When I started, I tested it but it was very crude and terrible in rendering certain icons. Now it has evolved exponentially and if I'm not mistaken now you can choose also Skia as SVG rendere engine. 

     

    Skia and SVGIconImageList are open source, RiverSoftSVG and DelphiSVG are commercial tools.

     

     

    • Like 1

  17. I solved these issues abandoning tradional icons (BMP,PNG) to SVG. I started too from Google Material Design SVG icons but with a different approach because I needed icons not present in these libraries (some I drew, others I took from other online free libraries). So now I've several SVG sprites (some Google MD some customized) all designed 24x24 with black as the main color and I pick images from these sprites (for buttons, imagelists etc). SVG are pure XML so it's not difficult to change on the fly size or color (you have just to change an xml attribute or xml node), so, when I need SVG for dark theme or I need to use the sysop accent color I just change black stuff in the desired color. For me now is easy to reach something like this:

     

    svgsamples.thumb.png.b1046cf4b5b758f2b9cda93e2dcae811.png

    I started these "revolution" on my apps about 4 years ago to approach both HIDPI monitors and dark mode and it was quite a lot of work; in that period SVG it wasn't as fashionable as now so I had to build some internal components myself to do this job. Now it seems that there are even opensource solutions that help to solve these problems.

     

    SVG is scalabale and is a text file. I don't like EMB approach of virtual image lists in which you have to provide several rastered icons for different sizes: Material desing base icons are 24x24 so if my app is 100% zoomed it uses this size, if the zoom is 150% ii switches to 36x36, if the zoom is 357% it uses 85x85 and so on, so the SVG images are rendered always of correct size for every zoom applied.

     

    I've categorized all my SVGs and each of them has a name like "confirm", "cancel", "exit", "print" etc. I've inerithed the components in which I need SVG stuff (buttons, images, ecc) adding a property in which I provide at design time just the SVG name and then all is solved at runtime as the program needs (style, size, zoom etc). In this way if I want to change/update an image  I just modify the SVG sprite.

     

    • Like 1

  18. I develop only VCL for Windows and my target are almost exclusively Win10 e Win11 (and Win2012 server+). Windows 7 practically disappeared from my customer PCs and Windows 8 never appeared.

     

    In my scenario I'm happily using styles: with latest Alexandria 11.x EMB provide at least 4 default VCL styles HIDPI compliant 2 for Win10 and 2 for Win11 (2 = light + dark). I decide in real time the style to use based on the SysOp and the user's choice to use the light or dark theme of Windows and I get an acceptable result and an UI compliant with that of the SysOp. Without styles in VCL its impossibile to create dark apps.

    • Like 4

  19. On 7/19/2022 at 7:35 AM, Davide Angeli said:

    Summurized in few words like Anders do it seems not really complicated. I will try it.

    Already using git for internal use, it is actually very easy to interface with github. In a few minutes, following the advice, I was able to create a pull request containing some corrections that I had made locally and I saw that they have also already been integrated into the master branch by obones :classic_smile:.

×