-
Content Count
1053 -
Joined
-
Last visited
-
Days Won
23
Everything posted by aehimself
-
I secretly hope that even after the release of 11.3 an LSP fix is going to be released for 11.2 since they figured out how to make one which is "best it's ever been". It's considered a nice business practice to deliver a usable product what you actually got paid for.
-
Not having to include the manifest file sounds promising, but this method only returns the OS version and nothing else. I might look into it in the future if I'll need that unit again.
-
Do not watch Task Manager to diagnose memory leaks. Windows often doesn't release the memory what the application is not using anymore but keeps it to speed up future memory allocations. I don't know if FastMM (ReportMemoryLeaksOnShutdown) will report a leak in a DLL, but you can request a trial of DeLeaker which will show you everything for sure. There's one thing for sure - there's no memory leak in System.SysUtils in the initialization / finalization section.
-
No, my updater is using the exact same mechanism and is working perfectly on every type of file (even system installed fonts).
-
Never used ICS's TFTPClient, but have you tried ftp.Get instead ftp.Put? You are leaking "FTP'. Uncomment the line in the finally section. Also, create the object outside, before the Try..Finally block.
-
TMS has a commercial package, you read more about it at https://www.tmssoftware.com/site/wupdate.asp I wrote my own, open source version which I am using in my main application for a while now and seems to do it's job properly. I attempted to build it up to be as versatile as possible but it's probably still a toddler compared with TMS when it comes to features, though. There's an example code on how to create an update file and how to update your application here:
-
-
We are developing a 20 year old application at work: over 1,5M LOC, 500-700 frames, couple thousands of units. Today we had a meeting with our teamlead where we successfully convinced him to allow the framework team to go for a full visual and codebase refactoring - effectively building it from the ground up once more; reusing mostly experience and tiny chunks of the original code (yeah, it's that bad). There are things what you can not delay any further. If this is what is needed to improve the coding experience devs will have to get used to the new model. It's for their own sake aswell, after all. With all that said, I'm fully aware that OP probably won't go in this direction. I'm leaving my remark here for future visitors, who might still be able to change their design seeing what the easy way can / will cause.
-
+1 for @Stano's idea. At a large number like this it's better to write a factory code and request these items runtime.
-
This is the method I ended up using: Procedure FixDateSeparator; Var Buffer: Array[0..2] Of Char; Begin If GetLocaleInfo(GetThreadLocale, LOCALE_SDATE, Buffer, 3) > 0 Then Begin FormatSettings.DateSeparator := Buffer[0]; FormatSettings.ShortDateFormat := FormatSettings.ShortDateFormat.Replace(FormatSettings.DateSeparator, '/'); End Else FormatSettings.DateSeparator := '/'; End; It's a close copy to Delphi 11.2's GetLocaleChar implementation which will fix the buffer underrun in prior versions. Add a TFormatSettings parameter and call it with "fmt" before you call StrToDate. This is the good news. The bad news is, parsing strings as dates was heavily refactored in D11. If the above won't fix your problem, you'll have to start playing around. For me the date format was "yyyy. mm. dd." D10.4 was happy to parse "2023. 02. 07" but D11 required the final dot.
-
In Delphi 11 they fixed the date separator, I had to include a new helper to bridge the difference between 10.4 and 11. Let's see if I can dig it up for you.
-
A comprehensive guide to Delphi programming language functions and procedures
aehimself replied to pouyafar's topic in VCL
Deleted. -
This will work as long as you have one instance in your application, or all your timers have the same handler.
-
Did you check the 3-rd party help? https://docwiki.embarcadero.com/RADStudio/Sydney/en/Indy "The RAD Studio CHM help of the Indy components is not provided when pressing the F1 button. However, RAD Studio provides a third-party help. Click Help > Third-Party Help > Indy Library Help to acces the Indy third-party offline help. "
-
Precision-wise probably nothing, multimedia timers are supposed to be the closest you can get. It is transparent though (you can see what is happening under the hood) and it is a drop-in replacement for TTimer which means 0 code change is required. It's also good to leave a variety of options so OP and future visitors can choose their favorite flavor.
-
I'm sorry, but that command became my Achilles heel. Don't use it.
-
You can give a try to TThreadedTimer. Not sure if it's that precise at millisecond level but it beats TTimer on everyday use.
-
I wrote my helper class for this purpose, it can be used and abused as one feels like it: Maybe it worth to revisit that code, I don't remember what lurks within it's lines.
-
var buffer: TBytes; read: Integer; Begin [...] read := Self.Receive(@buffer[0], Length(buffer));
-
Cross platform HTTP client with proxy support?
aehimself replied to softtouch's topic in Network, Cloud and Web
So we can use ChatGPT for reputation farming? 🙂 -
Where to put previously compiled dcu-files (subfolders in Lib folder)
aehimself replied to lookin030577's topic in Delphi IDE and APIs
You put your files wherever you like, just make sure you add those paths to the global / project settings. Copying them to the Lib is not a good idea so please don't do that 🙂 Let's say you create a folder, C:\DelphiComponents and you start to put your components here. For example, you download ICS and extract it to C:\DelphiComponents\ICS directory. In Delphi, go to Tools -> Options -> Language -> Delphi -> Library. The easiest solution is to add the folder where all source files are to the Library path field in all platforms, in our example C:\DelphiComponents\ICS\Source. At this stage you are ready to install and use the components and you don't have to worry about DCU locations, as the component will compile from the source and compiled DCUs will be placed in the project's own .\$(Platform)\$(Config) directory. Basically, Library path: the place Delphi will look for a referenced file, can either be a pre-compiled DCU or a .PAS source file. DCUs should be compiled in Release configuration Browsing path: locations where the editor's Code Browsing will look for source .PAS files when navigating Debug DCU path: in case you have pre-compiled DCUs in Library path, you can specify the same DCUs but in Debug configuration. During debugging these will be used so you can step in and debug the components source My suggestion is you set your library path to the source of the component and forget about platforms and configs if you are unsure. -
Generic from the RTL for sorted list of objects
aehimself replied to dummzeuch's topic in RTL and Delphi Object Pascal
So for years now I added that parameter without any particular purpose...? 😮 Time to revisit my old codes, then. Thank you for bringing this to my attention! -
Generic from the RTL for sorted list of objects
aehimself replied to dummzeuch's topic in RTL and Delphi Object Pascal
I have a hunch you can do the same if you override the protected Notify method somehow but yes, Uwe's solution will definitely work. Shouldn't this be TObjectList<V>.Create(True); ? -
Generic from the RTL for sorted list of objects
aehimself replied to dummzeuch's topic in RTL and Delphi Object Pascal
The only downside is, when adding a new key you'll have to do two commands: _dictionary.Add(myKey, TObjectList<TMyClass>.Create); _dictionary[myKey].Add(myObject); The neat thing is, you can nest them down until infinity, if you have the stomach to bear it. I personally start to feel uncomfortable after 2 🙂 -
Generic from the RTL for sorted list of objects
aehimself replied to dummzeuch's topic in RTL and Delphi Object Pascal
Only if you create them like: TObjectDictionary<T>.Create([doOwnsValues]); TObjectList<T>.Create(True);