[a134] Extending Built-In classes basics... Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

[a134] Extending Built-In classes basics...

Post by TheArkive » 08 May 2021, 05:38

Sorry to say, I think I might still be struggling with understanding .Prototype and .Base.

It seems I can attach single methods just fine, and entire groups of methods in a For loop, but actually extending / assigning a like base to another object is still eluding me.

Code: Select all

class ListView_Ex extends Gui.ListView {
    Static __New() {
        ; Gui.ListView.Prototype.NewMethod := this.Prototype.NewMethod ; <-- this works, or ... super.Prototype.NewMethod := this.Prototype.NewMethod
        Gui.ListView.Prototype := this.Prototype ; <-- should this work? --> error: No method named 'NewMethod'
    }
    NewMethod() {
        msgbox "I'm new here."
    }
}
g := Gui(), LV := g.Add("ListView")
LV.NewMethod() ; <-- method not found error when using 2nd statement in [ Static __New() ]

EDIT: The above actually doesn't throw an error on creation. So the assigning of the prototype seems to succeed, but NewMethod is not actually attached. Am i doing something wrong here?


User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: [a134] Extending Built-In classes basics...

Post by TheArkive » 08 May 2021, 09:18

Ok I read through that post. So, I guess now we'll see if I got the intended meaning out of it.

For an example, to extend the ListView control to have a few extra methods, is this the suggested / preferred way, or at least one of the paths of least resistance:

Code: Select all

class ListView_Ext extends Gui.ListView { ; Technically no need to extend classes unless
    Static __New() { ; you are attaching new base on control creation.
        For prop in this.Prototype.OwnProps()
            super.Prototype.%prop% := this.Prototype.%prop%
    }
    IsChecked(row) { ; This was taken directly from the AutoHotkey help files.
        return (SendMessage(4140,row-1,0xF000,, "ahk_id " this.hwnd) >> 12) - 1 ; VM_GETITEMSTATE = 4140 / LVIS_STATEIMAGEMASK = 0xF000
    }
    IconIndex(row,col:=1) { ; from "just me" LV_EX ; Link: https://www.autohotkey.com/boards/viewtopic.php?f=76&t=69262&p=298308#p299057
        LVITEM := Buffer((A_PtrSize=8)?56:40, 0)                   ; create variable/structure
        NumPut("UInt", 0x2, "Int", row-1, "Int", col-1, LVITEM.ptr, 0)  ; LVIF_IMAGE := 0x2 / iItem (row) / column num
        NumPut("Int", 0, LVITEM.ptr, (A_PtrSize=8)?36:28)               ; iImage
        SendMessage(StrLen(Chr(0xFFFF))?0x104B:0x1005, 0, LVITEM.ptr,, "ahk_id " this.hwnd) ; LVM_GETITEMA/W := 0x1005 / 0x104B
        return NumGet(LVITEM.ptr, (A_PtrSize=8)?36:28, "Int")+1 ;iImage
    }
    GetColWidth(n) {
        return SendMessage(0x101D, n-1, 0, this.hwnd)
    }
}

Apart from the above code, I know that it is also possible to omit Static __New() and either:
  • extend the Gui class to override .Add() when creating a ListView
    or
  • to simply assign the prototype of the class to the base of an instantiated control (this, I believe, is my main method lately, embedded in the extending class)
The intent/criteria I'm looking to accomplish is very similar to swagfag's, namely:
  • not require anything from the client code other than #Include
  • only exception to the above maybe would be to require that #Include be near the top to ensure the class __New() method is run on script init before control creation.
  • and also the rest of swagfag's criteria is what I'm also going for
Is that about right?

Post Reply

Return to “Ask for Help (v2)”