-1

I'm quite new to Delphi Pascal, and i'm not sure if this Question suits SO, but i don't really know where to ask this else.

My issue is, that i try to develop a Delphi Pascal application, that has an UI (nothing too complex, but rather an input mask with many inputs, such as TEdit, TComboBox, etc., aswell as a TVirtualStringTree that is used to display data (none database data for that matter)). Since there are many UI elements, i want to seperate some of the elements into their own units, to avoid overloading a single unit with dozens of procedures and functions handling the UI logic. However, since Delphi Pascal doesn't allow circular references, this doesn't seem straight forward (because i would need access to the original form, which contained the seperated element). I tried working around this, by just passing the said elements as a member into their own respective types in the seperated unit, but when i do this, i always get access violation exceptions (Am i doing something wrong?).

So therefore my question is, how to approach UI code cleanly in delphi pascal?

12
  • 2
    Maybe frames would help. Commented Mar 16, 2024 at 14:08
  • 2
    Frames would be separate units with their own collections of components and methods, and you can display the frames (or not) as needed. Commented Mar 16, 2024 at 14:24
  • 1
    Although I personally dislike it, Delphi actually allows circular unit references when they are in the implementation section. F.i.: If A uses B in the interface section then B can use A in the implementation section. Commented Mar 16, 2024 at 15:16
  • 5
    The "correct" way to handle this is to de-couple your data/logic from your UI. Your data/logic code should have no knowledge of your UI code, and vice versa. Use properties, callback/events, etc to pass around data from one to the other as needed. That will better isolate your code, make it easier to test and update, etc Commented Mar 16, 2024 at 22:52
  • 3
    "I tried working around this, by just passing the said elements as a member into their own respective types in the seperated unit, but when i do this, i always get access violation exceptions (Am i doing something wrong?)." Probably, but we'd need to see an example of your code to determine what you're doing wrong. Commented Mar 19, 2024 at 1:13

1 Answer 1

1

Delphi does allow "circular references" to a point. In your main form you can add references to your other units in the interface uses clause. In the other units you reference the main form in the implementation uses clause. You could also do it the other way around. You just can't have references in the interface section for both units/forms.

I also don't think there is a huge problem with dozens of routines that handle the UI, existing in one unit. It comes down to striking a balance between one big file or lots of little files. Which is easier to maintain? Some Delphi source files have many thousands of lines (e.g. System.Classes.pas has more than 20,000 lines). Don't be afraid of big files.

Sign up to request clarification or add additional context in comments.

2 Comments

Yes, but this means (like i mentioned in the comments of the post) that there can't be a member of type A (unit uA) in type B (unit uB), because i can't reference the unit uA in the declaration of type B before using unit uA (and vice versa). However, as mentioned, Ron Maupin's solution works just fine. Sure, big files are normal, but i personally prefer to have a modular structure with units only containing it's relevant variables and procedures/functions in itself. Also, i think a lot of LOC's could be saved if Delphi had DataBindings (like e.g. WPF).
I'm not familiar with frames, I'll have to have a closer look at them. FWIW, when I can't get around having to have circular references in the interface section, I declare a variable as a basic TObject or Pointer in the interface section and then cast it to the actual object when I access it in the implementation section. It's not perfect but it works. Just another way to skin the cat :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.