Der schöne Günther
Members-
Content Count
693 -
Joined
-
Last visited
-
Days Won
12
Everything posted by Der schöne Günther
-
RIO: Start Debug Session changes source
Der schöne Günther replied to PeterPanettone's topic in Delphi IDE and APIs
I was talking about a "version control" system that helps you keeping track of what files were changed, when, and why. Notable examples include Git, Mercurial or the good old Subversion. -
RIO: Start Debug Session changes source
Der schöne Günther replied to PeterPanettone's topic in Delphi IDE and APIs
Did you really add your .res file to your project? I think it's an auto-generated one and you should neither have it in source control, nor added to your project... -
Funny Code in System.Types
Der schöne Günther replied to Fritzew's topic in RTL and Delphi Object Pascal
I think it was Nick Hodges who called out for Embarcadero to make their unit tests open source and let the community contribute. Unfortunately, not much happened. Personally, I assume that there are unit tests, but only very few. Otherwise, things like that System.Generics.Collections disaster with XE8 certainly wouldn't have happened... -
I have never done that but thank you for encouraging me! I just found out that, at least in my special case, the IDE runs into this error when you Are using the form designer Edit -> Hide non-visual components (Ctrl+H) Close the project After that, the registry path HKEY_CURRENT_USER\Software\Embarcadero\BDS\17.0\Form Design has "Show NonVisual Components"="False" This appears to be deadly. Just setting this value back to "True" makes my RAD Studio work again. I am on Delphi 10.0 Seattle. Not sure if it also affects other versions.
-
Can you still open the ancestor frame in the form designer? Several times a week, my IDE somehow corrupts itself so that the form designer does no longer work for inherited frames. I then load a backup of my registry for HKCU\Software\Embarcadero\BDS\17.0 and everything is fine again for the next few days. I'm on 10 Seattle. Apart from that, it sometimes also just corrupts the DFM files for a frame. Your version control should be able to show you what happened.
-
track process execution
Der schöne Günther replied to Detector's topic in RTL and Delphi Object Pascal
Your question is relatively vague. I guess the technical definition of "programs executed" means "whenever the WinApi CreateProcess(..) routine is called"? In that case, the Microsoft or MahdiSafsafi libraries are probably the fastest way: https://github.com/MahdiSafsafi/DDetours https://github.com/microsoft/detours/wiki/Using-Detours -
Undocumented "Interface flag" for IInvokable?
Der schöne Günther posted a topic in RTL and Delphi Object Pascal
You can use the RTTI to evaluate certain properties of interace types. Please see the following snippet: program Project1; uses System.Rtti; var context: TRttiContext; rttiInterface: TRttiInterfaceType; begin context := TRttiContext.Create(); rttiInterface := context.GetType( TypeInfo(IInterface) ) as TRttiInterfaceType; rttiInterface.IntfFlags; // is [ifHasGuid] rttiInterface := context.GetType( TypeInfo(IInvokable) ) as TRttiInterfaceType; rttiInterface.IntfFlags; // is [3]. 3 is not a valid enum value end. You can put a breakpoint on both lines with a comment for evaluating the value of IntfFlags yourself. IInvokable (and every interface that derives from it) has an undocumented value of "3". What does it mean? I have not been able to find anything in the source code. Clearly, System.TypInfo.TIntfFlag is declared as TIntfFlag = (ifHasGuid, ifDispInterface, ifDispatch); -
Undocumented "Interface flag" for IInvokable?
Der schöne Günther replied to Der schöne Günther's topic in RTL and Delphi Object Pascal
I wonder where this value actually comes from. I guess not from RTL code that exists as a .pas file? -
Is it possible to know when a TObject is instanciated/freed?
Der schöne Günther replied to santiago's topic in General Help
Maybe this could be related? http://blog.marcocantu.com/blog/2017-june-delphi-packages-creators-update.html -
What's so interesting about that? I still don't get quite behind that language server thing. I see that they will be able to delegate things like Code Completion and Error Insight to some external process in the background. Is that also going to work the other way round? Will tools like VS Code be able to access Delphi's debugger? I am already looking forward to 10.4 because of High DPI. Maybe I will once again be able to use Delphi at home, not just at work.
-
ITask.Wait() behaving differently when called multiple times
Der schöne Günther posted a topic in RTL and Delphi Object Pascal
Consider the following: uses System.Threading; procedure TForm1.Button1Click(Sender: TObject); var task: ITask; begin task := TTask.Run( procedure() begin raise EProgrammerNotFound.Create('test'); end ); try task.Wait(); // << raises EAggregateException except ShowMessage('ex'); end; task.Wait(); // no exception. returns true // task.Status is now TTaskStatus.Exception end; I find this irritating. Why does waiting for a task raise an exception one time, but not the other? Apart from the fact that the Embarcadero documentation on ITask.Wait(..) does not even mention an exception should be expected, I guess they (once again) modelled it after .NET's Task.Wait(..) method which clearly states an exception is to be expected if the task was cancelled or failed with an exception. Some fine gentleman even reported this to Embarcadero almost five years back: https://quality.embarcadero.com/browse/RSP-9548 But two years later, it was closed as "Works as expected". I still don't understand. Can someone elaborate? I believe the implementation is wrong. -
ITask.Wait() behaving differently when called multiple times
Der schöne Günther replied to Der schöne Günther's topic in RTL and Delphi Object Pascal
Thank you for taking the time to explain. It sounds like a good point, although a bit artificial 😉 And I have trouble achieving just that. Even with something like procedure TForm1.Button1Click(Sender: TObject); var task: ITask; e: Exception; begin event := TSimpleEvent.Create(); task := TTask.Run( procedure() begin raise EProgrammerNotFound.Create(EmptyStr); end ); try try task.Wait(); finally task := nil; end; except e := Exception( AcquireExceptionObject() ); end; end; The task still lives. Maybe because the default thread pool still has a reference to it. -
ITask.Wait() behaving differently when called multiple times
Der schöne Günther replied to Der schöne Günther's topic in RTL and Delphi Object Pascal
Thank you for replying. If that can happen, then yes, then that won't work. But right now, I have no idea how that could happen, to be honest. In order to catch the exception, I have to call .Wait() on the task - Meaning I have to have a reference to it. Meaning the task cannot be freed yet. What am I missing? -
ITask.Wait() behaving differently when called multiple times
Der schöne Günther replied to Der schöne Günther's topic in RTL and Delphi Object Pascal
And because of that, it's even more important the exceptions do not get lost and you get a reliable and reproducible behaviour. 😎 As so often, it seems to be modelled after .NET. And what .NET does (raise the exception(s) every time you wait for the task) is perfectly achievable with Delphi. I just don't understand why they took this weird approach. -
ITask.Wait() behaving differently when called multiple times
Der schöne Günther replied to Der schöne Günther's topic in RTL and Delphi Object Pascal
There is no need to change anything about raising exceptions or lifetime management of exceptions. It's just that an EAggregateException always owns the exception it refers to. I believe that should be optional. Raise the exception normally, or acquire ownership and free it later - It doesn't matter. As long as the task owns its exceptions, not the EAggregateException. You can do with the AggregateExcption whatever you like. It's not the same, but TThread is similar. It has a FatalException property you can query for the exception that happened in the thread. The exception is owned by the thread. It is there for as long as the thread object is alive. With the way tasks are implemented, the first one to call .Wait() on a task gets the exceptions - After that, they're gone. It makes no sense. -
ITask.Wait() behaving differently when called multiple times
Der schöne Günther replied to Der schöne Günther's topic in RTL and Delphi Object Pascal
But "the exception" is an artificially generated EAggregateException that references exceptions that are already stored. The "true" exceptions have never been raised directly. There would be nothing wrong with raising an EAggregateException that does not own the exceptions it referred and instead the task can free those exceptions when it is destroyed. Which is what was suggested in https://quality.embarcadero.com/browse/RSP-9548. Wouldn't that solve all those problems? -
ITask.Wait() behaving differently when called multiple times
Der schöne Günther replied to Der schöne Günther's topic in RTL and Delphi Object Pascal
Does that mean 10.3 raises an exception for both times? Because I accidentally typed it would raise an EOperationCancelled. It does, in fact, properly raise an EAggregateException. But just for the first time. -
Is it possible to raise an aggregated exception?
Der schöne Günther posted a topic in RTL and Delphi Object Pascal
Consider the following: I have a method that raises an EAggregateException that only contains one inner exception In my try block, I would like to extract the one inner exception and raise this instead. procedure raiseAggregate(); var innerExceptions: TArray<Exception>; aggregateException: EAggregateException; begin innerExceptions := [EProgrammerNotFound.Create('hello')]; aggregateException := EAggregateException.Create(innerExceptions); raise aggregateException; end; procedure TForm1.Button1Click(Sender: TObject); begin try raiseAggregate(); except on e: EAggregateException do begin if (e.Count = 1) then raise e.InnerExceptions[0] // <<< that would be too easy else raise e; end else raise; end; end; How do I do this? I cannot simply use raise e.InnerExceptions[0] because e gets destroyed at the end of the try..except block. This is a problem because e owns its inner exceptions. When e gets destroyed, I have basically raised a destroyed exception. In case you're not familiar with the System.Threading.EAggregateException, you check the .NET documentation. Embarcadero documentation does not exist. -
Is it possible to raise an aggregated exception?
Der schöne Günther replied to Der schöne Günther's topic in RTL and Delphi Object Pascal
So far, the only solution I have come up with is ripping out the wanted exception with a class helper 🤷♂️ and then raise this exception instead. function EAggregateExceptionHelper.Extract(const index: NativeInt): Exception; var newArray: TArray<Exception>; arrayIndex: NativeInt; begin newArray := []; Result := nil; with self do begin for arrayIndex := Low(FInnerExceptions) to High(FInnerExceptions) do if(arrayIndex = index) then Result := FInnerExceptions[arrayIndex] else newArray := newArray + [FInnerExceptions[arrayIndex]]; FInnerExceptions := newArray; end; end; -
I don't use Visual Studio for Git, but Visual Studio Code with GitLens. And, from time to time, the Windows explorer integration from TortoiseGit. As far as I recall, Visual Studio didn't even have support for Git stashes until VS 2019.
-
There's not just VSC. Have a look at this: I honestly couldn't care less about the form designer. As horrible as it actually is, it's probably just too much work to completely rewrite it for another environment. Proper debugging capabilities are way more important.
- 29 replies
-
- delphi ide
- delphi
-
(and 2 more)
Tagged with:
-
Are you sure it's a capacitive touch screen or something more sophisticated that works with a "proper" pressure-sensitive pen? There are quite a lot of W10 devices that have an additional digitizer for pen input.
-
Interesting read: https://ux.stackexchange.com/q/84715
-
Trouble with (very) simple XML-parsing
Der schöne Günther replied to Tommi Prami's topic in RTL and Delphi Object Pascal
Doesn't getElementsByTagName(..) only list direct descendants? You will either have to search recursively, or use something like an XPath expression to get all the nodes you are interested in. -
ANN: Find leaks in Delphi and C++ with Deleaker
Der schöne Günther replied to Artem Razin's topic in Delphi Third-Party
That looks very exciting, but I do find the prices a bit steep 😶 Does one license work with both RAD Studio and Visual Studio integration? For VS, does it find leaks for C++/CLI Mixed mode applications?