Class Inheritance

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
Xeilous
Posts: 23
Joined: 04 Feb 2018, 04:06

Class Inheritance

26 May 2024, 14:52

I'm currently converting a class from v1 to v2:
LV_Rows(https://github.com/Pulover/Class_LV_Rows) which extends LV_EX(https://github.com/AHK-just-me/LV_EX).

I have managed to get the Copy, Cut, Paste, and Delete methods working within a singular ListView. What I am trying to figure out now is how to make CopyData shared between instances of the class without making it a global variable (or a better way to make it work). I need help understanding the concept used in the LV_Rows class and how one would convert that to v2.

My plan is to create a single instance of "MyClass" and pass multiple ListView HWNDs to it. The methods within this class would handle the copying and pasting between each ListView (using those HWND's). I figure this approach should work because the class can reference CopyData, and use it to manage the data between the ListView HWNDs. The class will include methods to copy, cut, and paste, etc.

I can't figure out how to make this happen. As you can see, the moment I add "extends Gui.ListView", what I have come up with, stops working.

Maybe I am going about this the wrong way. I could use some advice, and any help would be appreciated.


This works:

Code: Select all

myObj := MyClass("LV1Hwnd", "LV2Hwnd")
Loop myObj.handle.Length
    MsgBox(myObj.handle[A_Index])

Class ListViewExtensions {
    ; whatever
}

Class MyClass extends ListViewExtensions {
    __New(hwnd*) {
        this.handle := hwnd
    }
}

This doesn't work:

Code: Select all

myObj := MyClass("LV1Hwnd", "LV2Hwnd")
Loop myObj.handle.Length
    MsgBox(myObj.handle[A_Index])

Class ListViewExtensions extends Gui.ListView { ; 'extends Gui.ListView' causes it to stop working.
    ; whatever
}

Class MyClass extends ListViewExtensions {
    __New(hwnd*) {
        this.handle := hwnd
    }
}
vmech
Posts: 376
Joined: 25 Aug 2019, 13:03

Re: Class Inheritance

03 Jun 2024, 13:22

@Xeilous
I think error is happening because Gui.ListView itself is not a user-defined class, but a built-in object. For some reason, its Gui.ListView.Base property is not inherited by the user-defined class.
Manually assigning a base to the ListViewExtensions class using the static __New method avoids a runtime error in this particular code.

Code: Select all

myObj := MyClass("LV1Hwnd", "LV2Hwnd")
Loop myObj.handle.Length
    MsgBox(myObj.handle[A_Index])

Class ListViewExtensions {
    static __New() {
        this.Base := Gui.ListView
    }
}

Class MyClass extends ListViewExtensions {
    __New(hwnd*) {
        this.handle := hwnd
    }
}
Please post your script code inside [code] ... [/code] block. Thank you.
lexikos
Posts: 9690
Joined: 30 Sep 2013, 04:07
Contact:

Re: Class Inheritance

07 Jun 2024, 21:02

You can't instantiate a Gui.ListView directly, so you can't instantiate a MyClass which extends ListViewExtensions which extends Gui.ListView.

There is no point in manually assigning ListViewExtensions.Base := Gui.ListView, as the latter does not have any useful static members to inherit. Instances of ListViewExtensions will still not be instances of Gui.ListView, because ListViewExtensions.Prototype is not based on Gui.ListView.Prototype.

I don't understand why you are trying to do that. If MyClass is an object which manages multiple ListViews, it is not expected to behave or identify as a ListView, and inheriting the methods of a ListView would make no sense. So just don't use extends Gui.ListView.

In the LV_Rows class, CopyData is assigned to this.CopyData and this is an instance, so each instance has its own CopyData. What you want is for CopyData to be shared by all of the managed ListViews, right? If you are changing the model so that each instance manages multiple ListViews, isn't this.CopyData already shared by multiple ListViews?

Suppose that you want it to be shared by all ListViews and all instances of MyClass. I think you already know that a global variable would do what you want - there would be a single global variable for all instances, let's say GlobalCopyData. But you don't want it to be global. I presume the only reason for this is to avoid adding a name to the global namespace (or ListVars).

Essentially what you want is just a single variable which is not in the global scope but otherwise is no different to a global variable. If you assign to MyClass.CopyData, this will be a single "variable" (propertly actually) and not in the global scope. It doesn't matter what MyClass is, as long as it is always the same object and can be assigned a property. It doesn't even have to be a class, let alone extend Gui.ListView.

vmech wrote:For some reason, its Gui.ListView.Base property is not inherited by the user-defined class.
I do not know how you came to that conclusion, or why you think it would cause this effect. class ListViewExtensions extends Gui.ListView creates a class object where ListViewExtensions.base = Gui.ListView and ListViewExtensions.Prototype.base = Gui.ListView.Prototype. Extends just sets the base of these two objects; that is all it does. If ListViewExtensions did not have the base set like so, you would be able to instantiate it by calling ListViewExtensions() (or MyClass by calling MyClass()).

A Gui.Control must be created as part of adding a control to a Gui. In this case, we don't even want to create a control, so it doesn't make sense to instantiate a class which derives from Gui.Control.
vmech
Posts: 376
Joined: 25 Aug 2019, 13:03

Re: Class Inheritance

08 Jun 2024, 02:21

lexikos wrote:
07 Jun 2024, 21:02
vmech wrote:For some reason, its Gui.ListView.Base property is not inherited by the user-defined class.
I do not know how you came to that conclusion, or why you think it would cause this effect.
I just looked at the contents of the objects generated in the TC sample code in the debugger. And applied the first thing that came to mind.
I was too lazy to think further. Besides, it probably wasn't necessary.
Because:
lexikos wrote:
07 Jun 2024, 21:02
I don't understand why you are trying to do that.
I also don't understand what he wanted to achieve with his code.
lexikos wrote:
07 Jun 2024, 21:02
A Gui.Control must be created as part of adding a control to a Gui. In this case, we don't even want to create a control, so it doesn't make sense to instantiate a class which derives from Gui.Control.
I know it. TY.

Cheers.
Please post your script code inside [code] ... [/code] block. Thank you.

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: No registered users and 37 guests