Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get Delphi to leave my DFM alone?

Using DXE2, I've written a form generator that creates both .pas and .dfm files. I am working on a routine that will allow me to modify different properties in the the dfm, such as Font.Height and TabOrder.

When I open a generated file in notepad, everything looks exactly as I expect it to. When I open it up in Delphi, the properties get changed! The thing that is so frustrating is that I am using a form originally designed in the Delphi IDE as my template. I don't understand why Delphi won't respect my simple changes...

For example, the original Font.Height is -11. I read in the dfm, change it to -17, and save it. In notepad, it shows the -17. When I open it in Delphi, it shows up as -21!

Any ideas/tips/suggestions would be greatly appreciated!

like image 667
skippix Avatar asked Mar 29 '12 14:03

skippix


2 Answers

My guess is that you have a mismatch between the PixelsPerInch on your machine and the value stored in the .dfm file. When Delphi reads the .dfm file it will scale any dimensions according to the ratio of the .dfm file PixelsPerInch and your machine's current PixelsPerInch.

Typical values of PixelsPerInch are 96dpi and 120dpi. Note that 17*120/96 = 21.

Now, as for TabOrder, the IDE will always write out the form order in consecutive values. So, if you have any values missing in your .dfm file then the IDE will write out a different version of the TabOrder values.

Note that you can't get Delphi to leave your .dfm file alone. Once you make any modification to the design space, and save the form, Delphi will stream it out in its preferred format.

This is really an unavoidable consequence of the way .dfm files are handled. The IDE never edits .dfm files directly in the same way it does with your .pas files. Instead it reads the .dfm file in, creates the components defined on the form, and assigns their properties. When the .dfm file needs to be saved again, the components are asked to stream themselves out. So the underlying model that is holds the settings is a TComponent instance (often a form for example) owned by the IDE rather than the .dfm file.

like image 116
David Heffernan Avatar answered Oct 23 '22 02:10

David Heffernan


What I do is let the IDE make what changes it wants to, and use Tortoise{HG,SVN,etc}+KDIFF3 to review (using its merge feature) and only commit the changes that I make, reversing those that the IDE made that I don't want to keep.

Steps:

  1. Go to the commit dialog of your version control system.

  2. For each DFM in the list, right click and "View Diff" or "Visual Diff" or whatever the view-differences command in your version control app is called.

  3. Your diff tool will come up. I use KDIFF3, but some people use BeyondCompare. I click "Merge -> Merge Current file" and then I revert all changes that it makes that I don't want.

  4. Save results of merge. Commit it.

Believe me, the craziness of DFMs is something that you will be astounded at. Every time you open a DFM and change it, every single TImageList in it will be modified, creating a difference for you to commit in your version control system, and if you have more than 1 developer on your team, you are just about guaranteed "merge conflicts". Start practicing "DFM hygiene" and you'll thank yourself later. When you do a manual merge like this, you're basically deciding to keep or revert, each "hunk" of the delta that would be committed into your version control system. What is shown below as "Conflict" is really "A or B choice". Hit Ctrl+1 to choose A, hit Ctrl+2 to choose B, and continue. You can quickly go through a huge number of accidental changes, keep only those which you intended to make, and then commit your DFM.

enter image description here

like image 3
Warren P Avatar answered Oct 23 '22 02:10

Warren P