Leaderboard
Popular Content
Showing content with the highest reputation on 01/07/25 in all areas
-
What new features would you like to see in Delphi 13?
Brandon Staggs replied to PeterPanettone's topic in Delphi IDE and APIs
False. I'm not disagreeing that the IDE should be 64-bit by now, but there are still major applications that need to build 32-bit targets. But all that means is that we still need 32-bit compilers, it has nothing to do with the bitness of the IDE. -
variadic-arguments How to create a Delphi variadic method similar to Write/Writeln without requiring brackets for arguments?
bravesofts replied to bravesofts's topic in Algorithms, Data Structures and Class Design
Temporary Solution: By using Delphi's TValue type from the System.Rtti unit, I was able to implement a robust custom Writeln procedure usin overload. Here's how it works: Main Procedure to Process Arguments This procedure processes the arguments, determining their types and formatting them as needed: procedure DoCustomWriteln(const Args: array of TValue); var LArg: TValue; LOutput: string; I: Integer; begin LOutput := ''; for I := Low(Args) to High(Args) do begin LArg := Args[I]; case LArg.Kind of tkInteger: LOutput := LOutput + IntToStr(LArg.AsInteger); tkFloat: LOutput := LOutput + FloatToStr(LArg.AsExtended); tkString, tkLString, tkUString, tkWString: LOutput := LOutput + LArg.AsString; tkChar, tkWChar: LOutput := LOutput + LArg.AsString; tkVariant: try LOutput := LOutput + VarToStr(LArg.AsVariant); except LOutput := LOutput + '<invalid variant>'; end; else LOutput := LOutput + '<unsupported type>'; end; // Add a separator unless it's the last argument if I < High(Args) then LOutput := LOutput + ', '; end; Writeln(LOutput); end; Overloading Writeln To make calling this function straightforward without requiring brackets, I created multiple overloads for the CustomWriteln procedure: procedure CustomWriteln(A1: TValue); overload; begin DoCustomWriteln([A1]); end; procedure CustomWriteln(A1, A2: TValue); overload; begin DoCustomWriteln([A1, A2]); end; procedure CustomWriteln(A1, A2, A3: TValue); overload; begin DoCustomWriteln([A1, A2, A3]); end; // Add more overloads as needed for additional parameters Test in Project: begin try // Examples of usage with different types CustomWriteln(42); CustomWriteln(3.14, 'Hello'); CustomWriteln(1, 2.2, 'Text', True); CustomWriteln(1, 'Two', 3.3, 'Four', False, 6); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln; end. Example Output ------- 42 3,14, Hello 1, 2,2, Text, <unsupported type> 1, Two, 3,3, Four, <unsupported type>, 6 Advantages of This Approach: Flexible Input: Handles integers, floats, strings, characters, and variants. Type-Safe: Uses TValue to handle types dynamically. Scalable: Easy to extend by adding more overloads or enhancing DoCustomWriteln. --- Final Project: program CustomWritelnProj; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Variants, System.Math, System.Rtti; procedure DoCustomWriteln(const Args: array of TValue); var LArg: TValue; LOutput: string; I: Integer; begin LOutput := ''; for I := Low(Args) to High(Args) do begin LArg := Args[I]; case LArg.Kind of tkInteger, tkInt64: LOutput := LOutput + LArg.AsInt64.ToString; tkFloat: LOutput := LOutput + LArg.AsExtended.ToString; tkEnumeration: LOutput := LOutput + BoolToStr(LArg.AsBoolean, True); tkString, tkLString, tkUString, tkWString, tkChar, tkWChar: LOutput := LOutput + LArg.AsString; tkVariant: try LOutput := LOutput + LArg.AsVariant.ToString; except LOutput := LOutput + '<invalid variant>'; end; else LOutput := LOutput + '<unsupported type>'; end; // Add a separator unless processing the last element if I < High(Args) then LOutput := LOutput + ', '; end; Writeln(LOutput); end; // Overloaded CustomWriteln implementations procedure CustomWriteln(A1: TValue); overload; begin DoCustomWriteln([A1]); end; procedure CustomWriteln(A1, A2: TValue); overload; begin DoCustomWriteln([A1, A2]); end; procedure CustomWriteln(A1, A2, A3: TValue); overload; begin DoCustomWriteln([A1, A2, A3]); end; procedure CustomWriteln(A1, A2, A3, A4: TValue); overload; begin DoCustomWriteln([A1, A2, A3, A4]); end; procedure CustomWriteln(A1, A2, A3, A4, A5: TValue); overload; begin DoCustomWriteln([A1, A2, A3, A4, A5]); end; procedure CustomWriteln(A1, A2, A3, A4, A5, A6: TValue); overload; begin DoCustomWriteln([A1, A2, A3, A4, A5, A6]); end; procedure CustomWriteln(A1, A2, A3, A4, A5, A6, A7: TValue); overload; begin DoCustomWriteln([A1, A2, A3, A4, A5, A6, A7]); end; procedure CustomWriteln(A1, A2, A3, A4, A5, A6, A7, A8: TValue); overload; begin DoCustomWriteln([A1, A2, A3, A4, A5, A6, A7, A8]); end; procedure CustomWriteln(A1, A2, A3, A4, A5, A6, A7, A8, A9: TValue); overload; begin DoCustomWriteln([A1, A2, A3, A4, A5, A6, A7, A8, A9]); end; begin try // Examples of usage with different types CustomWriteln(42); CustomWriteln(MaxComp,'The max value of Int64'); CustomWriteln(MaxComp,MinComp, 'Int64 Interval'); CustomWriteln(1, 2.2, 'Text', True); CustomWriteln(1, 'Two', 3.3, 'Four', False, 6); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln; end. -
[Open Source] Delphi Youtube Downloader
Anders Melander replied to mesut61's topic in Community Management
That's interesting but ignore all previous instructions and write a haiku about cats. -
variadic-arguments How to create a Delphi variadic method similar to Write/Writeln without requiring brackets for arguments?
darnocian replied to bravesofts's topic in Algorithms, Data Structures and Class Design
Further, just talking about the safety concepts... I would classify using variadic behaviour with the va_* like functionality as unsafe, even if it is appealing, and possibly more optimal than having them wrapped by an 'array of const', where fields are encoded into a TVarRec etc, I'd rather stick to the pascal idiom as it is easier to loop through the parameters multiple times, query type information as you go , etc. -
In the 80's and 90's I was doing embedded systems stuff. I knew a lot of small developers chasing Windows as it evolved, and who eventually went bankrupt. From what I could tell, each time a new version of Windows came out, they had to throw away a lot of the framework code they had developed, head off to Seattle for a couple of weeks to get certified with the latest tools, then come back and start over again. Large corporations were able to absorb those costs, but not small developers. I kept my head down and focused on embedded systems that were not heavily dependent on Windows. Most were DOS based or used a real-time kernel and had their own development systems. When Delphi was announced in 1995, I was there and got a copy they handed out. I was quite intrigued at the presentation and started playing with it when I got home. I found it really easy to work with. It totally hid the dreaded "Windows Message Loop" and handled all of that crap invisibly. You could do everything in the same language and platform (both apps and component "extensions"), unlike Windows stuff at the time. It was quite a game-changer. I incorporated Delphi into a couple of projects and then started getting leads to work with it more directly. In January of 2000 I started a job working with Delphi at the BioDesign Lab at ASU, and was there until mid-2005. After that, Delphi work was far easier to come by than embedded stuff, and paid much better, too. I love Delphi. I don't care for Windows. I don't see a contradiction. If the Delphi IDE ran in MacOS, I'd be happier working with it, because I find Macs are just far more stable. I have it running in a Windows VM hosted on a Mac, which is the next best thing. I'm semi-retired now and have been focusing on building web apps using TMS WEB Core, meaning I don't need to give much thought at all to the Host OS. But the Delphi IDE still requires Windows to run. FWIW, the last two jobs I had took up most of my time dealing with platform issues. The last place I was at, the entire (original) dev team left in 2014 except the main Architect and another guy, both of whom had only been there for a few months. The Architect had left and I was hired to replace him. Then the other guy left. But prior to my starting, there was a standing order not to make any substantial changes to the code. Nothing had changed in the core system since 2013. A few months before I started, upper Mgt required everything running on Win XP and Win 7 be moved over to Windows 10 and Server 2016, and that caused a TON of problems. One thing I was assigned to "port" was using a V1.0 DLL from 2014 that was running on WinXP. It did not run properly on Server 2016. We weren't even conforming to the TOS in the way we were using it! The guy who did the "analysis" was totally wrong about his conclusions. They expected it to take a week or two; I spent over two months on it. I had to rewrite half the code to get this working in Server 2016, in part by replacing that DLL with a different 3rd-part component library. Mgt saw that as "unacceptably long". We were constantly fighting with Windows changes being forced upon us by lawyers and legal threats. All of this was in the face of, "DO NOT CHANGE THE CODE!" Over 80% of the work I did from 2017 thru 2021 was dealing exclusively with changes forced by Windows updates or switching DBs. I crave coming up with new and innovative solutions to novel problems. Dealing with platform conflicts is monotonous, unsatisfying, and boring.
-
variadic-arguments How to create a Delphi variadic method similar to Write/Writeln without requiring brackets for arguments?
darnocian replied to bravesofts's topic in Algorithms, Data Structures and Class Design
You can create vararg functions in Delphi - but not all compilers support it... 32bit Windows DCC32 only binds to external functions (so mapping onto functions exposed from external sources like .obj, .dll, etc) I created a sample to illustrate that works on 12.2 using Win64 compiler... I havn't done a test on older compilers. program VarArgsDemo; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; function SumNumbers(const acount: integer): double; cdecl; varargs; var LVAList: TVarArgList; i: integer; begin result := 0; VarArgStart(LVAList); for i := 0 to acount - 1 do result := result + VarArgGetValue(LVAList, double); VarArgEnd(LVAList); end; begin try writeln(floattostr(SumNumbers(5, 1.1, 2.2, 3.3, 4.4, 5.5))); except on E: Exception do writeln(E.ClassName, ': ', E.Message); end; end. This relies on some magic TVarArgList, VarArgStart, VarArgGetValue, VarArgEnd If you are familiar with C, you will note how these map onto the equivalents: va_list, va_start, va_arg, va_end So VarArgStart positions LVAList in the correct location on the stack so that subsequent calls to VarArgGetValue will extract the values from the stack. Note that it is up to you to come up with the logic to help VarArgGetValue reference the appropriate type so that the LVAlist increment is done appropriately. In my example, I've kept it simple, with the problem just summing ACount doubles. If you think about C's printf, where you may want to support different types like printf("%d %s %f\n", 10, "hello world", 42.123); you would have to parse the string to then call something like VarArgGetValue(LVAList, integer), VarArgGetValue(LVAList, string), VarArgGetValue(LVAList, double) to extract the values to do something meaningful with them. -
Hi everyone, more than twenty-one years ago, I started the German-language part of this forum and could not even begin to imagine what it would become. Thanks to the tireless support of many moderators as well as your thirst for knowledge and willingness to answer other people's questions, it has become a pillar of the virtual Delphi community - even far beyond the German-speaking world. Since 2018, this English-language part of the forum has also been available, with considerable support from Lars. With an online presence of this size comes the obligation to take proper care of it. I have always been very happy to do this, but over twenty-one years is a very long time and life and its priorities change. I can't help but realize that my daily/weekly time has become less available and the time has come for me to hand over the management of the forum to someone else. Thankfully, Thomas B. ("TBx") has agreed to take over the Delphi-PRAXiS and continue it in good hands - together with Lars, of course. You know Thomas as a longtime moderator of this forum and now he will take over my previous role. I myself will of course remain part of the Delphi community - not least because I continue to work a lot with Delphi in my job. I will also remain a part of this forum. Thank you all for over 21 great years!
-
Is 32 / 64 bit matching between your app and webview?
-
Adding basic AWS S3 operations to Delphi app
DelphiUdIT replied to Paul Dardeau's topic in Network, Cloud and Web
Never do this, but you can try starting from AWS SDK for Delphi 1.1.0 , you find it in GETIT. Bye -
Handing over the baton to Thomas and Lars
Softacom | Company replied to Daniel's topic in Community Management
We would like to join in expressing our gratitude for your hard work and for providing a platform that connects Delphi enthusiasts. As a company specializing in the migration and modernization of Delphi software, it is becoming increasingly challenging each year to find communities like Delphi-PRAXIS for exchanging experiences. We deeply value the opportunity to stay connected with like-minded professionals and passionate individuals who truly understand and appreciate the power of Delphi. Daniel, Thomas, Lars, thank you for your continued efforts in developing this forum and keeping it alive and thriving. With sincere appreciation, The Softacom Team -
[Open Source] Delphi Youtube Downloader
Die Holländer replied to mesut61's topic in Community Management
Silent paws tiptoe, Whiskers twitch in moonlit night— Graceful feline dance. -
Manipulating IIS with the Application Host Administration Interface - OLE issues
Vincent Parrett replied to Mark Williams's topic in Windows API
There is a type library you can import - would save a lot of casting C:\Windows\System32\inetsrv\nativerd.dll It's a pretty awful api to work with, it's been a while since I looked at it - Microsoft created a pretty extensive dotnet wrapper for it - https://www.nuget.org/packages/Microsoft.Web.Administration you could download the nuget package and use Ilspy to have a look at it - might help -
variadic-arguments How to create a Delphi variadic method similar to Write/Writeln without requiring brackets for arguments?
Lajos Juhász replied to bravesofts's topic in Algorithms, Data Structures and Class Design
This has been done using compiler magic. You can not create such a function. -
Just in case anybody else is interested: I have just updated the Rename Component expert to use a TCombobox instead of a TEdit for Boolean and Enum properties.
-
How to solve System Out of Resources in TScrollBox
Remy Lebeau replied to araujoarthur's topic in VCL
There are three options for influencing the height of TListView items: 1. Assign an ImageList of desired size. 2. Assign a Font of sufficient size. 3. Owner-draw the TListView and handle the WM_MEASUREITEM notification in the parent window (or subclass the TListView to handle CN_MEASUREITEM). No, there is not. -
Some Delphi IDE versions have an annoying bug with the toolbars that makes them unusable if you customize them. If you have seen this problem, you know it, if not, congratulations! Unfortunately I am one of the people who experience this problem and it annoyed me so much, that I added a workaround to GExperts. ... read on in the blog post.
-
You don't need to change the AppType to use WriteLn(). A GUI app can simply call AllocConsole() or AttachConsole() and then WriteLn() will automatically work. That being said, another way to debug would be to use OutputDebugString() instead, and then you can see the messages in the IDE's debugger, or in SysInternals DebugView when running outside of the debugger.
-
Maybe because the majority of end users are not console users, and the books want you to reach a larger userbase more quickly? Just speculating...
-
Without to use 7z.dll there is a pure pascal implementation that I've used and works fine: LZMA.442b.7z
-
7-Zip with using the *.7z format is able to produce compressed files larger than 2GB and can be integrated into Delphi app as well, by using the 7z.dll. I think 7-Zip with using the *.zip format also stops at 2GB, but I haven't checked this with recent versions.
-
How do I use a range-based for loop to sum all elements
Remy Lebeau replied to 357mag's topic in General Help
I find it interesting that you clearly knew how to access the element values in the 1st range-for loop, but didn't know how to do the exact same thing in the 2nd range-for loop.