Jump to content

aehimself

Members
  • Content Count

    1028
  • Joined

  • Last visited

  • Days Won

    22

Posts posted by aehimself


  1. In your browser it works because there are some JavaScript generating / fetching the data from somewhere else with your browser happily renders.

    You’ll need TEdgeBrowser or something similar to actually render it for you and then process the visible document.

    • Like 1

  2. 1 minute ago, Stano said:

    I have: amTranslationManagerInstall-2.0.8370.39904 - year 2019 
    So I went through it. I have understood/figured out where and how to get to the filters. How the filters and Find work.
    I searched for pumAutoIns from:

     

    LocNavigator unit;

    resourcestring
      pumAutoIns = 'Automatically insert the next record';

     

    Unfortunately, it's not there :classic_unsure:

    Resource strings are prefixed with the unit name they are in; so it should be named LocNavigator_pumAutoIns

    It must be there. Never met any resource string left out by BTM.


  3. Including the checks if a specific branch exists or not, you also can use the built-in System.Json unit:

    Var
      jo, coinmech: TJSONObject;
      recenum, tubeenum: TJSONValue;
      records, tubes: TJSONArray;
    begin
      jo := TJSONObject(TJSONObject.ParseJSONValue(Memo1.Text));
    
      If Not Assigned(jo) Then
        Exit;
    
      Try
        records := jo.GetValue<TJSONArray>('records');
    
        If Not Assigned(records) Then
          Exit;
    
        For recenum In records Do
        Begin
          coinmech := recenum.GetValue<TJSONObject>('coin_mech');
    
          If Not Assigned(coinmech) Then
            Continue;
    
          tubes := coinmech.GetValue<TJSONArray>('tubes');
    
          If Not Assigned(tubes) Then
            Continue;
    
          For tubeenum In tubes Do
          Begin
            WriteLn('Tube found, ID:' + tubeenum.GetValue<String>('tube_id'));
            // ...
            // Add a new record in a MemTable...?
          End;
        End;
      Finally
        FreeAndNil(jo);
      End;

    The code can be siplified significantly but this way you can see what is happening, how TJSONObject handling works. The code above produced the following output:

    image.thumb.png.840155cde934a6c0f89996b4cd61047f.png


  4. Short answer: never.

     

    Long answer: there are always code breaking changes in code or in protocols which will make older applications to be unable to communicate with never versions.

    This is why - if you really can not upgrade - we are using virtual machines with legacy OS-es hosting legacy applications.

     

    As ESXi is free you can also have your “museum” built this way but be aware that these legacy systems are usually extremely vulnerable to attacks in todays world.

    • Like 1

  5. I am using DCPCrypt in 64 bit applications without any issues but I remember that I had to dig for a package as there was one which didn’t compile.

     

    I’ll check later today which version I’m using and where exactly I downloaded it from.

     

    Edit: ReadMe simply say I'm too using v2 but I cannot find any reference to the sub version number. I still need to confirm this somehow but I think I'm using the SourceForge version.

     

    Do you have a code snipplet which fails to compile or it's the package itself?

     

    Edit-edit: my archive which has the source is called "dcpcrypt-code-r16-trunk.zip". So I'm pretty sure it's the SourceForge version 🙂


  6. 18 hours ago, TazKy said:

    I put the blame on DevExpress because I dislike the whole product and perhaps too quickly laid the blame on it.

    Thats very subjective, isn’t it? 🙂

     

    DevExpress indeed slows down Delphi - which is perfectly normal as it adds hundreds of components to the palette. But in my experience this only affects the load time of the IDE itself, not the appearance of your first form / unit on the screen!

     

    Which one you have an issue with?


  7. You simply can iterate through the members of the array, like:

     

    Var

      jval: TJsonValue;

      jarr: TJsonArray;

    begin

      // jarr := myJson.GetValue(‘drinks’) As TJsonArray;

      for jval in jarr do

         // …

    end;

     

    p.s.: sorry, I can not find how to format as code from my phone 😞


  8. On 7/31/2023 at 2:31 PM, 3ddark said:

    Can you explain with an example?

    Instead of “SELECT * FROM MyTable WHERE ID = 99” use “SELECT * FROM MyTable WHERE ID = :pID”, then assign the value 99 for the parameter named pID.

    • Like 1

  9. Minimum code I used is:

    procedure TForm1.FormCreate(Sender: TObject);
    Var
     windowstyle: Integer;
     appthreadid: Cardinal;
     cmdhandle: THandle;
    Begin
     cmdhandle := FindWindow('ConsoleWindowClass', 'Command Prompt');
    
     // Hide title bars and borders of launched application
     windowstyle := GetWindowLong(cmdhandle, GWL_STYLE);
     windowstyle := windowstyle - WS_CAPTION - WS_BORDER - WS_OVERLAPPED - WS_THICKFRAME;
     SetWindowLong(cmdhandle,GWL_STYLE,windowstyle);
    
     // Attach the container applications input thread to the launched ones, so that we receive user input
     appthreadid := GetWindowThreadProcessId(cmdhandle, nil);
     AttachThreadInput(GetCurrentThreadId, appthreadid, True);
    
     // Docking. Change the parent of the launched application
     WinApi.Windows.SetParent(cmdhandle, Self.Handle);
     SendMessage(Self.Handle, WM_UPDATEUISTATE, UIS_INITIALIZE, 0);
     UpdateWindow(cmdhandle);
    
     // Make the docked window fill all the client area of the container
     SetWindowPos(cmdhandle, 0, 0, 0, Self.ClientWidth, Self.ClientHeight, SWP_NOZORDER);
    
     // This prevents the parent control to redraw on the area of its child windows (the launched application)
     SetWindowLong(Self.Handle, GWL_STYLE, GetWindowLong(Self.Handle, GWL_STYLE) Or WS_CLIPCHILDREN);
    
    // SetForegroundWindow(WindowHandle);
    // SetFocus(WindowHandle);
    End;

    This does not take care of resizing the docked window if the form resizes and you also have to keep an eye on if / when your docked application closes. Also it includes no error checking / handling.

    The result is as expected:

     

    image.thumb.png.545c0e051c6aeed1e88584f4ff7d77ac.png

    • Like 1

  10. PING -t will continue to ping until you manually terminate it (usually Ctrl-C in your window). The code above does what it is told - read until the process ends; but the process will never die due to the -t switch.

    As your main thread is stuck in this loop you have but a handful of options:

    - Introduce a counter in the cycle. Exit the repeat-until cycle when the counter reaches a specific amount

    - Start a secondary thread before the loop, passing the process handle to it. The secondary thread can then kill the process at any time, causing the loop to break

    - You also can use a timer but you have to inject a message pump in your inner loop

    - Move this method to a thread and spam it across with "If Self.Terminated Then Exit". Start your thread and kill it any time from your main application with mythread.Terminate

     

    I'd go with option 4 as that is going to leave the UI useable during execution.


  11. SMComponents does that and their grid comes with many other interesting features while being as simple as possible. It's even free...!

    I almost ended up replacing my own DBGrid descendant with these when I had enough of tinkering around trying to fix it's issues 🙂


  12. 20 hours ago, Dave Nottage said:

    You'd need to typecast it to a TMemoryStream in order to do that, e.g:

    
    if LResponse.ContentStream is TMemoryStream then
      TMemoryStream(LResponse.ContentStream).SaveToFile(LFileName)
    // else the implementation has changed ;-)

     

    Yes, it is exposed as TStream, but internally it's a TMemoryStream if I recall correctly. So yes, typecasting is needed.


  13. 3 hours ago, egnew said:

    I am using a TNetHttpRequest component to retrieve text from a secure website.  I use the associated TNetHttpClient's OnAuthEvent to set the username and password.  This allows me to retrieve text into a string using IHTTPResponse.ContentasString.

     

    I need to retrieve files from the same secured website.  When I request the file using the same code, the IHTTPResponse.ContentStream seems to contain the requested file content since the IHTTPResponse.ContentLength appears to be correct.

     

    How can I save the content of IHTTPResponse.ContentStream to a file?

     

    Thanks

    AFFAIK it's a TMemoryStream, so you simply can call ContentStream.SaveToFile. You also can create a separate TFileStream and use .CopyFrom(ContentStream). just make sure position is 0 before calling .CopyFrom.

    • Like 1
×