I already told that I think that release method should be studied a bit upon.

To me, release() should never delete the window itselft and its
objects recursively. It should never call __objDelData (if I previusly
said that it should do, I was wrong).

I try to explain why:

Imagine you have class window and 2 istances, like in:

W1 := Window():New()
W2 := Window():New()

If we add a label called "label01" to W1 internally hmg4 calls
__objAddData( w1, "label01")...

unfortunately, __objAddData (that is a internal function and should
not be called directly) adds label01 TO THE CLASS and not to the
instance !!!
You can check this with ? W2:label01 that returns NIL and doen't raise
an error !!!!!!!!!!

So, this must be taken care of, it's not really a problem, everything
is working... but programmers should know that it is unreliable to
test for method/data existance to understand which object we are
dealing...

Suppose that W2 goes out of scope earlier than W1... when it goes out
of scope, and we call __objDelData recursively... ooopss, label01
disappears ?!

Harbour VM retrieves the oWindow object, then looks for "OLABEL"
inside it. Since it is not present, it calls the CLASS error handler.
In the XbpWindow:onError( ... ) method the "message" is retrieved
(message is "OLABEL") and in this specific case the message is used as
method on another object, it works as a layer...

Since we have the "message" we can do with it what we need. My
proposal (not really mine since Luigi already did some tests
indipendently with nice results using Hash to store objects and
something I already saw used in other situations) is to use an Hash to
store the children objects.
As we said in other threads, the objects (label) is stored in 3
places. IN a variable, in a list of objects in the parent, as a data
member.
With my proposal the data member is "emulated" and the list of objects
converted from array to Hash. oWindow:oLabel syntax is still valid.
With Hashes, every object members count doesn't grow. And it's
probably way easier to handle the children objects.

There is still one problem to solve... the release() stuff...

If we want to DELETE a window we can do it without problem, Harbour VM
should take care of everything and there should be no necessity for
recursive deleting... when VM deletes the window object tha hash (that
is a member) should be deleted item by item by the VM... if it's not
the case, a destructor method will be needed...

You will find the changes in addData and delData. Hash based implementation is at the bottom of basic.prg.
In this sample the added methods are public but they will be made protected.

The ::StartHash() line should be added to all widget source code whose New() method is overloaded and the super:new() method from basic.prg is not called (like in window.prg, where super:new() is not called...).

I tested it only on samples\slider\demo_1.prg and it is too late to do other tests. It should work on several other simple samples whose widgets call the new() of basic class, otherwise you need to add the ::StartHash() line...

Hi my friends.
For work reasons, I can spend little time to HMG and I'm very disappointed but I would like to leave a constructive contribution.I hope that my words are not misinterpreted and that my English can rise to the occasion
I believe that the structure, stability and performance of the current HMG4 version is not satisfactory.

As all of you know, to propose solutions for HMG4, I developed a small fork.
It has limitations too and has various problems, but I hope that these ideas/suggestions are useful to improve HMG4.

first item: the layout of classes
I believe we must carefully observe the structure of Qt. create the necessary classes, but maintaining a flexible structure that adapts to our project. For example, I remind you what we found - Francesco and me - about the replacement of aControls.
I believe that the structure of the classes should be like or about or very similar to this

class layout

ClassLayout.jpg (65.62 KiB) Viewed 2617 times

There are many similarities with the current, but be careful "BasicQt", the two groups "A" and "B", and groups of classes based on some similarities
I believe that, in the class "BasicQt" must be included (some and useful) methods and properties of QObject and QWidget.
see( http://doc.qt.nokia.com/latest/qobject.html e http://doc.qt.nokia.com/latest/qwidget.html )
for example: the data nCol, but its method is simply "RETURN:: oQtObject: x ()". The data lEnabled, in this case QT considers this property fundamental and then the method will be

second element: maintain a consistent programming style. Or use OOP or XBase classic style.
Examples currently included with HMG4 are a mixture of these styles and I believe no one thinks to write their own programs as well.
This topic is complex and takes time to be described, I believe that the examples will clarify my thoughts: they are all real.

I repeat.
My words must be considered as constructive criticism for the good of the project HMG4, to which many of us have contributed and spent their free time.
please, think about what I have given you before you shoot me

OOP style is WITH OBJECT xx := window():New()
xBase style is DEFINE WINDOW xx
variant of xBase style is the one with ; at the end of the line and one without... so we need to have multiple definition... and keep them in sync !!!!

This can lead to problems. For example look at DEFINE WINDOW in hmg.ch... it is translate to (partial)

What happens if the window is defined with OOP style and statusbar using xBase style ????

Luigi is not 100% correct on the need of variables to keep intermediate value. I don't remember why they started to appear. There were probably problems in the past, or it was just a shortcut to be able to reference them just with variable/object name...
With recent changes done (and for the reason that started this exact thread), New() automatically adds the object name as a data member of the parent and stores a reference to self there, and also adds itself to parent aControls.
So we don't need to have a local variable to keep the object "live" since there are at least 2 references to it stored in the parent... long life to the parent... !

Do windows need to have a variable ? short answer: no. Their New() adds them to hmgapp() object... so we may retrieve them starting from hmgapp().

hmgapp() iwanted to be a singleton but it was a not-really-a-singleton. I just committed a patch to make it a real singleton. Until now every time hmgapp() was called a new instance was created and this was ok was shared data members inherited from GLOBSHARED but was a pity for the standard data members from hmgapp itself... they reset at each call !
There were a couple of ways to solve the problem but I think that a singleton is the best way, it can help in the future.

I want to thank Luigi that shared his time with me in this week trying to understand how to improve hmg4., doing some tests, experimenting solutions, writing code, providing ideas and sharing his fork with me.

WITH OBJECT Button():New("button1")
or
WITH OBJECT Button():New()
or
WITH OBJECT Button1 := Button():New() this need a local declaration var
or
WITH OBJECT Button1 := Button():New("button1") this need a local declaration var
and
:row := 10
.....
END WITH

So what I mean is: we can't mix OOP and XBase because they need a different approach. IMHO, OOP it's very powerfull, but for a long time I write with XBase style: I like it.

Everyone can see the difference between a real OOP program (very brief explanation) and demos and differences with XBase style.

So if we want preserve the ability to write programs (end program) with XBase style using HMG4, we can't introduce any var with LOCAL or within hmg.ch and we must change the class/core code approach. If we want loose the ability to write programs with XBase style using HMG4, I think the real example is the last one not the first.

About class layout it's only a suggestion, because I found it very useful to create this forest even if it is complex to administer and can create misunderstandings or problems.