-
Content Count
2982 -
Joined
-
Last visited
-
Days Won
134
Everything posted by Remy Lebeau
-
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.
-
Still actively developed (by me). RAD Studio 10.4 includes an updated trunk version from Indy's GitHub repo from about 2 months ago. I'm not in charge of, or involved with, how Embarcadero incorporates help files for 3rd party components. But I do recall that Indy's help files are included, somewhere. Although, Indy's documentation is quite dated, it hasn't been updated in many years. There have been property/interface changes made over the years that still need to be documented.
-
Whats the idea behind Dev-Cpp support ?
Remy Lebeau replied to Rollo62's topic in Delphi IDE and APIs
Are you thinking of Borland C++Builder X? The Java-based IDE (using the JBuilder architecture) that was released after Borland EOL'ed C++Builder 6, and before CodeGear resurrected C++Builder in BDS 2005. Using wxWidgets with the Borland C++ BuilderX There is also TwinForms, which is a wxWidgets Form Designer for C++Builder. -
Whats the idea behind Dev-Cpp support ?
Remy Lebeau replied to Rollo62's topic in Delphi IDE and APIs
C++Builder includes a Delphi compiler. -
How to increase the distance between TCheckBox glyph and caption text?
Remy Lebeau replied to PeterPanettone's topic in VCL
The WordWrap property was added to TButtonControl (which TCheckBox derives from) in Delphi 7. All it does is enables the BS_MULTILINE window style on the control, so it is possible to enable this style manually in earlier Delphi versions, too. -
That is a VERY OLD problem that interface users must always be careful of. You are creating a strong circular reference between the two classes. TMyClass1 has a strong reference to TMyClass2, so the refcount of TMyClass2 is incremented. And TMyClass2 has a strong reference to TMyClass1, so the recount of TMyClass1 is incremented. In that situation, neither object's refcount can fall to 0 to destroy either object without explicit intervention to release one of the references, otherwise both objects are leaked. So yes, one solution is to explicitly release one of the references to decrement its refcount manually. Another solution is to have one of the objects use a weak reference instead of a strong reference, so that the refcount of the weak-referenced object is not incremented to begin with. Delphi 10.1 Berlin added support for [weak] and [unsafe] attributes on interface variables. But prior to 10.1 Berlin, raw Pointers have to be used to accomplish the same thing. For example: program Project3; {$APPTYPE CONSOLE} {$R *.res} uses FastMM4, system.Classes, System.SysUtils; type MyInterface2 = interface ['{8E7BC71F-55EE-4345-8A5B-42C433BE9EBA}'] procedure print; end; MyInterface1 = interface ['{607A66A6-D68C-4980-9FB1-83B325EE9A91}'] procedure SetInterface2(aInterface: MyInterface2); procedure DoSomethingWithInterface2; end; TMyClass1 = class(TInterfacedObject, MyInterface1) private RefToInterFace2: MyInterface2; public procedure SetInterface2(aInterface: MyInterface2); procedure DoSomethingWithInterface2; end; TMyClass2 = class(TInterfacedObject, MyInterface2) private // in Delphi 10.1 Berlin and later, use this... [weak]{or [unsafe]} Ref: MyInterface1; // prior to Delphi 10.1 Berlin, use this... // (you will have to typecast Ref every time you want to access MyInterface1) // Ref: Pointer{MyInterface1}; public constructor Create(int: MyInterface1); reintroduce; procedure print; end; { TMyClass1 } procedure TMyClass2.print; begin Writeln('TMyClass2.print'); Sleep(1500); end; { TMyClass2 } procedure TMyClass1.DoSomethingWithInterface2; begin if RefToInterFace2 <> nil then RefToInterFace2.print; end; procedure TMyClass1.SetInterface2(aInterface: MyInterface2); begin RefToInterFace2 := aInterface; end; constructor TMyClass2.Create(int: MyInterface1); begin inherited Create; Ref := int; if int <> nil then int.SetInterface2(Self); end; var aMyClass1: MyInterface1; aMyClass2: MyInterface2; begin aMyClass1 := TMyClass1.Create; aMyClass2 := TMyClass2.Create(aMyClass1); aMyClass1.DoSomethingWithInterface2; end. Or: program Project3; {$APPTYPE CONSOLE} {$R *.res} uses FastMM4, system.Classes, System.SysUtils; type MyInterface2 = interface ['{8E7BC71F-55EE-4345-8A5B-42C433BE9EBA}'] procedure print; end; MyInterface1 = interface ['{607A66A6-D68C-4980-9FB1-83B325EE9A91}'] procedure SetInterface2(aInterface: MyInterface2); procedure DoSomethingWithInterface2; end; TMyClass1 = class(TInterfacedObject, MyInterface1) private // in Delphi 10.1 Berlin and later, use this... [weak]{or [unsafe]} RefToInterFace2: MyInterface2; // prior to Delphi 10.1 Berlin, use this... // (you will have to typecast RefToInterFace2 every time you want to access MyInterface2) // RefToInterFace2: Pointer{MyInterface2}; public procedure SetInterface2(const aInterface: MyInterface2); procedure DoSomethingWithInterface2; end; TMyClass2 = class(TInterfacedObject, MyInterface2) private Ref: MyInterface1; public constructor Create(int: MyInterface1); reintroduce; // prior to Delphi 10.1 Berlin, use this... // destructor Destroy; override; procedure print; end; { TMyClass1 } procedure TMyClass2.print; begin Writeln('TMyClass2.print'); Sleep(1500); end; { TMyClass2 } procedure TMyClass1.DoSomethingWithInterface2; begin if RefToInterFace2 <> nil then begin // in Delphi 10.1 Berlin and later, use this... RefToInterFace2.print; // prior to Delphi 10.1 Berlin, use this... // MyInterface2(RefToInterFace2).print; end; end; procedure TMyClass1.SetInterface2(const aInterface: MyInterface2); begin RefToInterFace2 := aInterface; end; constructor TMyClass2.Create(int: MyInterface1); begin inherited Create; Ref := int; if int <> nil then int.SetInterface2(Self); end; // prior to Delphi 10.1 Berlin, use this... {destructor TMyClass2.Destroy; begin if Ref <> nil then MyInterface1(Ref).SetInterface2(nil); inherited Destroy; end;} var aMyClass1: MyInterface1; aMyClass2: MyInterface2; begin aMyClass1 := TMyClass1.Create; aMyClass2 := TMyClass2.Create(aMyClass1); aMyClass1.DoSomethingWithInterface2; end.
-
I don't use ICS, so I don't know the answer to that. However, an easy way to find out is to simply have the event handler compare the return value of the Win32 GetCurrentThreadId() function against the value of the RTL's MainThreadID variable. If the values match, the event is run in the UI thread and accessing UI controls is safe, otherwise access needs to be synchronized. If the TWSocket is running in the context of the main UI thread, then whether you do the logic in the OnDataAvailable event or in another UI event, you are still going to block subsequent data receiving while the TMemo is busy adding data. I would say don't worry about it unless it proves to be a real bottleneck, in which case you can then either move the TWSocket to another thread that posts new data to the main UI thread asynchronously so as not to block the socket, or else perhaps put new data into a queue somewhere and then use a timer to periodically dump the queue into the TMemo.
-
Note that only applies to MessageDlg() and other custom dialogs. For the Win32 MessageBox() function, and the VCL's Application.MessageBox() (which just calls the Win32 MessageBox()), you would have to hook into the Win32 API via SetWindowsHookEx() or SetWinEventHook() in order to capture the dialog window, and then you can reposition it as needed.
-
When a class object instance is destroyed, its managed data members are finalized automatically for you (inside of TObject.CleanupInstance(), which is called automatically by the RTL). Strings, dynamic arrays, and interfaces are all managed types that use reference counting. The RTL automatically decrements their reference counts for you when they go out of scope, such as when a TMyClass1 object is destroyed (it will not necessarily set the variables themselves to nil, though, but that doesn't matter during object destruction). RefToInterFace2.Release() is invoked by the RTL when the TMyClass1 object is destroyed. Actually, it does. When the TMyClass1 object is destroyed, the RTL calls TObject.CleanupInstance(), which then loops through TMyClass1's RTTI finalizing all managed class members. That destruction happens when your aMyClass1 variable goes out of scope on the 'end.' statement, where the RTL finalizes the aMyClass1 variable, decrementing the TMyClass1 object's refcount. And since its refcount falls to 0, the TMyClass1 destructor is called. Your aMyClass2 variable will have already gone out of scope and been finalized by that time, so the refcount of the TMyClass2 object will be 1 when the TMyClass1 destructor is entered. When RefToInterFace2 is finalized by the RTL, the TMyClass2 object's refcount falls to 0, calling the TMyClass2 destructor.
-
How to increase the distance between TCheckBox glyph and caption text?
Remy Lebeau replied to PeterPanettone's topic in VCL
For VCL, you could set the button to owner-draw and then manually draw your own check box however you want, then you can include more spacing in the drawing. However, you would have to do this at the Win32 API layer, not at the VCL layer.