Jump to content

Remy Lebeau

Members
  • Content Count

    2338
  • Joined

  • Last visited

  • Days Won

    95

Everything posted by Remy Lebeau

  1. Can you provide a concrete example of such a difference?
  2. Why are you using Base64 at all? REST runs over HTTP, and HTTP handles binary data without needing to encode it.
  3. You should also set the bInitialOwner parameter to False in the CreateMutex() call. You don't need ownership of the mutex just to create it and test for its existence. You can then remove the call to ReleaseMutex() as well.
  4. Remy Lebeau

    Call for Delphi 12 Support in OpenSource projects.

    Embarcadero already has private channels/forums available for its beta testers and MVPs/TPs.
  5. Just note that WideString is very inefficient in general, since it is an ActiveX/COM string type managed by the OS, not the Delphi RTL. But you also said a lot of your strings are UTF-8, and you can't store UTF-8 in a WideString. But you can use UTF8Encode()/UTF8Decode() to convert strings between UTF8String and WideString as needed. I doubt it, and if I'm not mistaken, TNT isn't even around anymore. Not to mention it is largely unnecessarily anyway, as the core Delphi classes are now Unicode capable since 2009. So many/most of the TNT classes you are using can be replaced with the native RTL/VCL counterparts (TForm, TListBox, TStringList, etc). Hard to say without seeing your actual code, and what kind of workarounds you are using. You can still use ASM coding in modern Delphi, although 64bit does have some additional restrictions on its usage.
  6. Possibly. Depends on the context in which it's being used. In any case, if you need UTF-8 strings, you should use the native UTF8String type instead of AnsiString (even in Delphi 7, you should have been doing that). If you must use UTF8 encoded AnsiString in D2009+, at least use SetCodePage() to make sure the CP_UTF8 (65001) codepage is assigned to its data. UTF8String and UnicodeString are assignment-compatible in D2009+, the RTL will automatically convert between them without any data loss (in Delphi 7, you would have had to use the UTF8Encode()/UTF8Decode() functions for that). At least with SetCodePage(), you can make sure not to lose any data if a UTF8 encoded AnsiString is assigned to a UnicodeString (the reverse is not true, though).
  7. Already covered on StackOverflow: https://stackoverflow.com/questions/77326298/trouble-inserting-text-value-into-html-input-with-twebbrowser-evaluatejavascript
  8. None of that has anything to do with migrating from 32-bit to 64-bit. Only with migrating from ANSI to Unicode. You can still use the ANSI types in 64-bit code if you need to, albeit more explicitly than before.
  9. Remy Lebeau

    C++ / windows.h and data alignment

    Didn't say there is one. From the get go, the discussion has been about compiling with <windows.h> in general, and how Microsoft doesn't force the alignment but Embarcadero does. Yes, a shame (FreePascal does). Even Marco agreed it would be a useful feature to add, but they still haven't added it yet.
  10. Remy Lebeau

    C++ / windows.h and data alignment

    That header is modified by Embarcadero, as evident by the check for __CODEGEARC__. Microsoft doesn't care about checking for CodeGear/Embarcadero compilers. The question is, what does Microsoft's native SDK version of the header look like?
  11. Remy Lebeau

    Use of dynamic control names

    That "works" but may be overkill, as you would potentially be iterating through a lot of other controls that you are not interested in.
  12. Remy Lebeau

    Use of dynamic control names

    Don't do that! You are invoking undefined behavior. You can only iterate using a pointer like that if the values are in an array, Otherwise, you can't be sure the compiler is not adding padding between them inside the class. If you want to use a pointer to iterate the members, you have to put them into an array first and iterate that instead.
  13. Remy Lebeau

    Searching Edit component with autocomplete for Directory/Files

    Ah. No, it does not. In that case, you would indeed need a custom enumerator.
  14. Remy Lebeau

    C++ / windows.h and data alignment

    I would just stick with using the <pshpack#.h>/<poppack.h> headers, since they support multiple compilers, and will use #pragma pack(push) if the compiler supports it. I have never seen that warning before when using #pragma pack directly. But then, I don't ever wrap the standard Win32 headers with it, either. I doubt it, but anything is possible, I guess. You will have to review the headers for yourself.
  15. Remy Lebeau

    Searching Edit component with autocomplete for Directory/Files

    Why implement a custom IEnumStrings class for directories/files? There is already a pre-made data source provided by the OS for that exact purpose - CLSID_ACListISF, which can be created with CoCreateInstance(), configured via IACList2::SetOptions(), and then passed to IAutoComplete::Init().
  16. Creating a COM object to run a process won't bypass the AV if it is looking for process creations. That will just add more overhead to the app that is wanting to create the processes. Unless the AV ignores COM objects that run elevated, which would be pretty risky. Besides, it's not really possible for an AV to determine whether a process creation is occurring inside a COM object vs an application anyway. I think your IT is acting stupid, but that is just my opinion. Do you really need to run an external process on every file? What is the new process doing exactly that you can't do directly inside your own app with an equivalent library?
  17. Remy Lebeau

    Send basic email not working for me

    My example assigns the TIdSMTP object as the Owner of the SSLIOHandler object. When the TIdSMTP object is freed, it will free the SSLIOHandler object for you. This is a memory management mechanism that is implemented by all TComponent descendants. If you want to free the object yourself, you certainly can do so, eg: procedure SendTestEmail2; var SMTP: TIdSMTP; SSLHandler: TIdSSLIOHandlerSocketOpenSSL; Message: TIdMessage; begin try SMTP := TIdSMTP.Create(nil); try SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil); try SSLHandler.SSLOptions.SSLVersions := [sslvTLSv1_2]; // and/or sslvTLSv1, sslvTLSv1_1, etc. SSLHandler.SSLOptions.Mode := sslmClient; SMTP.IOHandler := SSLHandler; SMTP.Host := 'smtp.gmail.com'; SMTP.Port := 465; // or 587, depending on your server SMTP.UseTLS := utUseImplicitTLS; // or utUseExplicitTLS, depending on your server SMTP.Username := 'UserName'; SMTP.Password := 'Pass'; Message := TIdMessage.Create(nil); try Message.From.Address := 'men@gmail.com'; Message.Recipients.EMailAddresses := 'grantful@yahoo.com'; Message.Subject := 'Test Subject'; Message.Body.Add('Test message.'); SMTP.Connect; try SMTP.Send(Message); finally SMTP.Disconnect; end; finally Message.Free; end; finally SSLHandler.Free; end; finally SMTP.Free; end; except on E: Exception do begin ShowMessage('Error: ' + E.Message); end; end; end; It is customary to assign a nil Owner when you want to free an object yourself. But it is safe to manually free an object that has an Owner assigned, as the freed object will simply remove itself from its Owner to avoid being freed again. Are you debugging your app on those platforms to see what is actually going on? Which line of code is actually raising those errors?
  18. Remy Lebeau

    C++ / windows.h and data alignment

    On 32bit systems, as well. Using the Windows Headers What structure packing do the Windows SDK header files expect?
  19. Remy Lebeau

    C++ / windows.h and data alignment

    Yes - 8 bytes Because the Windows SDK is old and predates those headers? I don't know. Not sure if the original SDK headers do this, but In Embarcadero's copy of windows.h and other SDK headers, there are actually #pragma statements to setup 8-byte alignment, eg: #pragma option push -b -a8 -pc -A- /*P_O_Push*/ ... #pragma option pop /*P_O_Pop*/ The -a8 parameter is the alignment. Yes, and most VCL headers have #pragma statements for that purpose, eg: #pragma pack(push,8) ... #pragma pack(pop)
  20. Remy Lebeau

    Send basic email not working for me

    Look at that code very carefully. You have commented out the creation of an SSLHandler object, but then are accessing its members. Crash. And, if that one line were not commented out, you would then be creating a 2nd SSLHandler object and assigning it to the same variable, leaking the 1st object. You need to fix your object creation. This is not specific to Indy, this is a fundamental issue to how Pascal/OOP programming works in general. You have to create an object before you can use it. Now, after fixing that, your code has another problem - SMTP port 465 is an implicit TLS port, but you are setting the TIdSMTP.UseTLS property to utUseExplicitTLS. SMTP port 587 is the explicit TLS port. Use utUseImplicitTLS for port 465, and utUseExplicitTLS for port 587 (and optionally 25). Try this: procedure SendTestEmail2; var SMTP: TIdSMTP; SSLHandler: TIdSSLIOHandlerSocketOpenSSL; Message: TIdMessage; begin try SMTP := TIdSMTP.Create(nil); try SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(SMTP); SSLHandler.SSLOptions.SSLVersions := [sslvTLSv1_2]; // and/or sslvTLSv1, sslvTLSv1_1, etc. SSLHandler.SSLOptions.Mode := sslmClient; SMTP.IOHandler := SSLHandler; SMTP.Host := 'smtp.gmail.com'; SMTP.Port := 465; // or 587, depending on your server SMTP.UseTLS := utUseImplicitTLS; // or utUseExplicitTLS, depending on your server SMTP.Username := 'UserName'; SMTP.Password := 'Pass'; Message := TIdMessage.Create(nil); try Message.From.Address := 'men@gmail.com'; Message.Recipients.EMailAddresses := 'grantful@yahoo.com'; Message.Subject := 'Test Subject'; Message.Body.Add('Test message.'); SMTP.Connect; try SMTP.Send(Message); finally SMTP.Disconnect; end; finally Message.Free; end; finally SMTP.Free; end; except on E: Exception do begin ShowMessage('Error: ' + E.Message); end; end; end;
  21. Remy Lebeau

    Obfuscating secrets

    That is not a good idea. Store them outside of the exe (config file, database, etc), and secure them with encryption, etc in case they need to be changed over time. If a hacker has access to your exe, all bets are off. Nothing stops a competent hacker from discovering the memory blocks your app is using and just pull the login values directly from that memory as soon as your app uses it.
  22. Remy Lebeau

    How do I execute code after FormShow ?

    That is what the WM_APP range, and RegisterWindowMessage(), are meant for instead. Yes, it is perfectly safe to use the WM_USER range for your own messages within your own window.
  23. Remy Lebeau

    Minimizing Forms

    FYI, your manual setting is not guaranteed to be persistent. The Form's Handle CAN be recreated dynamically during the Form's s lifetime, which would lose your manual setting. If you want to customize the Form's owner window, you need to override the Form's CreateParams() method so your manual value takes affect on every HWND that the Form creates, eg: type TMyContestForm = class(TForm) ... protected procedure CreateParams(var params: TCreateParams); override; ... end; procedure TMyContestForm.CreateParams(var params: TCreateParams); begin inherited CreateParams(params); params.WndParent := 0; // or GetDesktopWindow() end;
  24. Remy Lebeau

    Minimizing Forms

    A VCL owner and an API owner are two completely different things. The VCL's owner manages object lifetime. The API's owner manages window display and Z-ordering. Did you perhaps forget the 'override' directive on the declaration of CreateParams() in the TMyContest class? type TMyContest = class(TForm) ... protected procedure CreateParams(var params: TCreateParams); override; ^^^^^^^^^ ... end; The Create() and CreateNew() constructors are just to create the TForm object. The CreateParams() method is called by the TWinControl.Handle property getter whenever the HWND window is being created at the API level. TForm object construction and HWND window creation are two different things.
  25. Remy Lebeau

    Minimizing Forms

    It is a bit more complicated than that. The owner window that is used at the API level depends on many factors, like if the TForm has a Parent or PopupParent assigned, or the MainForm window or the currently active TForm window may be used depending on the TForm's PopupMode. If the VCL decides the MainForm should be used, it will do so only if TApplication.MainFormOnTaskbar is True and the MainForm window has already been allocated, otherwise the TApplication window is used instead. Even then, there are TApplication.OnGetActiveFormHandle and TApplication.OnGetMainFormHandle events which allow the app to override the VCL's decision and use a different window of the app's choosing. See the implementation of TCustomForm.CreateParams(), there is a lot of decision-making going on in that method to decide which owner window to use.
×