[lazarus] compile error on New Sources from cvs - FIXED

Micha Nelissen M.Nelissen at student.tue.nl
Thu Nov 27 15:27:40 EST 2003


Mattias Gaertner wrote:

> On Thu, 27 Nov 2003 19:22:37 +0100  Micha Nelissen
> <M.Nelissen at student.tue.nl> wrote:
> 
> 
>>Mattias Gaertner wrote:
>>
>>
>>>By using the the uses section in the implementation section you created
>>>some circles. This is allowed, but it makes the code harder to structure
>>>and less readable. They are allowed, but IMO you should try to avoid
>>>them.
>>
>>I find the current approach less readable: extra units (menutype in this 
>>case), extra definitions (TBaseMenuItem), unnecessary casting from 
>>TBaseMenuItem to TMenuItem, while we know it is a TMenuItem. 
> 
> 
> see below
> 
> 
> 
>>IMHO, the 
>>interface hierarchy is like this:
>>
>>high - lcl (delphi compatible) interface
>>      - generic platform independant interface
>>      - lcl itself: controls, stdctrls, etc.
>>low  - lcl type definitions
> 
> 
> I think we are talking about the same thing. Maybe a little bit more clear:
> 
> interface
>  .. uses ..
> LCL
>  .. uses ..
> interface base
>  .. uses ..
> base types
> 
> IMPORTANT:
> In the following context, the "LCL" is the lazarus component library. That
> means the OO components and not the interface functions. 
> 
>>From the user point of view this is the top level part, while the interface
> functions are the add ons, that are only used, if there is no LCL component
> to handle the task. In other words: The LCL wraps the interface in an object
> pascal way. 
> 
> For example: The user should never use the LCLCheckMenuItem. For the user
> this is a low lvl function. The LCL delegates and controls the interface.
> So, the interface base is below the LCL.
> 
> Our trick is, that the actual implementations of the interface (gtk, win32)
> overrides the interface base. And because the user does not use the real
> interface, we have the choice to put it wherever we want in the hierachy.
> And the easiest position for the implementation is above the whole LCL and
> its base. That's why we can use TMenuItem in the win32 intf. 
> This is only because of its hideous character. If we would use a perfect OO
> design, the implemented interface would ly right on the interface base and
> would not know the LCL. 

You've made a good point here. However it has problems:
1) It assumes that all interfaces need the same information for doing 
the same thing, so we can pass exactly that information. This assumption 
is false as proven by recent CheckMenuItem. If, and I hope when, the qt 
interface is going to be implemented it may need other kinds of 
information currently not passed through the parameters.
2) All these calls should be reported back. So CheckMenuItem not only 
checks the menuitem in the interface, but it should also report back to 
the lcl that it has checked the menuitem.

These two reasons combined, mainly reason 1 though, I'd still vote for 
the 'hideous' way, putting the interfacebase above the LCL in the 
hierarchy. This could also have the advantage that potential users 
aren't going to call the interface directly because it suddenly is a 
'higher' level. Everything the interfacebase can do, the lcl should be 
able to do. So by using the lcl, users have its full potential and power 
available.

> The other side:
> What would happen, if we put the LCL and the interface base on the same
> level?
> This would mean, a call of LCLCheckMenuItem and the use of
> AMenuItem.Checked:=true is equivalent. This would mean the LCL logic must be
> handled in the interface (unchecking if it is a radio item, etc.).
> I strongly suggest, that we do not try this way.

This seems like my reason 2) above. In essence, what you are then trying 
to do, as we are partly doing now, is make H... out of everything which 
only the interface knows about: HDC, HWND, ... and then are synced to 
their corresponding object in the lcl. It does have a clear advantage 
also: my reason 1) is also solved, because that H... carries the 
information the interface needs to know about. Disadavantage is that you 
have all, or a lot of it, information twice.

>>If we adhere to this order, nothing can go wrong. Things on lower level 
>>may use things on a higher level, but only when they need to implement 
>>functionality.
>>
>>
>>>If units are ordered hierachical, an user can start exploring the high
>>>lvl units and then go down, as he needs. But with unit circles, he needs
>>>to read the whole circle to understand what is going on.
>>
>>I think not many users read interface uses and 'know' what's meant when 
>>he reads an interface call.
> 
> 
> That's exactly my point. Although it seems, you can draw different
> conclusions from it.
> 
> 
> Back to the "unnecssary" casting:
> - it is always a good idea to check the input of a function 

This is true, but doesn't apply in this case if you ask me. Pascal has 
quite strong typing. So let's use that to our advantage to provide as 
much information as possible.

> - the interface functions can also be used by the user. Even if we say: Plz
> don't do. People will do.

Yes, this is unavoidable indeed. But how does it relate to unnecessary 
casting?

> - We can add function to TBaseMenuItem, so that te typecast is not needed.

Can you suggest an example?

Thanks for your reply,

Micha.







More information about the Lazarus mailing list