Jump to content

Remy Lebeau

  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by Remy Lebeau

  1. Remy Lebeau

    Which Objects Allow ActiveControl?

    Only windowed controls (TWinControl descendants) can receive input focus, and thus be assigned as an ActiveControl. TLabel is a graphical control (TGraphicControl descendant), not a windowed control. If you need a windowed text label, use TStaticText instead of TLabel. TBitBtn is a windowed control. All windowed controls support that. All components, visual and non-visual, support that. The reason that doesn't work for you is most likely due to OS theming. So turn off theming on the button. Or, use a 3rd party button that allowed custom coloring. Or, just owner-draw the button yourself manually. I don't think any standard controls support vertical alignment, only custom-drawn controls can do that. All controls support that. For controls that are just wrappers for standard OS controls (like TButton), that behavior is controlled by the user's system settings, not by the framework. Most controls support that. Even if the event is not exposes, it still exists in all controls. Why are you posting this in a Delphi forum and not in the Lazarus forums? https://forum.lazarus.freepascal.org
  2. Remy Lebeau

    Which Objects Allow ActiveControl?

    Then why is this being posted in a Delphi forum and not in the Lazarus forums? https://forum.lazarus.freepascal.org
  3. RFC 3659 Well, not just undocumented, but implementation-defined. Servers can (and do) use whatever format they want for LIST.
  4. Remy Lebeau

    Common code base for VCL and FMX control code

    Is your component visual (derived from TControl)? Or is it non-visual (derived from TComponent)? Non-visual components can be used in both VCL and FMX without splitting up the implementation (just IFDEF the pieces you need). But visual controls take more work to design for separate frameworks. Then those lines should be in separate units. The rest of your code should be in a common unit(s) that the framework-specific units can then use. This is where Unit Scope Names come into play. Create separate VCL-specific and FMX-specific projects with appropriate Unit Scope Names specified in the Project Options, and then don't use any Unit Scope names in your code. That way, you have less IFDEF'ing to do. Your common gtDocumentPrinter code should be in its own separate unit, not in an include file. All the more reason not to use an include file.
  5. Remy Lebeau

    Smaller custom component between design & Running mode

    Probably because the IDE is not HighDPI-aware, so it gets stretched by the OS. It wasn't necessary to show EVERYTHING, most of that code is not related to painting.
  6. Remy Lebeau

    Smaller custom component between design & Running mode

    You are going to have to show your actual painting code. The fundamentals of painting controls haven't changed over the years (certainly newer APIs - ie theming - have been added, but that is secondary). Your old painting code should still be functioning the same way it always did.
  7. Setting the Text property replaces the ENTIRE contents of the Memo. If you want to APPEND a line to the EXISTING text, use the Lines.Add() method instead, eg: Memo1.Lines.Add(lineoftext); In which case, your entire loop can be replaced with a single LoadFromFile() instruction, eg: procedure TForm1.Button4Click(Sender: TObject); begin Memo1.Lines.LoadFromFile('Test.txt'); end; Or, if you want to append the entire file to the end of the EXISTING text, do what Lars Fosdal showed you - load the file into a TStringList first, then you can AddStrings() that into the TMemo. If you really want to manually loop through a text file line-by-line, consider using the TStreamReader class instead of old-style Pascal file I/O. TStreamReader has a ReadLine() method (and in Delphi, it supports Unicode text encodings), eg: procedure TForm1.Button4Click(Sender: TObject); var FS: TFileStream; Reader: TStreamReader; begin FS := TFileStream.Create('Test.txt', fmOpenRead or fmShareDenyWrite); try Reader := TStreamReader.Create(FS); try while not Reader.Eof do begin lineoftext := Reader.ReadLine(myFile); Memo1.Lines.Add(lineoftext); end; finally Reader.Free; end; finally FS.Free; end; end;
  8. Both of my PCs at home are old Dells, running XP and Win7, and they both have BIOSes that support scheduling power events on weekdays only. So they both power up before I start a work day, and as long as I shut them down cleanly (ie, not by holding down the power button, which I do have to do sometimes) then they power up correctly on the next weekday. No weekend runs, unless I leave them powered on Friday night (for backups, etc).
  9. Here is a response I saw on another forum with a similar question:
  10. The only way your worker threads could be causing the UI to lag is if they are making the UI thread wait for lengthy periods of time, such as by synchronizing with the UI thread, submitting large amounts of asynchronous notifications to the UI thread, not yielding to the CPU so the UI thread gets starved for CPU time, etc. But without seeing your actual code, it is hard to say for sure why your UI is lagging. That is what the debugger is meant for.
  11. Remy Lebeau

    FastMM4 and option "AlwaysClearFreedMemory"

    No, it is not, because AlwaysClearFreedMemory is a compile-time {$define}, not a runtime variable (like ReportMemoryLeaksOnShutdown is, for instance). It is processed only when FastMM4.pas is being compiled. There was a feature request made 2 years ago asking for AlwaysClearFreedMemory to be configurable at runtime. It is still open: #51 Feature request regarding option "AlwaysClearFreedMemory" Then don't do such things on strings/interfaces containing sensitive data. And do use things like the CryptProtectMemory(), CryptUnprotectData(), and SecureZeroMemory() functions to secure the sensitive data in memory while you are not actively using it.
  12. Remy Lebeau

    Highlight a specific popup menu item?

    I simply mean that properly managing managed fields (strings, interfaces, variants, etc) is an important pro for using Default() vs ZeroMemory(). But, if the type has no managed fields, then it doesn't really matter which one you use, though Default() does make for cleaner code.
  13. Remy Lebeau

    Highlight a specific popup menu item?

    Maybe you meant *LESS* error prone? That is a biggy. You don't need heap allocation to get into that situation, but it is harder to do without manually coercing the type system.
  14. Remy Lebeau

    Highlight a specific popup menu item?

    The way you are using SetMenuItemInfo() and HiliteMenuItem() in the DropdownMenuShow() method will not work. You are calling them after TPopupMenu.Popup() has exited. Popup() is a blocking method, it does not exit until the popup menu has been dismissed. The TPopupMenu.OnPopup event is fired while Popup() is running. However, upon further review, OnPopup is fired BEFORE the menu is made visible, and TPopupMenu may recreate the menu AFTER OnPopup has been called and BEFORE the menu is actually shown. So, your best bet is likely to subclass the TPopupList window so you can intercept the WM_ENTERMENULOOP message, then customize your menu items at that point. For example: type TPopupListEx = class(TPopupList) protected procedure WndProc(var Message: TMessage); override; end; procedure TPopupListEx.WndProc(var Message: TMessage); begin inherited; if (Message.Msg = WM_ENTERMENULOOP) and (Message.WParam = 1) then begin // customize pmTest items as needed... end; end; initialization Popuplist.Free; //free the "default", "old" list PopupList := TPopupListEx.Create; //create the new one // The new PopupList will be freed by // finalization section of Menus unit. end.
  15. Remy Lebeau

    THostName delphi seattle

    LoadLibrary() will not return anything other than 0 on failure, so if Hinstance_Error is not 0 then checking for it is wrong. When LoadLibrary() does fail, what does GetLastError() say about WHY it failed?
  16. Remy Lebeau

    FMX and https

    By default, Indy uses OpenSSL. When that error happens, you can use the WhichFailedToLoad() function in the IdSSLOpenSSLHeaders unit to find out why. But note that Indy does not support OpenSSL 1.1.x yet, so you would have to deploy OpenSSL 1.0.2 dylibs with your app, and then tell Indy where those dylibs are located at runtime via the IdOpenSSLSetLibPath() function so it can find them. Also look at the IdOpenSSLSetCanLoadSymLinks() and IdOpenSSLSetLoadSymLinksFirst() functions to make Indy avoid loading dylibs for other non-compatible OpenSSL versions. In any case, be aware that ever since Google dropped support for OpenSSL in Android 6 in favor of BoringSSL, using OpenSSL on Android is increasingly difficult. The above MAY OR MAY NOT work, depending on the device's setup. Indy does not support BoringSSL at this time, or any of the more official higher-level Java APIs that Google wants developers to use instead of using lower-level native libraries, like OpenSSL/BoringSSL directly. The alternative is to write your own TIdSSLIOHandlerSocketBase-derived class (or find a 3rd party one) that uses whatever SSL/TLS library/API you want besides OpenSSL. For example, there is some effort in progress to add support for LibreSSL/LibTLS to Indy, though I don't think that will help you in this particular situation, but it shows that supporting alternative SSL/TLS APIs is possible.
  17. Remy Lebeau

    THostName delphi seattle

    The code you have presented does not actually use ANY real functionality from the Sockets unit AT ALL. It is actually using functionality from the WinSock unit instead. So you can just remove the Sockets unit completely, you don't have to replace it with anything. The ONLY things you need to replace are the TSocketHost and TSocketProtocol types. Those are very easy to replace, just re-define them directly in the PCConnectionHelper unit, eg: type TSocketHost = type AnsiString; TSocketProtocol = Word; Or, just drop them completely, they are not actually needed. PCConnectionHelper should just use AnsiString and Word as-is instead. That being said, I do see a number of other problems in your code, particularly in the PCConnectionHelper unit, it is using some unsafe pointer operations that can be made simpler and safer. Maybe that is causing your 64bit issue? But there are some other issues in the IBConnectionHelper unit too, most notably Ansi vs Unicode mismatches. Try these files instead: PCConnectionHelper.pas IBConnectionHelper.pas
  18. Remy Lebeau

    THostName delphi seattle

    That Sockets unit is OLD (dating back to Delphi 6) and is not maintained. That unit was Borland's (before Embarcadero owned Delphi) attempt at providing cross-platform socket classes for Kylix, but it doesn't work very well, and they decided to drop it in favor of Indy in later versions. In fact, that unit is not even distributed with Delphi anymore, XE was the last version to include it. And even if it were still distributed, the 3 class functions you mention never existed in it, not even in 2010, they were always non-static methods of the TIpSocket class, so you could never call them as standalone functions. I'm not quite sure what you are asking for, but you should not be using that Sockets unit in modern projects at all.
  19. Remy Lebeau

    TEdit - Center text vertical

    TEdit is just a wrapper for a standard Win32 edit control, which does not support vertical alignment, only horizontal.
  20. Remy Lebeau

    Mac Catalina and OpenSSL + Indy

    If you are using an up-to-date version of Indy, the IdSSLOpenSSLHeaders unit has IdOpenSSLSetCanLoadSymLinks() and IdOpenSSLSetLoadSymLinksFirst() functions available. By default, Indy attempts to load unversioned dylibs before loading versioned dylibs. You can turn off this behavior, which is useful in cases where the unversioned dylibs are symlinks to versioned dylibs that are not compatible with Indy. Or, in this case, to turn off the loading of unversioned dylibs altogether.
  21. Remy Lebeau

    Could not load OpenSSL library.

    Code has already been written to do exactly that, actually, but it hasn't been checked in yet.
  22. Remy Lebeau

    Why is ShowMesssage blocking all visible forms?

    Then don't use ShowMessage() for that. It displays a modal TForm whose owner window (in Win32 API terms, not VCL terms) is the currently active TForm. An owned window is always on top of its owning window. For what you describe, use a normal TForm instead of ShowMessage(). Set its PopupParent property to the monitoring TForm that needs attention, and then show the popup TForm. This way, the popup Tform stays on top of only its monitoring TForm, but other TForms can appear on top of the popup TForm. Otherwise, change your UI to not use a popup TForm at all. Put a visible message inside the TForm that needs attention.
  23. Remy Lebeau

    Generics and Classes on Windows 2000 = OOM

    The TDictionary.Keys property uses a singleton, so no matter how many times you read the Keys property itself, there will only be 1 TKeyCollection object in memory. However, every time you call ToArray() on that collection, it will allocate a new array in memory and populate it with the current keys. Dynamic arrays are reference counted, so every assignment to the local tdictkeys variable will decrement the refcount of the old array, freeing it, and increment the refcount of the new array. When the method exits, the refcount of the last array allocated is decremented, freeing it. If the dictionary is continuously growing in count, then the loop above will allocate larger and larger arrays accordingly, , where a new array is allocated before the previous array is freed. So yes, that has the potential to cause an OOM error over time, depending on just how large the dictionary actually grows. At the assembly level, yes. But if the binary has external dependencies on DLLs/APIs that don't exist on the machine (and modern versions of Delphi's RTL do use APIs that don't exist in Win2K), then the binary will not be loaded by the OS and will not be allowed to run any of its code.
  24. Remy Lebeau

    How to iterate a TDictionary using RTTI and TValue

    In that TPair record, TKey and TValue are Generic parameters, they belong to the TPair type itself. In C++, that TPair record type gets renamed to TPair__2 because of the Generic parameters. When the Delphi compiler generates a C++ .hpp file, it will declare a constructor inside that type. But since the type is renamed for C++, the HPPEMITs are being used to provide an implementation for that constructor using the new name. I have never seen the [HPPGEN] attribute before, though. It is not documented.
  25. (copied from my answer to your same question on StackOverflow😞 Indy is not really designed for peeking data, it would rather that you read whole data, letting it block until the requested data has arrived in full. That being said, TIdBuffer does have a PeekByte() method: function PeekByte(AIndex: Integer): Byte; var B: Byte; if AContext.Connection.IOHandler.InputBuffer.Size > 0 then begin B := AContext.Connection.IOHandler.InputBuffer.PeekByte(0); ... end; Or, if you are looking for something in particular in the buffer (ie, a message delimiter, etc), TIdBuffer has several overloaded IndexOf() methods: function IndexOf(const AByte: Byte; AStartPos: Integer = 0): Integer; overload; function IndexOf(const ABytes: TIdBytes; AStartPos: Integer = 0): Integer; overload; function IndexOf(const AString: string; AStartPos: Integer = 0; AByteEncoding: IIdTextEncoding = nil {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF} ): Integer; overload; var Index: Integer; Index := AContext.Connection.IOHandler.InputBuffer.IndexOf(SingleByte); Index := AContext.Connection.IOHandler.InputBuffer.IndexOf(ArrayOfBytes); Index := AContext.Connection.IOHandler.InputBuffer.IndexOf('string'); ...