Jump to content

Der schöne Günther

Members
  • Content Count

    691
  • Joined

  • Last visited

  • Days Won

    12

Everything posted by Der schöne Günther

  1. Der schöne Günther

    NetHTTPClient

    You probably might want to read the "Important note about DLL memory management" you just posted.
  2. Der schöne Günther

    Choosing a Mac

    Thank you for your experience. I couldn't have told.
  3. Der schöne Günther

    Choosing a Mac

    Exactly the same configuration I am also considering. If you have something to share about your experience, please do tell.
  4. Der schöne Günther

    Choosing a Mac

    Can you give a rough estimate what you consider "enough" for both RAM (probably 16+ GB) and disk? I am not familiar with Parallels, and how its VMs tend to grow in size. PS: I found it surprisingly convenient to go the other way: Use the Mac as my main computer and remote into an old PC (hosting my Delphi Hyper-V machines) for doing Delphi stuff.
  5. Der schöne Günther

    Control Edge Downloads via TEdgeBrowser

    Haven't tried to run it, but looks legit to me. You will call add_StateChanged(..) to then monitor for the value to become COREWEBVIEW2_DOWNLOAD_STATE_COMPLETED. Are you using the latest runtime?
  6. Der schöne Günther

    Escaping UK pound sign in JSON

    Don't experiment and then forget about it. Write some proper unit tests so that they will always be with you and your project. 🧐
  7. Der schöne Günther

    Escaping UK pound sign in JSON

    None of this should be necessary. Just using a regular TJsonString outputs {"MyString":"The price is £20.00"} {"MyString":"The price is \u00A320.00"} Check: program Project1; uses System.JSON; var LText, LEscapedText: string; LJsonString: TJsonString; LJsonPair: TJsonPair; LJsonObject: TJsonObject; begin LText := 'The price is £20.00'; LJsonString := TJsonString.Create(LText); // Not your subclass TSvJsonString LJsonPair := TJsonPair.Create('MyString', LJsonString); LJsonObject := TJsonObject.Create(LJsonPair); try LEscapedText := LJsonObject.ToString; WriteLn(LEscapedText); LEscapedText := LJsonObject.ToJSON; WriteLn(LEscapedText); finally LJsonObject.Free; end; ReadLn; end.
  8. Der schöne Günther

    Best Practice Question: Bidirectional EXE-to-EXE communication

    Is there a public documentation how one has to implement "AppTethering" to be compatible? Otherwise, it's another vendor-lockin, and you're stuck with Delphi/C++ Builder for implementing both sides.
  9. Der schöne Günther

    Best Practice Question: Bidirectional EXE-to-EXE communication

    I recently did it to extend a Delphi application. The extension was written in C++ and is a regular console application. The Delphi "master" app launches it, sends it commands via stdin and gets result via stdout. It was super easy to test in isolation with a clients machinery because the console app can also be launched and used by a regular ... console window. Would definitely do so again. Not sure if it's a feasible solution if you need to rapidly exchange gargantuan amounts of data. For that, memory mapped files or sockets are probably a better approach.
  10. Der schöne Günther

    Best Practice Question: Bidirectional EXE-to-EXE communication

    There's tons of different IPC mechanisms. What you need depends on your requirements. If you already have the "logic" part in a separate console application, why don't use its stdin/stdout (which are already pipes)?
  11. That's an interesting approach, never seen it before. 🤔 To this day, I also go with try .. except Rollback; raise; end
  12. Der schöne Günther

    Embarcadero C++ Programmer for Engineering UK

    You have been having a vacant C++ developer position for over two years now? How many applicants did you get so far?
  13. Der schöne Günther

    D 11.3 Word occurrences marking - colour setting

    Ok great, that's exactly what I was hoping for. Looking forward to trying out 11.3 😊
  14. Der schöne Günther

    D 11.3 Word occurrences marking - colour setting

    Oh, really? That's rather useless. Documentation says it should be "anywhere on screen" Source: 11 Alexandria - Release 3 - RAD Studio (embarcadero.com)
  15. Der schöne Günther

    Windows Notification in Exe2 when Exe2 started from Exe1

    You should probably start by fixing your CreateProcessAndReturn(..): You pass the address of a constant string value into your lpCommandLine parameter, but if the parameter is passed, the memory must be writeable. Remove the const, and call UniqueString(AppName) before calling CreateProcess(..)
  16. Der schöne Günther

    restricting floating point range

    It's pretty verbose, but you can add your own struct with operator overloading (implicit assignment) that can throw an EArgumentOutOfRangeException when you try to stuff values outside of [0.0, 1.0] into it. While you're at it, you can overload the equality operator as well for just the precision you need. Or perhaps the add operator as well. So that adding 0.75 with 0.40 will result in 1.0. It depends on how you use these values. I'm sure the compiler is clever and won't even allocate more than the needed 4 bytes for the float.
  17. CreateProcess(..) returned a 2 which is ERROR_FILE_NOT_FOUND. Does the file exist at all? If not, have you simply tried reinstalling? I remember that Embarcaderos setups delegate installation to sub processes which are often blocked by Windows ransomware protection. As far as I recall, I had to completely disable Windows ransomware protection for the setup to even complete.
  18. Consider the following code: program Project1; uses System.SyncObjs, System.Threading; begin var counter := 0; TParallel.For( 0, 9, procedure(i: Int64) begin TParallel.For( 0, 9, procedure(i: Int64) begin TInterlocked.Increment(counter); end ); end ); Assert(counter = 100); end. It will entirely hang up. When I check the debugger, all worker threads are blocked by waiting for some event that is never happening. As the Parallel Library seems to be modelled after C#, I tried out the exact same thing which works as expected: var counter = 0; Parallel.For( 0, 10, i => Parallel.For( 0, 10, i => Interlocked.Increment(ref counter) ) ); System.Diagnostics.Debug.Assert(counter == 100); The documentation on TParallel.For also does not say anything about this.
  19. Der schöne Günther

    Nested TParallel.For: Immediate deadlock

    Thank you, that's also the temporary workaround I have come up with. I discovered it when running code from a library in a TParallel.For-loop that also made use of TParallel.For. They all implicitly used the default thread pool. Still, I'd like this caveat to be properly documented, and not to discover it in a running factory like I just did. And it still leaves me wondering why the C# runtime does not have these problems.
  20. Der schöne Günther

    Nested TParallel.For: Immediate deadlock

    Ooops, sorry - No. I updated my profile to Delphi 11. I noticed that it does run and produce the expected output when I lower the range to something like 0..6. As soon as it is 8² or more, it will block. Maybe it's depending on the number of cores. On my system, TThreadPool.Default.MinWorkerThreads will report 2 and MaxWorkerThreads is 4. It's just a guess, but I changes the example slightly: program Project2; uses System.SyncObjs, System.Threading; begin var counter := 0; const COUNT = TThreadPool.Default.MaxWorkerThreads * 2; TParallel.For( 0, Pred(count), procedure(i: Int64) begin TParallel.For( 0, Pred(count), procedure(i: Int64) begin TInterlocked.Increment(counter); end ); end ); Assert(counter = (COUNT * COUNT)); end.
  21. Der schöne Günther

    Need a "Delphi programming guideline"

  22. Der schöne Günther

    Puzzled by StrToDate

    Can confirm, works for me (Delphi 11.1).
  23. Der schöne Günther

    Detect if WebView2 Runtime is installed

    From my experience, this is sufficient: TWebBrowserHelper = class helper for TWebBrowser function getIsUsingEdge(): Boolean; end; function TWebBrowserHelper.getIsUsingEdge(): Boolean; begin Result := Assigned(GetEdgeInterface()); end;
  24. I think Embarcaderos wrapper does not throw any exceptions or displays error messages if it doesn't find the runtime, but I recall seeing an event that lets you check if loading was successful or not. Whether Edge is installed or not does not matter. You have to ship the WebView2 runtime. It is available as a standalone installer. It took me a few minutes to understand how to use TEdgeBrowser (or TWebBrowser), that the runtime must be installed and your Delphi app will need a "WebView2Loader.dll", but after that, I never had to tweak it again. We started shipping it even when TEdgeBrowser/WebView2 was still in preview.
  25. We are using the built-in TEdgeBrowser which is sufficient for our needs. I am guilty of taking the quick & dirty way out of Edge blocking local files by default. In one of our projects where we needed it, I simply have: Win32Check( SetEnvironmentVariable( 'WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS', '--allow-file-access-from-files' ) ); right in the DPR file. Above it is some kind of //TODO: Patch Vcl.Edge.pas so this is no longer necessary. Overall, I'm rather happy with the Edge Browser. We are using it to play videos, display and annotate PDFs, display web content and using rich HTML content editors like SunEditor.
×