-
Content Count
2684 -
Joined
-
Last visited
-
Days Won
113
Everything posted by Remy Lebeau
-
"Best" is subjective and opinionated. There's are plenty of mature options that have the features you are asking for. Why? See above about not using the native components
-
No. In what context, exactly?
-
I answered your same question on StackOverflow before seeing it posted here too: https://stackoverflow.com/a/79151906/65863 I see you actually posted this same question on 3 forums at the same time: Delphi-PRAXiS, StackOverflow, and Lazarus. It's generally considered rude to ask the same question on multiple forums at the same time. It gives people the impression that you are in a hurry and don't value any given forum, and you'll usually get similar answers, and you lessen the value of people duplicating their efforts. Pick a forum, give it some time to amswer (like a few days at least), and if you don't get a satisfactory answer then try another forum if needed.
-
TValue.ToString for TAlphaColor type returns a strange result.
Remy Lebeau replied to dmitrybv's topic in RTL and Delphi Object Pascal
I can reproduce the issue. Interestingly, if you don't use the TRttiContext and just assign the ColorProp directly to the TValue then TValue.ToString() works as expected: //Val := AColorProp.GetValue(ColorObj); Val := ColorObj.ColorProp; // Val.ToString now returns '4294303411' In both cases, the numeric value (inside the TValue.FAsULong field) is correct, but the RTTI for the value different - in the first case, the TValue.FTypeInfo belongs to TAlphaColor, but in the second case the TValue.FTypeInfo belongs to Cardinal instead! Both RTTIs have Kind=tkInteger and OrdType=otULong, so the numeric value is stored in TValue.FAsULong and TValue.ToString() formats as a UInt64. But, the TValue.AsUInt64 property getter behaves differently on the two RTTI types: function TValue.AsUInt64: UInt64; begin if not IsEmpty then begin if FTypeInfo = System.TypeInfo(Int64) then Exit(FAsSInt64) else if FTypeInfo = System.TypeInfo(UInt64) then Exit(FAsUInt64) else if FTypeInfo = System.TypeInfo(Cardinal) then Exit(FAsULong) // <-- SECOND CASE else if FTypeInfo^.Kind = tkInteger then Exit(AsInteger); // <-- FIRST CASE end; AsTypeInternal(Result, System.TypeInfo(UInt64)); end; function TValue.AsInteger: Integer; begin if not IsEmpty then begin if FTypeInfo = System.TypeInfo(Integer) then Exit(FAsSLong) else if FTypeInfo^.Kind = tkInteger then case GetTypeData(FTypeInfo)^.OrdType of otSByte: Exit(FAsSByte); otSWord: Exit(FAsSWord); otSLong: Exit(FAsSLong); else Exit(FAsULong); // <-- FIRST CASE end; end; AsTypeInternal(Result, System.TypeInfo(Integer)); end; In the first case, TValue.FTypeInfo does not belong to either UInt64 or Cardinal (it belongs to TAlphaColor), so the TValue.FAsULong field (whose unsigned value is 4294303411, hex $FFF5DEB3) first gets converted to a signed Integer, resulting in a negative value of -663885 (hex $FFF5DEB3), which is then converted up to a sign-extended UInt64, resulting in a large unsigned value of 18446744073708887731 (hex $FFFFFFFFFFF5DEB3). In the second case, the TValue.FTypeInfo belongs to Cardinal (an unsigned type), so the TValue.FAsUlong field (hex $FFF5DEB3) is converted as-is to a zero-extended UInt64, preserving the original value (hex $00000000FFF5DEB3). -
General question for "Edit.Text's": Why is WordWrap not active bydefault?
Remy Lebeau replied to Rollo62's topic in Delphi IDE and APIs
Well, since TEdit is supposed to be a single-line edit control, it doesn't make sense to enable word-wrapping on it by default. Use TMemo instead if you need a multi-line edit control. -
What is the likelihood that the new Clang tool chain will be accessible for 32 bit projects?
Remy Lebeau replied to Gord P's topic in General Help
I don't see why. It's still clang, just a newer version with a higher language compliance. At this time, the newer clang compiler is available only for 64bit. -
What is the likelihood that the new Clang tool chain will be accessible for 32 bit projects?
Remy Lebeau replied to Gord P's topic in General Help
Umm, are you not aware that there is already a 32bit Clang compiler? (two, actually). You can switch to it by turning off the "Use 'classic' Borland compiler" option in the project settings. https://docwiki.embarcadero.com/RADStudio/en/Win32_Clang-enhanced_Compilers The difference between the 32bit Clang compiler and the newly released 64bit Clang compiler (besides bit-size, obviously) is that the 64bit compiler uses a newer version of clang. But, after it has matured a little bit, I'm sure they will update the 32bit compiler too, as 32bit development is still popular. But, at least you can get started using clang today. -
Double, default value
Remy Lebeau replied to Skrim's topic in Algorithms, Data Structures and Class Design
Sorry, I had misread your earlier message. -
Double, default value
Remy Lebeau replied to Skrim's topic in Algorithms, Data Structures and Class Design
StrToFloat() does not have an option to return a default value. You need to use TryStrToFloat() for that. -
In 64bit, you can't mix inline assembly with Pascal code in the same function, but you can still write entire functions in just assembly and then call them from Pasal functions. You can't. At least, not in a Pascal function, where you don't have access to modify the function's prolog and epilog.
-
You said: "But in the first one I end method TIdIOHandler.RaiseConnClosedGracefully". That implied to me that you are directly calling RaiseConnClosedGracefully() yourself. If that is not the case, then ignore what I said. Indy will raise an EIdConnClosedGracefully exception when the extra client disconnects if it does not send a request.
-
Copy file to temp folder fails
Remy Lebeau replied to emileverh's topic in RTL and Delphi Object Pascal
Use the Win32 SHFileOperation() API to copy the file with the FOF_RENAMEONCOLLISION flag: If you need to know what the copied filename was renamed to, include the FOF_WANTMAPPINGHANDLE flag as well: Alternatively, on Windows Vista+, you can use the IFileOperation API instead, using IFileOperation.SetOperationFlags() to set the FOF_RENAMEONCOLLISION flag, IFileOperation.CopyItem() and IFileOperation.PerformOperations() to perform the copy, and if needed use an IFileOperationProgressSink event sink to discover the copied filename in the PostCopyItem event. -
That is a known issue with postman. And how are you doing that, when there is no OnCommandGet event fired for that connection? The only option would be to use the OnConnect event, in which case you could instead just assign a ReadTimeout to the connection and let TIdHTTPServer close the connection when no request arrives.
-
Copy file to temp folder fails
Remy Lebeau replied to emileverh's topic in RTL and Delphi Object Pascal
You cannot delete a file that is in use, unless the app that is using the file explicitly permits the deletion (by specifying FILE_SHARE_DELETE when opening the file). Nobody does that under normal usage, so you will need to detect when this condition happens (check GetLastError() when the deletion fails) and then. either 1) retry the deletion later or 2) ask Windows to delete the file on the next reboot (via MoveFileEx(MOVEFILE_DELAY_UNTIL_REBOOT)). -
A new Context is not created until a client is accepted. Only 1 Context is created per client. So, there must have been multiple clients accepted. But maybe a client didn't send a request. You should put that loop inside a try..finally block to ensure the list is always unlocked. The list will never hold a freed object, ie the pointers in it are always valid while inside of the lock. Make sure you are not accessing the pointers outside of the lock. There is no guarantee that a client assigned to a Context is still connected to the server while you are accessing the list. But the objects in a Context will still be alive while the list is locked.
-
I'll rephrase. Prior to the introduction of 64bit, the Tag was an Integer and pointers fit in an Integer, so it was common to store pointers in a Tag. When 64bit was added, the Tag became a NativeInt to preserve existing code in common use.
-
Using Python4Delphi library in a Windows service
Remy Lebeau replied to Luca Pretti's topic in Python4Delphi
That is correct. The TService's DataModule is created in the process' main thread, whereas its On(Start|Execute|Stop|Shutdown) events are called in a worker thread. -
Never a good idea... This function is not very accurate. A file can fail to open for any number of reasons, and you are treating all errors as success. A more accurate approach would be to open the file in exclusive mode and then check if the error code is ERROR_SHARING_VIOLATION specifically. Can you be more specific? What is the actual problem you are having with it?
-
Using Python4Delphi library in a Windows service
Remy Lebeau replied to Luca Pretti's topic in Python4Delphi
An AV near address 0 usually means a nil pointer is being dereferenced. Did you try debugging your service? Where and how are you creating the Python Engine? -
That is actually quite common, and is why the Tag is a NativeInt to begin with.
-
I can't answer that, since I don't know where you got those source files from to begin with. Those are 3rd party units, so you will have to figure out who authored them and ask them for updates, or find alternative replacements. This has nothing to do with Indy.
-
There has never been a 0.7 version of OpenSSL. In 2010, OpenSSL was at 1.0.0. 0.9.8 was released in 2005. OpenSSL 1.1.0 was released in 2016, and had significant changes to OpenSSL's APIs that are not backwards compatible with the older version your code apparently depends on. Your code needs to be updated to work with the newer APIs.
-
True. Now I see what the code is doing. It's stuffing the first 4 (32bit) or 8 (64bit) characters of the string directly into the NativeInt's bytes. So, if the string is longer than the NativeInt can hold, the remaining characters get lost. Storing the string's pointer into the NativeInt would preserve the entire string, but at the cost of having to manage its reference count properly.
-
Very bad idea. ReadTagString() is not so bad, but IDK what WriteTagString() is trying to accomplish. It is converting characters into bytes, completely ignoring the pointer that is inside the string. It is not the inverse of ReadTagString().