The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,839 other subscribers

Archive for the ‘Delphi’ Category

Where do you place your unit uses?

Posted by jpluimers on 2019/04/18

Over the years, I have had the question of where to put uses list entries a lot.

Last year, there was one again from a very experienced developer: [WayBack] Where do you place your unit uses? Over the years, I’ve come to preferring to place my uses in the Interface section only, even if its types, constants… – Lars Fosdal – Google+

The answer is really simple, and comes down to this:

  • use only the units you need (Law of Demeter)
  • use the units as close as possible to where you need them (this helps Minimizing Scope which is related to Information Hiding and the Proximity Principle)

Besides these Clean Code and Code Complete arguments, there is another very important argument:

The larger the scope of a unit, the more resources it takes to compile your project.

This gets worse when you have cycles in your unit dependencies.

I think it gets more than progressively worse; I have seen ~5 million line projects use close to 2 gigabytes of RAM during compilation when they had deep/long cyclic dependencies, forcing a full project build with DDevExtensions configured correctly in order to avoid out-of-memory at all.

For the above question, the poll seems to indicate the public at large gets it right:

References

A few tips from the thread:

Read the rest of this entry »

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

Just found out about the SysUtils.FindCmdLineSwitch Function

Posted by jpluimers on 2019/04/17

I learn new things every day. So today I learned about [WayBackSysUtils.FindCmdLineSwitch Function, which was introduced in Delphi 4, but I was still messing with ParamCount/ParamStr loops.

It as not changed over time. The above docs are Delphi 2007, and these are some of the newer:

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

Debugging RTL/VCL Code with CodeSite – Dave’s Development Blog

Posted by jpluimers on 2019/04/17

This is so cool! [WayBackDebugging RTL/VCL Code with CodeSite – Dave’s Development Blog.

It comes down to performing CodeSite.Send(...) calls as evaluation expressions in non-breaking breakpoints.

Ensure you have the CodeSite.Logging unit in your uses lists and you’re good to go.

Thanks David for pointing me to this!

This is even more useful than the breakpoint Log Message itself (which is only a string) or plain Eval Expression (which puts just one item into the Delphi event log) despite them being there since Delphi <= 5:[WayBackDebugging code in Delphi XE – Stack Overflow.

–jeroen

via: [WayBack] Debugging RTL/VCL Code with CodeSite – David Hoyle – Google+

 

Posted in Delphi, Development, Software Development | 2 Comments »

Delphi annoyance: in debug mode, no breakpoints are being adhered to, no blue bullets

Posted by jpluimers on 2019/04/16

For all Delphi Galileo versions (the BDS based Delphi versions: 8 until now), I have bumped into this annoyance:

Over time, while working on an application, running it in DEBUG mode in the debugger, wil not fire any breakpoints and all blue bullets (meaning the lines have code generated) are gone.

There are no warnings or (error) dialogs leading to this situation.

The only remedy is to quit Delphi, start it again, then do a full rebuild of the application.

Of course this happens more often with large applications than with small ones.

Is there anyone who has a reliable method to:

  • signal this before it happens
  • workaround it in a better way

–jeroen

Posted in Delphi, Development, Software Development | 1 Comment »

delphi – IfThen(Assigned(Widget), Widget.Description, ‘No Widget’) doesn’t crash. Should it? – Stack Overflow

Posted by jpluimers on 2019/04/16

Very interesting question [WayBackdelphi – IfThen(Assigned(Widget), Widget.Description, ‘No Widget’) doesn’t crash. Should it? – Stack Overflow.

Three important things here:

  • depending on inlining and kind of arguments, function calls can evaluate their arguments one or multiple times
  • lacking formal language specification, you never know if a method will be inlined or not
  • function calls should not have side effects

Via another interesting discussion at [WayBack] Inline functions are not guaranteed to evaluate their arguments exactly once… – David Heffernan – Google+

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

including enumerations and JPEG compression examples for wPDF 4 Manual: Compression related properties

Posted by jpluimers on 2019/04/11

Since I was tracking down an issue having to to with generating DIB in a compressed PDF: [Archive.is] wPDF 4 Manual: Compression related properties

Property CompressStreamMethod

By modifying this property you can let the PDF engine compress (deflate) text. By using compression the file will be reasonable smaller. On the other had compression will create binary data rather than ASCII data. While “deflate” produces the smallest files, “run-length” compression is compatible even to very old PDF reader programs.

Property JPEGQuality

wPDF can compress bitmaps using JPEG. This will work only for true color bitmaps (24 bits/pixel) and if you have set the desired quality in this property.

Property EncodeStreamMethod

If data in the PDF file is binary it can be encoded to be ASCII again. Binary data can be either compressed text or graphics. You can select HEX encoding or ASCII95 which is more effective then HEX.

Property ConvertJPEGData

Note: Only applies to TWPDFExport.

If this property is true JPEG data found in the TWPRichText editor will not be embedded as JPEG data. Instead the bitmap will be compressed using deflate or run length compression. It is necessary to set this property to TRUE if the PDF files must be compatible to older PDF reader programs which are incapable to read JPEG data.

Note that EncodeStreamMethod does not do compression, but it does belong here because the encodings result in different PDF sizes.

The settings are not documented in more detail, so here are the enumerations explaining them in a bit more depth:

–jeroen

Posted in ASCII95, Delphi, Development, Encoding, HEX encoding, Software Development | Leave a Comment »

Some notes on Testinsight Issues

Posted by jpluimers on 2019/04/10

So I won’t forget:

Note to self:

Read the rest of this entry »

Posted in Delphi, Development, Software Development, TestInsight | Leave a Comment »

ILockable/TLockable/Lockable. Similar to IManaged in Spring4D, but provides a Locked interface.

Posted by jpluimers on 2019/04/10

Had to use this to start solving threading issues in a project I inherited a while ago in a temporary way before doing a huge refactoring. Will likely need it in the future as well: ILockable/TLockable/Lockable. Similar to IManaged in Spring4D, but provides a Locked interface..

ILockable/TLockable/Lockable. Similar to IManaged(now IShared) in Spring4D, but provides a Locked interface.

Note this is very inefficient, but can be practical as a shotgun approach to start solving the mess when you inherit a project that has the “I know, I’ll use threads!” approach in it.

Replace the resource typed TNeedsLock that needs protection with a ILockable<TNeedsLock>, then route all references via a call to the Locked()() call to it.

If you need a simpler approach, then use [WayBack] Interfaced monitor lock — Bitbucket by Stefan Glienke.

–jeroen

Read the rest of this entry »

Posted in Conference Topics, Conferences, Delphi, Development, Event, Multi-Threading / Concurrency, Software Development | Leave a Comment »

Detecting the Delphi edition that is installed

Posted by jpluimers on 2019/04/09

Via [WayBack] In what ways can you detect which edition of Delphi in installed from the installed files? I’m trying to distinguish between Standard, Professional, E… – Jeroen Wiert Pluimers – Google+

Different Delphi editions have different msbuild support files. For instance IDL is only available in Enterprise/Architect/Ultimate (which use the exact same binaries anyway).

IDL is old, see

So I updated my [WayBack] jeroenp / wiert.me / Run-Dependend-rsvars-From-Path.bat — Bitbucket (which besides running rsvars.bat, can start the various Delphi IDE personalities, or run msbuild with various configurations) with [WayBack] jeroenp / wiert.me / commit / 2c55fa1bf786 — Bitbucket:

Support 10.1 Berlin and 10.2 Berlin in Run-Dependend-rsvars-From-Path.bat, as well as Professional/Starter editions.

Thanks to Andrea Magni – Google+, Querying was simple: look for the value of the Edition entry under inside the *\X\BDS\Y.0 where Y is the BDS version, X is Borland, CodeGear or Embarcadero (depending on the BDS version) and * is the base key HKEY_CURRENT_USER\Software, HKEY_LOCAL_MACHINE\SOFTWARE , HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node.

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

When generics and VCL controls bite you: memory overwrites when you show the control usually ending up in access violations

Posted by jpluimers on 2019/04/09

Recently I got bitten by the 2013 reported http://qc.embarcadero.com/wc/qcmain.aspx?d=112101 (too bad the site is gone and the WayBack machine doesn’t have it archived) as a result of [WayBackdelphi – Why do I get access violations when a control’s class name is very, very long? – Stack Overflow.

It got reentered as [RSP-18399] Buffer overflow in TWinControl.CreateParams() – Embarcadero Technologies but since that requires logon, it’s not search machine indexed so it’s very hard to find unless you know where to look.

So I spent a quite some time to find out what was wrong:

Since Delphi 1, the [WayBackControls.TCreateParams Record has a 64-byte WinClassName field that’s blindingly copied by the TWinControl.CreateParams without range checking.

The structure is used by the [WayBackTWinControl.CreateWnd Method to call the Windows API [WayBackRegisterClass function that takes a [WayBackWNDCLASS structure with a lpszClassName field that supports up to 256 characters and it fails when it’s longer.

That overwrite cause spurious other errors depending on the memory that gets overwritten. It took almost a day to figure out the cause of the error was this field, then an hour or to track that down to the long class names created by generic code.

To my surprise, I found back [WayBack] This issue caused coworkers and me quite a few hours wasted:Long story short – refactor some forms/frames to class names longer than 64 chars and boom… – Stefan Glienke – Google+.

As of Delphi 8 (yes, that version that a lot of people want to forget, but did bring a few good things), the structure was defined as below, and the code intialising also got improved:

Params.WinClassName := ClassName;
...
Params.WinClassName := Format('%s.%d', [Params.WinClassName, AppDomain.CurrentDomain.GetHashCode]);

So there it’s a string that – if it is too long – will get rejected by the Windows API anyway just like the native Delphi VCL implementation should have done 20+ years ago.

The sad part for FMX users: that structure and code got blindingly copied to the FMX.Controls.Win unit.

Read the rest of this entry »

Posted in Delphi, Development, Software Development | Leave a Comment »