-
Content Count
2914 -
Joined
-
Last visited
-
Days Won
130
Everything posted by Remy Lebeau
-
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.
-
Cannot login to Quality Central - who to contact?
Remy Lebeau replied to A.M. Hoornweg's topic in General Help
Works fine for me just now. -
Setting Action=caFree in the OnClose event is a DEFERRED destruction. It does not free the Form right away, it postpones the actual destruction until control flow returns to the calling thread's message loop, THEN the Form is freed when it is safe to do so (ie, no other messages are being processed). So it doesn't matter if the Form is owned or not. If the Form is owned, and the Owner destroys the Form before the caFree request is processed, then the request will simply get ignored since there is nothing to Free anymore.
-
Be sure to file these issues to Quality Portal so Embarcadero sees them for future updates.
-
Depends on your needs. You could use GetLastInputInfo() in a loop/timer. Or you could use SetWindowsHookEx() or RegisterRawInputDevices() to receive real-time events from the mouse/keyboard directly.
-
OK. But my point still stands. Other non-OpenSSL libraries can be plugged into Indy with a little work.
-
Put the PNG TImage on top of another TImage, or a TPanel, or whatever you want, that has the desired background image.
-
Assign a pointer to a dynamic array
Remy Lebeau replied to dummzeuch's topic in RTL and Delphi Object Pascal
I would use PWord: function SomeFunction(segment_ptr: Pointer; segment_count: Integer ): TSmallintArray; var i: Integer; p : PWord {absolute segment_ptr}; begin SetLength(Result, segment_count); p := PWord(segment_ptr); for i := 0 to segment_count-1 do begin Result[i] := SwapInt16(p[i]); // or, if POINTER_MATH is not available on PWord: // Result[i] := SwapInt16(p^); Inc(p); end; end; -
Technically speaking, Indy DOES NOT depend on OpenSSL specifically. Indy uses a plugin model so that any SSL/TLS library can be used, all you need is a TIdSSLIOHandlerSocketBase-derived class to wrap the library's API. It is just that Indy provides a DEFAULT class which uses OpenSSL (TIdSSLIOHandlerSocketOpenSSL), since OpenSSL is portable to multiple platforms. But Indy as a whole doesn't care which SSL/TLS library you actually use at runtime. For example, Eldos SecureBlackbox provides an Indy SSLIOHandler for its own SSL/TLS implementation. And eventually I would like to provide an SChannel SSLIOHandler as a replacement for OpenSSL on Windows.
-
GetTopWindow() returns the CHILD window that is at the top of the z-order of a specified PARENT window. GetActiveWindow() returns the currently active window belonging to the CALLING THREAD (or another thread that is assigned to the message queue of the calling thread). Neither of those are well-suited for finding the active window of ANOTHER app. Have a look at GetForegroundWindow() instead.
-
Linking to a C obj file that makes Windows calls
Remy Lebeau replied to pyscripter's topic in RTL and Delphi Object Pascal
Short answer - no, since you can't have a @ in a variable/function name. You tell us. Is the C code able to call VirtualFree() correctly when you do that? AFAIK, no. Delphi does not support external variables, only external functions. In the specific case of variables exported from DLLs, you can use GetProcAddress() directly. But for linking to variables defined in .obj files, no. -
Short answer - no, it is not possible. biHelp (the WS_EX_CONTEXTHELP extended window style) requires biSystemMenu (the WS_SYSMENU window style), even though this does not seem to be documented anywhere. And it is not a VCL limitation. Enabling biSystemMenu and biHelp, and then manually removing WS_SYSMENU at runtime, still disables the Help button. To do what you are asking, you will have to custom-draw the title bar to draw your own Help button. Or, in 10.4+, use the new Custom Title Bar feature.
-
Patch 2 for RAD Studio 10.4 now available
Remy Lebeau replied to Marco Cantu's topic in General Help
Also https://quality.embarcadero.com/browse/RSP-30078 (oops, didn't see that someone else had already posted this link) -
Patch 2 for RAD Studio 10.4 now available
Remy Lebeau replied to Marco Cantu's topic in General Help
Custom Managed Records Coming in Delphi 10.3 (deferred to 10.4) Custom Managed Records Coming to Delphi 10.4 Custom Managed Records New in Delphi 10.4 Sydney Custom Managed Records -
Windows 10 vs Windows 7 SMTP/Winsock issue
Remy Lebeau replied to GillesL.'s topic in ICS - Internet Component Suite
I have used direct Winsock calls on all Windows versions since Win9x and have never had this problem. So it has to be an issue with the way your code is using Winsock. Can you please show the actual code that is failing? "Interrupted system call" is the text message for WSAEINTR (10004), which is very unusual for connect() to report, unless your code is calling WSACancelBlockingCall(), which it should not be doing since that is a legacy Winsock 1.1 function that was deprecated in Winsock 2.0 and removed in 2.2. -
Can you be a little more specific? ContentFields is a property of TWebRequest itself, it is not implemented by Indy. TWebRequest parses data the same way regardless of platform. And there is no platform-specific code in Indy's IdHTTPWebBrokerBridge.pas, either. So, it does not really make sense for the ContentFields to be empty on Linux but not on Windows, unless there is a low-level error occuring. Internally, the TWebRequest.ContentFields property getter calls TWebRequest.ExtractContentFields() to fill a TStringList, and then returns that TStringList. TWebRequest.ExtractContentFields() checks the TWebRequest.ContentLength property for > 0, and if true then reads the TWebRequest.Content property and parses it into name=value pairs. The TWebRequest.Content data is decoded from the TWebRequest.RawContent property using a charset determined from the TWebRequest.ContentType property. Indy's TIdHTTPAppRequest class provided the data for the ContentLength, ContentType, and RawContent properties. So, what exactly is broken on Linux? Which property is not returning what it should be - ContentLength, ContentType, or RawContent? If all of those properties are returning valid data, but the ContentFields is still blank, then the problem is in WebBroker itself, not in Indy.
-
Not the way you have shown, no. All type info is lost with an untyped var parameter, so you HAVE to specify a type somehow. A Generic is the most direct way to specify a type in a, well, generic manner, eg: type TRecSI = record FInteger: Integer; FString: string; constructor Create(const s: string; i: Integer); end; THelper = class class procedure DoSomething<T>(var Anything: T); end; constructor TRecSI.Create(const s: string; i: Integer); begin FInteger := i; FString := s; end; class procedure THelper.DoSomething<T>(var Anything: T); begin case GetTypeKind(T) of tkInteger: Writeln(PInteger(@Anything)^); /// end; end; var A: Integer; B: string; C: TArray<Byte>; D: TArray<Integer>; E: TArray<string>; F: TRecSI; begin THelper.DoSomething(A); THelper.DoSomething(B); THelper.DoSomething(C); THelper.DoSomething(D); THelper.DoSomething(E); F := TRecSI.Create('Hello', 1234); DoSomething(F); Readln; end. Otherwise, you could use TValue instead, eg: type TRecSI = record FInteger: Integer; FString: string; constructor Create(const s: string; i: Integer); end; constructor TRecSI.Create(const s: string; i: Integer); begin FInteger := i; FString := s; end; procedure DoSomething(const Anything: TValue); begin case Anything.Kind of tkInteger: Writeln(Anything.AsInteger { or: Anything.AsType<Integer> } ); /// end; end; var A: Integer; B: string; C: TArray<Byte>; D: TArray<Integer>; E: TArray<string>; begin // TValue supports implicit conversions for some fundamental types... DoSomething(A { or: TValue.From(A) }); DoSomething(B { or: TValue.From(B) }); // but no implicit conversions for array types... DoSomething(TValue.From(C)); DoSomething(TValue.From(D)); DoSomething(TValue.From(E)); // or records... DoSomething(TValue.From(TRecSI.Create('Hello', 1234))); Readln; end.
-
Just use Generics for this (see Testing the type of a generic in delphi), eg: type TSomeClass = class class procedure DoSomething<T>(const AParam: T); end; class procedure TSomeClass.DoSomething<T>(const AParam: T); begin case GetTypeKind(T) of tkUString: begin ShowMessage(PUnicodeString(@AParam)^); end; tkInteger: begin ShowMessage(IntToStr(PInteger(@AParam)^)); end; end; end;
-
Cross-platform support for non-Windows platforms. Mac OSX is certified POSIX-compliant. Linux, iOS, and Android (which runs on top of Linux) are mostly compliant, but not certified.