-
Content Count
2914 -
Joined
-
Last visited
-
Days Won
130
Everything posted by Remy Lebeau
-
Showing secondary form from the main form OnShow event
Remy Lebeau replied to Mowafaq's topic in Cross-platform
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); -
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.
-
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;
-
Showing secondary form from the main form OnShow event
Remy Lebeau replied to Mowafaq's topic in Cross-platform
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; -
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.
-
Random unsigned 64 bit integers
Remy Lebeau replied to julkas's topic in Algorithms, Data Structures and Class Design
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); -
Is the missing System.TStringHelper SetChars in Chars property on purpose ?
Remy Lebeau replied to Rollo62's topic in RTL and Delphi Object Pascal
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. -
Is the missing System.TStringHelper SetChars in Chars property on purpose ?
Remy Lebeau replied to Rollo62's topic in RTL and Delphi Object Pascal
(Low|High)(string) were introduced in XE3, the same version that introduced {$ZEROBASEDSTRINGS} and TStringHelper. -
Is the missing System.TStringHelper SetChars in Chars property on purpose ?
Remy Lebeau replied to Rollo62's topic in RTL and Delphi Object Pascal
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}. -
Is the missing System.TStringHelper SetChars in Chars property on purpose ?
Remy Lebeau replied to Rollo62's topic in RTL and Delphi Object Pascal
FYI, Embarcadero was considering making Delphi strings immutable in the NEXTGEN compilers, but they ultimately decided against that. -
Is the missing System.TStringHelper SetChars in Chars property on purpose ?
Remy Lebeau replied to Rollo62's topic in RTL and Delphi Object Pascal
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. -
Updated plans for C++Builder were posted in July 2020: https://blogs.embarcadero.com/c-builder-and-platforms-support/
-
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);
-
IFileOperation recursion happens when set not to
Remy Lebeau replied to RTollison's topic in General Help
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. -
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.
-
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.
-
TIdHTTPServer -> run PHP code Cross-Patform including Android 10
Remy Lebeau replied to PavelX's topic in Cross-platform
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. -
Why is there no DDevExtensions for Delphi 10.4.1
Remy Lebeau replied to panie's topic in Delphi Third-Party
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: -
TIdHTTPServer -> run PHP code Cross-Patform including Android 10
Remy Lebeau replied to PavelX's topic in Cross-platform
There was a recent discussion related to this topic in the AToZed Indy forum: Process PHP with TIdHTTPServer -
Extending string - How to call the default record helper?
Remy Lebeau replied to Incus J's topic in RTL and Delphi Object Pascal
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). -
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.
-
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.
-
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.
-
Contributing to projects on GitHub with Subversion
Remy Lebeau replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Have you tried TortoiseGit yet? -
"Simulating" a com port with data arriving
Remy Lebeau replied to Dave Nottage's topic in Windows API
Yup, that is the one I use, too.