Jump to content

Remy Lebeau

Members
  • Content Count

    2333
  • Joined

  • Last visited

  • Days Won

    94

Posts posted by Remy Lebeau


  1. 9 hours ago, Cristian Peța said:

    I suppose you are using TXMLDocument. Then why not using TXMLDocument.LoadFromStream and TXMLDocument.SaveToStream and let the library do the encoding work for you?

    Agreed. XML carries its own encoding information, which any compliant parser must handle. So always pass raw bytes into an XML parser and let it work out the encoding, don't decode the bytes yourself. 

    • Like 1

  2. 7 hours ago, pcoder said:

    I believe Microsoft is aware of these and other challenges and has corrected globalSize(), but I have no proof.

    Is Raymond Chen's word not proof enough for you?

    Quote

    Bonus chatter: It appears that at some point, the kernel folks decided that these “bonus bytes” were more hassle than they were worth, and now they spend extra effort remembering not only the actual size of the memory block but also the requested size. When you ask, “How big is this memory block?” they lie and return the requested size rather than the actual size.

     


  3. 5 hours ago, softtouch said:

    TPythonModule of P4D

    THAT'S an important piece of information that was missing.

     

    Python4Delphi's MainModule is a function that returns a custom Variant holding a reference to Python's __main__ object.  A custom class named TPythonVariantType derived from Delphi's TInvokeableVariantType is used to allow such Variants to access properties and methods of the Python objects they hold.

     

    So, in your example, when you call MainModule.ClickElement_ByXPATH, the Delphi compiler emits code to pass the MainModule Variant to Python4Delphi's implementation of TPythonVariantType.DoProcedure() or TPythonVariantType.DoFunction() (depending on whether a return value is used or not) to invoke the "ClickElement_ByXPATH" function by name at runtime.

     

    So, to do what you are asking for, you could invoke TPythonVariantType.DoProcedure() manually, eg (UNTESTED!):

    uses
      ..., Variants, VarPyth;
    
    var
      custType: TCustomVariantType;
      v: Variant;
    begin
      // MainModule.ClickElement_ByXPATH();
      if FindCustomVariantType(VarPython, custType) then
      begin
        v := MainModule;
        custType.DoProcedure(TVarData(v), 'ClickElement_ByXPATH', nil);
      end;
    end;

     

     


  4. On 3/29/2024 at 8:10 AM, pcoder said:

    In my use case, the clipboard format, used in getClipboardData(format), refers to a MIME type (a file in memory).

    The clipboard reader needs to save each received stream to a file, which is easy if the file size is known. But interpreting every data format
    (more than 20 different MIME types) to find the correct file size is very cumbersome.

    Are you the one putting the data on the clipboard to begin with? If so, then why not store the required file size explicitly? If you can't put it in the MIME data itself, you can store it as a second format alongside the MIME data. The clipboard can hold more than one data item at a time.


  5. In case anyone is not already aware of this

     

    https://quality.embarcadero.com is now in a permanent read-only mode.  A new system is being implemented, but has not been opened to the public yet.  So, if you do have a legit bug/feature to report, feel free to post it in a public forum, or write to Embarcadero directly, and someone who has internal access to the new system can open tickets for you until the new system is ready for public use.

    • Thanks 4

  6. 16 hours ago, kvk1989 said:

    So this method work over the internet?

    No.  Using a share path only works on the local LAN network, and only if the file is exposed by the server to the LAN via a UNC share to begin with.  If you want to copy a file over the Internet, you need to setup a suitable TCP server for that, such as an HTTP or FTP server.

    • Thanks 1

  7. 4 hours ago, Angus Robertson said:

    Technically, https://test.com?test is an invalid URL, since there is no path included in the URL,

    That is not correct.  Technically, the path component is allowed to be empty in any url, per RFC 3986 sections 3 and 3.3:

          URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
    
          hier-part   = "//" authority path-abempty
                      / path-absolute
                      / path-rootless
                      / path-empty
          path-abempty  = *( "/" segment )
          path-absolute = "/" [ segment-nz *( "/" segment ) ]
          path-noscheme = segment-nz-nc *( "/" segment )
          path-rootless = segment-nz *( "/" segment )
          path-empty    = 0<pchar>

    RFC 2616 section 3.2.2 tried to restrict an HTTP url to require a non-empty absolute path if the query component is present:

    http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]

    But, RFC 2616 section 5.1.2 does allow the path in an HTTP url to be empty:

    Quote

    Note that the absolute path cannot be empty; if none is present in the original URI, it MUST be given as "/" (the server root).

    RFC 7230 sections 2.7.1 and 2.7.2 loosen the restriction to allow the path in HTTP and HTTPS urls to be empty:

         http-URI = "http:" "//" authority path-abempty [ "?" query ]
                    [ "#" fragment ]
         https-URI = "https:" "//" authority path-abempty [ "?" query ]
                     [ "#" fragment ]
    
    4 hours ago, Angus Robertson said:

    If you want to do it yourself, in THttpCli.DoRequestAsync change:

     

    if FPath = '' then FPath := '/';    to 

    if Pos('/', FPath) <> 1 then FPath := '/' + FPath;

    Why would you an inefficient "Pos" check instead of using something like StartsText() instead?  Or simply: "if (FPath = '') or (FPath[1] <> '/')" ?

    • Thanks 1

  8. 23 hours ago, bdw_nz20 said:

    I was hoping there was a simple Windows message the could be sent to trigger the DPI change to the application.

    Sorry, that is not how HDPI works.


  9. 21 hours ago, alogrep said:

    What do you mean by "debugging the RTL source code"?

    I meant exactly what I said.  You can turn on Debug DCUs in the project options, and then step through the RTL source code at runtime using the IDE's debugger.

    21 hours ago, alogrep said:

    My own code  here?

    No.

    21 hours ago, alogrep said:

    Or does that mean the RTL Dephi code?

    Yes.

    21 hours ago, alogrep said:

    If so, how can I find  where the thread failure happens? 

    There is only one place it fails - in the TThread.Create  constructor.  But at least you will be able to see the actual error code before the exception is raised (provided you can reproduce the problem at will), eg:

    constructor TThread.Create(CreateSuspended: Boolean; ReservedStackSize: NativeUInt);
    begin
      ...
        if FHandle = 0 then
          raise EThread.CreateResFmt(@SThreadCreateError, [SysErrorMessage(GetLastError)]); // <-- WHAT VALUE DOES GETLASTERROR RETURN HERE???
      ...
    end;

     


  10. 4 hours ago, giomach said:

    Is there a way to test for the existence of a remote file without actually trying to download it

    Yes - use TIdHTTP.Head() instead of TIdHTTP.Get().  A HEAD request is identical to a GET request except that no body data is sent, but the response headers will be the same.

    4 hours ago, giomach said:

    and importantly would that be quicker than what I'm doing, which is trying to download and checking whether the size is non-zero?  (I will treat a non-existing remote file and an existing file of zero size in the same way, so I don't need to distinguish those two cases.)

    A HEAD response will include the 'Content-Length' header, so yes, you can determine the file's size without actually downloading the file.

     

    However, if you are going to download the file anyway then there is really no point in checking for its existence beforehand, just download the file and handle whatever error may arise, such as HTTP 404 when the file does not exist.

    • Like 1

  11. It sounds like you disabled/uninstalled the Indy packages from the IDE.  Under the "Component" menu, choose "Install Packages", and make sure the 2 design-time packages dclIndyCore and dclIndyProtocols are installed and enabled.  If they are, then make sure your project's search paths are configured correctly.

    • Thanks 1

  12. 2 hours ago, alogrep said:

    Thanks Christian. So to know what is the error what should I do,  what should I have in

    EXCEOT

    ON E: ???

    It doesn't matter what you put in the 'except' handler, the information you are looking for has already been lost before the code gets that far.  If the error text is not already present in the raised Exception then there is no text to be retrieved.  What you should be focusing on is why the error text is not present in the Exception to begin with.  That would imply a bug in SysErrorMessage(), which the RTL calls when raising an EThread exception.  If the thread failed to create than GetLastError() should not be returning an error code that has no error text associated with it (however, after an exception is raised, GetLastError() is not guaranteed to be meaningful anymore).  So, I would suggest debugging the RTL source code when the thread failure happens and see what is really going on behind the scenes.  You should not be getting a blank error message.


  13. 35 minutes ago, davornik said:

    How to subclass TDateTimePicker's window on WM_MOUSE(DOWN|UP) messages?

    See Subclassing Controls on MSDN, and Safer subclassing on Raymond Chen's blog. For example:

    uses
      Winapi.CommCtrl;
    
    function CalendarSubclassProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM;
      uIdSubclass: UINT_PTR; dwRefData: DWORD_PTR): LRESULT; stdcall;
    begin
      case uMsg of
        WM_LBUTTONDOWN: begin
          TDateTimePicker(dwRefData).Format := '';
        end;
        WM_NCDESTROY: begin
          RemoveWindowSubclass(hWnd, @CalendarSubclassProc, uIdSubclass);
        end;
      end;
      Result := DefSubclassProc(hWnd, uMsg, wParam, lParam);
    end;
    
    procedure TForm1.DateTimePicker1DropDown(Sender: TObject);
    var
      cal: HWND;
    begin
      cal := DateTime_GetMonthCal(DateTimePicker1.Handle);
      SetWindowSubclass(cal, @CalendarSubclassProc, 1, DWORD_PTR(DateTimePicker1));
    end;

     

    • Like 1

  14. 4 minutes ago, davornik said:

    Yes, but it will then show something like 1899 year. DateTimePicker1.Date must be :=Date; is because it needs to be on today's date for user convinience, when calendar drops down - it is user frendly to have view of current month.

    Then you are just going to have to do what Peter suggested.  Just assume today's Date is the default unless the user selects a different date, or else use another UI element to specify when the default Date should be ignored.


  15. 16 minutes ago, davornik said:

    I dont want to use checkbox, because it is not user frendly.

    And yet, that is the way Microsoft wants you to use it.

    16 minutes ago, davornik said:

    Main problem is that OnChange event does not fire on every click on calendar but only if Date <> Today.

    If you really want to detect a mouse click, you will likely have to subclass the window for the TDateTimePicker's  drop down calendar to handle WM_LBUTTON(DOWN|UP) messages directly.


  16. 4 hours ago, PeterBelow said:

    If your requirements really need a way to detect that the user has entered a date you can use an additional TCheckbox that disables the picker unless it is checked.

    Or, use the TDateTimePicker.ShowCheckBox and TDateTimePicker.Checked properties instead.


  17. 5 minutes ago, Lajos Juhász said:

    Close can cause access violation if the form is prematurely freed. 

    Close() doesn't free the Form unless you explicitly ask for that behavior in its OnClose event (and even that, that logic uses Release() internally).

     

    In 20+ years using Delphi, I've never run into an AV from closing a Form. If you are getting an AV when closing a Form then you are likely mismanaging your code that uses the Form.


  18. 2 hours ago, Lajos Juhász said:

    The correct code would be:

     

    
    // OPEN INPUT SCREEN FOR BOR DOSSIER
                      try
                        inputCheckForm := Tfrm_InputCheck.Create(Self);
                        try
                          inputCheckForm.ShowModal;
                        finally
                          inputCheckForm.Free;
                          Release; // CLOSE THE CURRENT INPUT FORM
                        end;
                      except
                        on E: Exception do
                          DoShowException(E);
                      end;
     

    https://docwiki.embarcadero.com/Libraries/Athens/en/Vcl.Forms.TCustomForm.Release

    Release() destroys the Form that it is called on. Whereas Close() merely closes (hides) the Form, allowing it to be reopened (shown) again at a later time if desired. 

×