Jump to content

Remy Lebeau

Members
  • Content Count

    3060
  • Joined

  • Last visited

  • Days Won

    139

Everything posted by Remy Lebeau

  1. Remy Lebeau

    Draw TBitmap

    Where is localBMP coming from? You don't really need to make a copy of a TBitmap just to draw it, so you could just use localBMP as-is and get rid of tempBMP. Unless localBMP is actually supposed to be aBMP instead (typo?), then using tempBMP makes more sense if you are trying to draw a TBitmap onto itself. When calling DrawBitmap(), RecFull is supposed to be a rectangle within the TBItmap that you are drawing from, but you are setting it to the rectangle of the TBitmap that you are drawing onto. Change aBMP to tempBMP when populating RecFull.
  2. Remy Lebeau

    Free Resource Builder Utility?

    Or, you could just treat them as-is as RCDATA resources instead. Any data can be stored in RCDATA, it is just raw bytes. Now, whether you can load a PNG image from an RCDATA resource at runtime is another issue, depending on HOW you load it.
  3. Remy Lebeau

    Free Resource Builder Utility?

    https://stefansundin.github.io/xn_resource_editor/
  4. If they all have the SAME argument types, yes. The TFunc generic supports 0..4 arguments, plus the return type: TFunc<TResult> = reference to function: TResult; TFunc<T,TResult> = reference to function (Arg1: T): TResult; TFunc<T1,T2,TResult> = reference to function (Arg1: T1; Arg2: T2): TResult; TFunc<T1,T2,T3,TResult> = reference to function (Arg1: T1; Arg2: T2; Arg3: T3): TResult; TFunc<T1,T2,T3,T4,TResult> = reference to function (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4): TResult; I don't have a working IDE right now, so I didn't try to compile it. I was trying to be clever using a const, instead of a var that has to be recreated every time the function is called, eg: function IsAnyTrue5: boolean; var Funcs: array[0..2] of TFunc<Boolean>; i: Integer; begin Result := False; Funcs[0] := A; Funcs[1] := B; Funcs[2] := C; for i := Low(Funcs) to High(Funcs) do Result := Funcs[i]() or Result; end; Or: function IsAnyTrue5: boolean; var Funcs: TArray<TFunc<Boolean>>; i: Integer; begin Result := False; Funcs := [A, B, C]; for i := Low(Funcs) to High(Funcs) do Result := Funcs[i]() or Result; end; Or: var Funcs: TArray<TFunc<Boolean>>; function IsAnyTrue5: boolean; var i: Integer; begin Result := False; for i := Low(Funcs) to High(Funcs) do Result := Funcs[i]() or Result; end; initialization Funcs := [A, B, C]; In any case, the idea being to put all of the functions into an array, and then loop through the array calling them and tallying up the results. This way, more functions can be added in the future with minimal effort, Sure, that will work. I knew TFunc existed, I had just forgot about plain function pointers, too. Yes, all of the functions would have to be of same signature. Otherwise they have to be called individually. Since the OP mentioned running through a lot of options, I assume there is some common interface for them.
  5. How about something like this? uses System.SysUtils; function IsAnyTrue5: boolean; const Funcs: array[0..2] of TFunc<Boolean> = (A, B, C); var i: Integer; begin Result := False; for i := Low(Funcs) to High(Funcs) do Result := Funcs[i]() or Result; end;
  6. Remy Lebeau

    Is interposer class really best to customize TPanel.Paint?

    In this example, no, since the only design-time functionality being used is RegisterComponents() which is implemented in the RTL in a runtime package, not a design-time package. So this example can exist in a single runtime+designtime package. Yes, so that the IDE knows that it is allowed to use this package for both installation into the IDE and compiling into executables. Yes, because designtime-only packages are not allowed to be compiled into executables, only runtime-only and runtime+designtime packages. Marking the package for runtime usage is important. Maybe not a hard requirement, especially in the early days, but around D6 or so this actually did start getting enforced. And besides, it is how the system has always been intended to be used, and how it gets documented by 3rd party books and such. And frankly, it just makes sense to do it this way. Component logic goes in a runtime package, design-time editors go in a design-time package. If there are no editors, the two packages can be merged into one. Simple and straight forward. Whether or not it works to compile a designtime-only package into a runtime executable is another matter. It is not supposed to work.
  7. Remy Lebeau

    Is interposer class really best to customize TPanel.Paint?

    http://docwiki.embarcadero.com/RADStudio/Sydney/en/Package-specific_Compiler_Directives https://www.oreilly.com/library/view/delphi-in-a/1565926595/re414.html
  8. Remy Lebeau

    Is interposer class really best to customize TPanel.Paint?

    If you make the layered window be a child of the panel, then that will only work on Windows 8+. On earlier Windows, you would have to make the layered window be a top-level overlay window that follows the panel onscreen.
  9. Remy Lebeau

    Is interposer class really best to customize TPanel.Paint?

    Um no, because designtime-only packages are not used in runtime executables. The component needs to be in a runtime package, which in this particular example can ALSO be used as a design-time package.
  10. Remy Lebeau

    Is interposer class really best to customize TPanel.Paint?

    If the component does not have extra design-time functionality that directly interacts with IDE APIs (property/component editors, OpenTools plugin, etc), then you do not need to make a separate design-time package. You can create 1 package and mark it as being BOTH a runtime package AND a design-time package. That will work just fine.
  11. Remy Lebeau

    enums with duplicate values

    According to my notes, assigning explicit ordinal values to enums has been supported since D6. I haven't tested it in earlier versions, though.
  12. The only time this should make any real difference is if Search() is re-entrant. If it is not, then don't worry about this, use whatever style you are comfortable with. But if it is, then you can't use class members, as they could get overwritten during one Search() while another Search() is still running.
  13. Remy Lebeau

    Delphi 10.4 compiler going senile

    I really wish Delphi would stop mimicking DotNet. Delphi IS NOT DotNet!
  14. Remy Lebeau

    Delphi 10.4 compiler going senile

    Yeah. They should really rename either System.TMonitor or Vcl.Forms.TMonitor to avoid that conflict. Frankly, I never understood why the System one was named TMonitor to begin with. Since it is inherently tied to TObject, maybe something more like TObjectLock, TObjectSync, TObjectMonitor, etc would have made more sense. Of course, on the flip side, for the Vcl.Forms one, maybe something more like TDisplayMonitor, TScreenMonitor, etc would have made more sense. Oh well, too late now, I guess.
  15. Remy Lebeau

    Sending an SMTP email to AOL.com

    What is the actual problem you are having? What does your code actually look like? Which SMTP component/library are you using? You need to be more specific.
  16. Remy Lebeau

    ICS v8.64 can't compile on Delphi 7

    There are some 3rd-party INC files like that already. But different vendors have different requirements for different feature use-cases. I can only speak for myself, but I don't like using monolithic INC files that define lots of things that I'm not actually using. That is why authors typically use their own INC files to tailor for their particular requirements. What we really need is a compiler-level feature detection system instead. C++ has had something like that standardized for awhile now: https://en.cppreference.com/w/cpp/feature_test https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros
  17. Remy Lebeau

    Set form height based on resolution??

    Which version of Delphi are you using? Recent versions have better support for DPI. Have a look at things like the TForm.Monitor.PixelsPerInch property and the TControl.ScaleForPPI() method. Try something like this: Height := MulDiv(iDesiredHeight, Monitor.PixelsPerInch, 96); Or this: Height := iDesiredHeight ScaleForPPI(Monitor.PixelsPerInch); I don't know if these are actually correct or not. I don't design UIs for multi-DPI systems.
  18. Remy Lebeau

    ICS v8.64 can't compile on Delphi 7

    This is the way Indy does it. Then the conditional is defined only for D2006+ (and FPC), and only for release builds.
  19. Are you really using a relative path to the file? Do you have the same problem when using an absolute path?
  20. Remy Lebeau

    TIdSSLIOHandlerSocketOpenSSL and TLS 1.3 ?

    You can download it from the current pull request on GitHub: https://github.com/IndySockets/Indy/pull/299 It has not been merged into Indy's main codebase yet.
  21. Remy Lebeau

    Problem closing forms..

    Show() is non-blocking, so your example would reach myForm.Free() before the Form's window is actually shown to the user. It is perfectly safe to use caFree with a modal Form. The Form object remains alive until after ShowModal() exits and control returns to the main message loop, THEN the Form is destroyed. If you want to get results from the Form, you just have to do so immediately after ShowModal() exits, which is the best time to get the results anyway. If you need the results at a later time, save them somewhere that you can get them back when needed. So, you would either: -auto-create a Form and then Show()/Hide() it when needed. Let the TApplication handle destroying the Form during app shutdown. - Create() and Show() the Form, then Free() it when you don't need it anymore, or use OnClose to caFree it. - Create() and ShowModal() the Form, and then Free() it (directly or via caFree) after ShowModal() has exited.
  22. Remy Lebeau

    Problem closing forms..

    Then they likely weren't being owned properly to begin with. Yes. No. In fact, that even makes it more complex, because a Parent also destroys its child controls when itself is destroyed, outside of TComponent ownership. destructor TWinControl.Destroy; var I: Integer; Instance: TControl; begin ... I := ControlCount; while I <> 0 do begin Instance := Controls[I - 1]; Remove(Instance); Instance.Destroy; // <-- HERE I := ControlCount; end; ... end; I have VCL sources going back to Delphi/BCB 5. Here is the TComponent destructor in D5: destructor TComponent.Destroy; var I: Integer; begin Destroying; if FFreeNotifies <> nil then begin for I := FFreeNotifies.Count - 1 downto 0 do begin TComponent(FFreeNotifies[I]).Notification(Self, opRemove); if FFreeNotifies = nil then Break; end; FFreeNotifies.Free; FFreeNotifies := nil; end; DestroyComponents; if FOwner <> nil then FOwner.RemoveComponent(Self); // <-- HERE inherited Destroy; end; IIRC, there was not much in the way of sweeping changes between D1 to D5, so I agree with Uwe that TComponent ownership likely dates back all the way to D1, when the VCL was first introduced.
  23. Remy Lebeau

    Problem closing forms..

    If it is owned, it is destroyed when its Owner is destroyed. Otherwise, it is leaked and not destroyed at all. When the process exits, the OS will reclaim the leaked memory. Using Action=caFree in the OnClose event is the correct way to do that. Whether or not the Form has an Owner is irrelevant. An owned object can be destroyed at any time, even before its Owner is destroyed. If the object is destroyed first, it will simply remove itself from its Owner so that that Owner does not try to destroy it again.
  24. Remy Lebeau

    Is quality.embarcadero.com down?

    Works fine for me just now.
×