Jump to content

Remy Lebeau

Members
  • Content Count

    2914
  • Joined

  • Last visited

  • Days Won

    130

Everything posted by Remy Lebeau

  1. No, I meant what I posted. An anonymous procedure is not necessary. TThread.ForceQueue() accepts both standard method closures and anonymous procedures as input, same as TThread.Synchronize() and TThread.Queue() do: type TThreadMethod = procedure of object; TThreadProcedure = reference to procedure class procedure ForceQueue(const AThread: TThread; const AMethod: TThreadMethod; ADelay: Integer = 0); overload; static; class procedure ForceQueue(const AThread: TThread; const AThreadProc: TThreadProcedure; ADelay: Integer = 0); overload; static; What I had left off by accident in my example was just the nil TThread parameter: TThread.ForceQueue(nil, SignForm.Show);
  2. Remy Lebeau

    Need help with IDhttp and Thread

    Did you try profiling your code to see where it is actually spending its time? You are starting a new TTask thread for each ListBox item, but running 100 threads simultaneously will not be faster than processing 100 items in batches of, say, 4-8 threads at a time. Creating more simultaneous threads does not mean the job will be completed faster. If anything, doing so will slow it down, because the OS can only handle so much work simultaneously, the more threads you have running the more time the OS has to spend switching between them. In general, you should not have more threads running than you have CPU cores. Have you tried using TParallel.For() instead? It uses a smaller pool of threads and will manage them according to its actual work load. Or, at the very least, you can use the TTask constructor that allows your tasks to use threads from a TThreadPool that you create. Also, don't pass TThread.Current to TThread.Queue(). That will link the queued operation to the thread, and if the thread terminates before the queued operation is performed, the operation will be canceled, and you won't see the thread's result in your UI. Better to pass nil instead in this case. Also, you are leaking the TIdHTTP object, and thus the TIdSSLIOHandlerSocketOpenSSL and TIdCookieManager objects. Also, there is no need to invoke your TRegEx logic in the context of the main UI thread (I wouldn't even use TRegEx at all), it should be invoked in the context of the TTask thread instead. Only the final ListBox addition (the only part of the thread code that actually touches the UI) should be queued, if it is to be performed at all.
  3. Remy Lebeau

    IPropertyStore

    Ideally yes. Or, you can just reset the variables locally before CoUninitialize() is called (don't forget to clear the PROPVARIANT, too), eg: var Store: IPropertyStore; v: PropVariant; InitHr: HResult; begin if OpenDialog1.Execute then begin InitHr := CoInitialize(nil); if FAILED(InitHr) and (InitHr <> RPC_E_CHANGED_MODE) then OleError(InitHr); try OleCheck(SHGetPropertyStoreFromParsingName(PChar(OpenDialog1.FileName), nil, GPS_READWRITE, IPropertyStore, store)); try OleCheck(store.GetValue(PKEY_Music_AlbumTitle, v)); try if v.vt = VT_EMPTY then Showmessage('Album Title not found') else Showmessage(v.bstrVal); finally PropVariantClear(v); // <-- add this end; finally store := nil; // <-- calls Release() end; finally if SUCCEEDED(InitHr) then CoUninitialize; end; end; end; However, Co(Un)Initialize() really should not be called more than 1 time per thread. For instance, in this case, they should be called at program startup/cleanup only, eg: private InitHr: HResult; procedure TMainForm.FormCreate(Sender: TObject); begin InitHr := CoInitialize(nil); if FAILED(InitHr) and (InitHr <> RPC_E_CHANGED_MODE) then OleError(InitHr); end; procedure TMainForm.FormDestroy(Sender: TObject); begin if SUCCEEDED(InitHr) then CoUninitialize; end; // the above would be better handled by moving Co(Uninitialize)() into // the main DPR directly, before TApplication is initialized, and after // TApplication.Run() is finished, respectively... ... procedure TMainForm.DoSomething; var Store: IPropertyStore; v: PropVariant; begin if OpenDialog1.Execute then begin OleCheck(SHGetPropertyStoreFromParsingName(PChar(openDialog1.FileName), nil, GPS_READWRITE, IPropertyStore, store)); OleCheck(store.GetValue(PKEY_Music_AlbumTitle, v)); try if v.vt = VT_EMPTY then Showmessage('Album Title not found') else Showmessage(v.bstrVal); finally PropVariantClear(v); // <-- still needed end; end; end;
  4. Another option I can think of is to delay showing the secondary Form until after the Main Form is done fully showing itself. For instance, via TThread.ForceQueue(), eg: procedure TMainForm.FormShow(Sender: TObject); begin SetScreensLang; if MustSignIn then begin TabControl1.ActiveTab := PersonalTabItem; TThread.ForceQueue(SignForm.Show); // <-- end else begin CheckAlerts; TabControl1.ActiveTab := AlertsTabItem; AlertsTabItemClick(nil); end; end;
  5. Remy Lebeau

    Need help with IDhttp and Thread

    That StackOverflow post already showed working code. If it is not working for you, then you are likely using it incorrectly, but we can't see the code you are using. Please show YOUR actual code that you are having trouble with, and explain HOW it is not working for you exactly.
  6. That should be easy enough to account for, using Random(16) to generate 4 random bits that can be shifted into the UInt64's bits 0, 31, 32, and 63 which the shifted Random(MaxInt) values will never fill in, eg: var Num, Bits: UInt64; Num := (UInt64(Random(maxInt)) shl 32) or UInt64(Random(maxInt)); Bits := UInt64(Random(16)); Num := Num or (Bits and 1); Num := Num or ((Bits and 2) shl 30); Num := Num or ((Bits and 4) shl 30); Num := Num or ((Bits and 8) shl 60);
  7. That makes no sense. {$ZEROBASEDSTRINGS} is local to the unit only. Its use depends on whether YOU want to access YOUR strings inside YOUR unit using 0-based or 1-based indexes, The IDE settings have nothing to do with that.
  8. (Low|High)(string) were introduced in XE3, the same version that introduced {$ZEROBASEDSTRINGS} and TStringHelper.
  9. That is easy enough to account for by using Low(String), eg: var s: String; c: Char; ... c := s.Chars[ZeroBasedIndex]; s[Low(s)+ZeroBasedIndex] := ...; Low(s) will be 0 for {$ZEROBASEDSTRINGS ON}, and 1 for {$ZEROBASEDSTRINGS OFF}.
  10. FYI, Embarcadero was considering making Delphi strings immutable in the NEXTGEN compilers, but they ultimately decided against that.
  11. You do know that is no longer necessary starting with RAD Studio 10.4, don't you? Embarcadero has moved mobile platforms away from ARC memory management for objects, and has done away with all of the NEXTGEN compiler features, which includes 0-based string indexing on mobile. Mobile now defaults to 1-based indexing, just like desktop platforms. If you really want to continue using 0-based string indexing, you can use {$ZEROBASEDSTRINGS ON}, or TStringHelper.
  12. Remy Lebeau

    Outdated Delphi Roadmap

    Updated plans for C++Builder were posted in July 2020: https://blogs.embarcadero.com/c-builder-and-platforms-support/
  13. Remy Lebeau

    Call a D7 dll from C#

    Assuming the calling convention of the DLL function is stdcall, then the correct PInvoke declaration in C# would be as follows: [DllImport("my.dll", CharSet = CharSet.Ansi)] static extern bool Mostra_Msg (string Parmsg); Alternatively: [DllImport("my.dll")] static extern bool Mostra_Msg ([MarshalAs(UnmanagedType.LPStr)]string Parmsg);
  14. Remy Lebeau

    IFileOperation recursion happens when set not to

    That applies to SHFileOperation(), but not to IFileOperation. You would have to either: - call CopyItem() for each desired source file individually. - call CopyItems() for the whole list of desired files.
  15. Remy Lebeau

    Delphi 10.4.1 and the IDE FIx Pack

    Yup, and here we are, months after the initial 10.4 release, and already into a new 10.4.1 release, and Embarcadero still hasn't stated one way or the other if they are even working on a Community Edition or not, let alone an ETA for it.
  16. Remy Lebeau

    How to detect when control is scrolled into view

    What is on the Cards exactly? When a UI has to display a lot of elements that start hindering performance, that is when I start considering either redesigning the UI to use different higher-performant controls, or switching to owner-drawing as much as possible to reduce resource usage.
  17. Yes. On Android, maybe, maybe not. ISAPI is IIS-specific, and support for ISAPI has been dropped from PHP. So, if you can execute the PHP CGI executable AND redirect its STDIN/STDOUT on Android, or if you can find a FastCGI processor that works on Android, or if you can compile the PHP core library (or 3rd party implementation) directly into your app, then you might have a chance.
  18. For the same reason that an updated IDEFixPack hasn't been released for 10.4.x yet - because Andreas doesn't have an active paid license for the IDE anymore, and Embarcadero hasn't released a 10.4.x Community Edition yet. See this topic:
  19. There was a recent discussion related to this topic in the AToZed Indy forum: Process PHP with TIdHTTPServer
  20. Which is funny, given that the syntax for helpers actually supports inheritance, but Delphi allows it only in class helpers, not in type/record helpers. FreePascal proves inheritance can work in all three kinds of helpers (just not in Delphi mode, for compatibility reasons).
  21. Remy Lebeau

    Tbutton Flashing

    Here is another idea - instead of flashing the Button itself, place it inside a Panel whose borders appear slightly beyond the Button's edges, and then flash the Panel as needed. Or, create an alpha-blended overlay window, place it over the Button, and then hide/show the window as needed.
  22. Remy Lebeau

    Indy package names

    Not yet. Updating the existing scripts to make sure they work properly is one thing. Adding new scripts for new IDEs is another, it is just one more headache to maintain. But if you want to provide some scripts, I'll look at them.
  23. Remy Lebeau

    Tbutton Flashing

    Not by default, but you can manually enable the BS_OWNERDRAW style on it, and then intercept WM_DRAWITEM messages sent to it. Then you can make it look however you want. Or, simply use a different Button control that supports custom coloring, like TBitBtn (which already has the BS_OWNERDRAW style) or TSpeedButton.
  24. Have you tried TortoiseGit yet?
  25. Remy Lebeau

    "Simulating" a com port with data arriving

    Yup, that is the one I use, too.
×