-
Content Count
3060 -
Joined
-
Last visited
-
Days Won
139
Everything posted by Remy Lebeau
-
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.
-
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.
-
https://stefansundin.github.io/xn_resource_editor/
-
Boolean short-circuit with function calls
Remy Lebeau replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
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. -
Boolean short-circuit with function calls
Remy Lebeau replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
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; -
Is interposer class really best to customize TPanel.Paint?
Remy Lebeau replied to Mike Torrettinni's topic in VCL
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. -
Is interposer class really best to customize TPanel.Paint?
Remy Lebeau replied to Mike Torrettinni's topic in VCL
http://docwiki.embarcadero.com/RADStudio/Sydney/en/Package-specific_Compiler_Directives https://www.oreilly.com/library/view/delphi-in-a/1565926595/re414.html -
Is interposer class really best to customize TPanel.Paint?
Remy Lebeau replied to Mike Torrettinni's topic in VCL
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. -
Is interposer class really best to customize TPanel.Paint?
Remy Lebeau replied to Mike Torrettinni's topic in VCL
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. -
Is interposer class really best to customize TPanel.Paint?
Remy Lebeau replied to Mike Torrettinni's topic in VCL
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. -
enums with duplicate values
Remy Lebeau replied to dummzeuch's topic in RTL and Delphi Object Pascal
According to my notes, assigning explicit ordinal values to enums has been supported since D6. I haven't tested it in earlier versions, though. -
Class fields as parameters or refer to fields directly?
Remy Lebeau replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Recursion, or multi-threading. -
Class fields as parameters or refer to fields directly?
Remy Lebeau replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
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. -
I really wish Delphi would stop mimicking DotNet. Delphi IS NOT DotNet!
-
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.
-
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.
-
ICS v8.64 can't compile on Delphi 7
Remy Lebeau replied to Kyle_Katarn's topic in ICS - Internet Component Suite
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 -
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.
-
ICS v8.64 can't compile on Delphi 7
Remy Lebeau replied to Kyle_Katarn's topic in ICS - Internet Component Suite
This is the way Indy does it. Then the conditional is defined only for D2006+ (and FPC), and only for release builds. -
issues using filenames with spaces
Remy Lebeau replied to FranzB's topic in Algorithms, Data Structures and Class Design
Are you really using a relative path to the file? Do you have the same problem when using an absolute path? -
TIdSSLIOHandlerSocketOpenSSL and TLS 1.3 ?
Remy Lebeau replied to Lars Fosdal's topic in Network, Cloud and Web
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. -
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.
-
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.
-
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.
-
Works fine for me just now.