GuiControl_Ex - Extending GuiControls - 2023/04/03 - v2.0.2

Post your working scripts, libraries and tools.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

GuiControl_Ex - Extending GuiControls - 2023/04/03 - v2.0.2

26 Jan 2021, 15:11


**** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ****


This script adds modifications to original built-in GUI and GuiControl-related objects. If you combine this script with another script that does the same thing, you will likely get unpredictable results. Especially in the case of methods/properties being mistakenly overwritten, no error messages will be generated.

It is not recommended to use this script in combination with other scripts that also modify the Gui and GuiControl objects.

The main focus for this is to add some handy additional methods for some GuiControls, and to post a template of how it works so others can learn from it and use it.

This is meant to be more of a code template / tutorial for accomplishing this goal, than an actual library.

Thanks to @lexikos for his multiple posts and insight into doing this properly. This method extends + preserves the AHK v2 native style.

I plan to add more methods / properties over time, or make any other modifications to extend this functionality while maintaining the AHK v2 Gui native style.

Check the GitHub repo for detailed docs.

Contributors:
  • AHK_User
  • just me
  • iPhilip
  • teadrinker
==================================================================
Updates
==================================================================

:arrow: Download on GitHub
Last edited by TheArkive on 03 Apr 2023, 08:09, edited 49 times in total.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Extending Gui and GuiControls - add Methods / Properties

27 Jan 2021, 14:16

Update 2021/01/27
  • This code is now 99% transparent and maintains the native AHK v2 object-oriented feel.
  • Only one concession needs to be made. When a GuiControl is passed as a parameter from a built-in callback function it needs to be re-wrapped via: ctl := gCtl.New(orig_ctl)
  • Of course if you bind a gCtl object as a param to a function, then no such re-wrapping is needed.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Extending GuiControls (and Gui) - add Methods / Properties

31 Jan 2021, 05:07

Update 2021/01/31
  • Full rewrite, thanks to lexikos showing me how to do this properly.
  • Added some more useful methods for better examples: for ListBox and ComboBox: .GetCount(), .GetItems(), .GetText(row)
  • Added methods for ListView: .Checked(row), .IconIndex(row)
  • Improved the example with more useful methods.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: GuiControl_Ex - Extending GuiControls - 2021/05/30 - a136

30 May 2021, 12:54

Update 2021/05/30
  • added btn.SetImg() for easy image buttons
  • added btn.SetSplit() for an easy split button
  • moved to GitHub
  • cleaned up example file
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: GuiControl_Ex - Extending GuiControls - 2021/05/31 - a136

31 May 2021, 08:47

Update 2021/05/31
  • Now PicButton, SplitButton, and ToggleButton are separate classes. They can be created with Gui.AddPicButton(), Gui.AddToggleButton(), Gui.AddSplitButton().
  • All 3 new classes have .SetImg() method, but for PicButton, you can set the image on creation.
  • Updated docs.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - a137

21 Jun 2021, 07:16

Update 2021/06/21
  • added StatusBar.RemoveIcon(part:=1)
  • added Edit.Append(text,top:=false)
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

16 Sep 2021, 09:57

:bravo: :superhappy: :dance:
Amazing code, very well made. this is a must have library.

I am suprized that nobody responded to this post.

I wonder one thing, can we change the color of the titlebar of the gui in V2, or do we need to make a fake one?
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

16 Sep 2021, 10:00

Thanks for the cudos :P

I don't know of any "native" ahk v2 method for changing the titlebar color. But it is certainly possible with the win32 API.

If by "make a fake one" you mean using GDI/GDI+ and layered windows, then of course you can do that as well.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

17 Sep 2021, 15:31

Can we use this to make a special method that creates a colored button that changes from color when hovering over it?
That is also a high in demand control to get a different style of buttons. I tried to add text to the AddPicButton method, but it is not visible because of the picture inside it.

With the AddPicButton, you can simulate it by creating simple color images, create an PicButton, add text on top of it and add an onmessage function to SetImg to a different color. Is it necessary to create a simple color image or can we include this inside the method?

I did some tests, the standard gui methods of v2 allow to change the color of some controls, It works a little (you still get some of the white background color, but for buttons it still does not work at al...
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

17 Sep 2021, 16:09

AHK_user wrote: Can we use this to make a special method that creates a colored button that changes from color when hovering over it?
Technically yes, but the best way to do that depends on how you would use it (I would say).
AHK_user wrote: I tried to add text to the AddPicButton method, but it is not visible because of the picture inside it.
Yah I didn't design that button type to have text. I didn't need the text for my uses at the time. It is of course it is still possible, however you must also specify several settings in the API that determine where the text goes. To my knowledge, you need to use the NM_CUSTOMDRAW event to best apply your chosen custom buttons (and this should work regardless of system theme).
AHK_user wrote: With the AddPicButton, you can simulate it by creating simple color images, create an PicButton, add text on top of it and add an onmessage function to SetImg to a different color.
I know I've seen one script, CreateImageButton by "just me", that uses GDI/GDI+ as one of the methods to create a "pic button", with or without text. It's a pretty darn good lib.
AHK_user wrote: That is also a high in demand control to get a different style of buttons.
I'll add this to my To-Do list and see what I come up with. I know, most likely, the "shortest" solution will be NM_CUSTOMDRAW with GDI.

EDIT: The easiest approach is to have button images, then draw them into an HDC on script load. Then use NM_CUSTOMDRAW to draw the proper btn state. This can be done dynamically with a few options too, but that will be trickier.
just me
Posts: 9407
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

18 Sep 2021, 06:00

Thanks for sharing this lib.

:arrow: BM_SETIMAGE
You must not set the BS_BITMAP/BS_ICON style if you want to display text with the bitmap/icon.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

18 Sep 2021, 11:15

Thanks @just me :)

Would that work to change the color of a button of any size? I thought the img shown on a button would be limited to square shaped images/icons?
just me
Posts: 9407
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

19 Sep 2021, 03:48

If I understand your question right: It can be any rectangular shape.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

19 Sep 2021, 03:49

Yah that was basically my question. Thanks for the info. I'll give that a try in more testing.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

16 Oct 2021, 13:26

I have a proposal to add a "Rectangle" class that adds a picture with a specified color with the c option.
It has the method "SetColor(color)" to change the color.

This can also be used to add some lines to your gui.

I was thinking of changing the native picture class to accept an included c option, but I do not know how we can change the method Opt().
I would prefer to do it this way.

[Codebox=autohotkey]; Creating rectangles filled with a color
g.AddRectangle("x" 230 " y" 00 " w" 32 " h" 32 " cRed")
g.AddRectangle("x" 262 " y" 0 " w" 32 " h" 32 " cGreen")
g.AddRectangle("x" 230 " y" 32 " w" 32 " h" 32 " cBlue")
g.AddRectangle("x" 262 " y" 32 " w" 32 " h" 32 " cYellow")[/Codebox]
2021-10-16 20_03_12-Test.png
2021-10-16 20_03_12-Test.png (10.28 KiB) Viewed 6142 times

Code: Select all

; ==================================================================
; GuiControl_Ex
; ==================================================================

class ListComboBox_Ext {
    Static __New() {
        For prop in this.Prototype.OwnProps() {
            Gui.ListBox.Prototype.%prop% := this.prototype.%prop%
            Gui.ComboBox.Prototype.%prop% := this.prototype.%prop%
        }
    }
    
    GetCount() {
        If (this.Type = "ListBox")
            return SendMessage(0x018B, 0, 0, this.hwnd) ; LB_GETCOUNT
        Else If (this.Type = "ComboBox")
            return SendMessage(0x146, 0, 0, this.hwnd)  ; CB_GETCOUNT
    }
    
    GetText(row) {
        If (this.Type = "ListBox")
            return this._GetString(0x18A,0x189,row) ; 0x18A > LB_GETTEXTLEN // 0x189 > LB_GETTEXT
        Else if (this.Type = "ComboBox")
            return this._GetString(0x149,0x148,row) ; 0x149 > CB_GETLBTEXTLEN // 0x148 > CB_GETLBTEXT
    }
    
    GetItems() {
        result := []
        Loop this.GetCount()
            result.Push(this.GetText(A_Index))
        return result
    }
    
    _GetString(getLen_msg,get_msg,row) {
        size := SendMessage(getLen_msg, row-1, 0, this.hwnd) ; GETTEXTLEN
        buf := Buffer( (size+1) * (StrLen(Chr(0xFFFF))?2:1), 0 )
        SendMessage(get_msg, row-1, buf.ptr, this.hwnd) ; GETTEXT
        return StrGet(buf)
    }
}

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%
    }
    Checked(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)
    }
}

class StatusBar_Ext extends Gui.StatusBar {
    Static __New() {
        For prop in this.Prototype.OwnProps()
            super.Prototype.%prop% := this.Prototype.%prop%
    }
    RemoveIcon(part:=1) {
        hIcon := SendMessage(0x414, part-1, 0, this.hwnd)
        If hIcon
            SendMessage(0x40F, part-1, 0, this.hwnd)
        return DllCall("DestroyIcon","UPtr",hIcon)
    }
}

class PicButton extends Gui.Button {
    Static __New() {
        Gui.Prototype.AddPicButton := this.AddPicButton
    }
    Static AddPicButton(sOptions:="",sPicFile:="",sPicFileOpt:="") {
        ctl := this.Add("Button",sOptions)
        ctl.base := PicButton.Prototype
        ctl.SetImg(sPicFile, sPicFileOpt)
        return ctl
    }
    SetImg(sFile, sOptions:="") { ; input params exact same as first 2 params of LoadPicture()
        Static ImgType := 0       ; thanks to teadrinker: https://www.autohotkey.com/boards/viewtopic.php?p=299834#p299834
        Static BS_ICON := 0x40, BS_BITMAP := 0x80, BM_SETIMAGE := 0xF7
        
        hImg := LoadPicture(sFile, sOptions, &_type)
        curStyle := ControlGetStyle(this.hwnd)
        ControlSetStyle (curStyle | (!_type?BS_BITMAP:BS_ICON)), this.hwnd
        hOldImg := SendMessage(BM_SETIMAGE, _type, hImg, this.hwnd)
        
        If (hOldImg)
            (ImgType) ? DllCall("DestroyIcon","UPtr",hOldImg) : DllCall("DeleteObject","UPtr",hOldImg)
        
        ImgType := _type ; store current img type for next call/release
    }
    Type {
        get => "PicButton"
    }
}

class Rectangle extends Gui.Pic {
    ; Creates a Picture with one color, the color defined by an option starting with a c in the options.
    Static __New() {
        Gui.Prototype.AddRectangle := this.AddRectangle
    }
    Static AddRectangle(sOptions := "", sPicFile := "") {
        Color := RegExReplace(sOptions, ".*\bc([^\s]*)\b.*", "$1", &ColorCount)
        if (ColorCount and Color != ""){
            sOptions := RegExReplace(sOptions, "(.*)\bc([^\s]*)\b\s?(.*)", "$1$3") " +0x4E"
        }
        
        ctl := this.Add("Picture", sOptions, sPicFile)
        ctl.base := Rectangle.Prototype
        ctl.SetColor(Color)
        return ctl
    }
    SetColor(sColor) {	; input params exact same as first 2 params of LoadPicture()
        This.Color := sColor
        switch sColor{
            case "Black":
                sColor := "000000"
            case "Silver":
                sColor := "C0C0C0"
            case "Gray":
                sColor := "808080"
            case "White":
                sColor := "FFFFFF"
            case "Maroon":
                sColor := "800000"
            case "Red":
                sColor := "FF0000"
            case "Purple":
                sColor := "800080"
            case "Fuchsia":
                sColor := "FF00FF"
            case "Green":
                sColor := "008000"
            case "Lime":
                sColor := "00FF00"
            case "Olive":
                sColor := "808000"
            case "Yellow":
                sColor := "FFFF00"
            case "Navy":
                sColor := "000080"
            case "Blue":
                sColor := "0000FF"
            case "Teal":
                sColor := "008080"
            case "Aqua":
                sColor := "00FFFF"
        }
        
        BMBITS := Buffer(4, 0), NumPut("UInt", "0x" . sColor, BMBITS, 0)
        hBM := DllCall("Gdi32.dll\CreateBitmap", "Int", 1, "Int", 1, "UInt", 1, "UInt", 24, "Ptr", 0)
        hBM := DllCall("User32.dll\CopyImage", "Ptr", hBM, "UInt", 0, "Int", 0, "Int", 0, "UInt", 0x2008)
        DllCall("Gdi32.dll\SetBitmapBits", "Ptr", hBM, "UInt", 3, "Ptr", BMBITS)
        return DllCall("User32.dll\SendMessage", "Ptr", this.hwnd, "UInt", 0x172, "Ptr", 0, "Ptr", hBM)
    }

    Type {
        get => "Picture"
    }
}

class SplitButton extends Gui.Button {
    Static __New() {
        super.Prototype.SetImg := PicButton.Prototype.SetImg
        Gui.Prototype.AddSplitButton := this.AddSplitButton
    }
    Static AddSplitButton(sOptions:="",sText:="",callback:="") {
        Static BS_SPLITBUTTON := 0xC
        
        ctl := this.Add("Button",sOptions,sText)
        ctl.base := SplitButton.Prototype
        
        ControlSetStyle (ControlGetStyle(ctl.hwnd) | BS_SPLITBUTTON), ctl.hwnd
        If callback
            ctl.callback := callback
          , ctl.OnNotify(-1248, ObjBindMethod(ctl,"DropCallback"))
            
        return ctl
    }
    Drop() {
        this.DropCallback(this,0)
    }
    DropCallback(ctl, lParam) {
        ctl.GetPos(&x,&y,,&h)
        f := this.callback, f(ctl,{x:x, y:y+h})
    }
    Type {
        get => "SplitButton"
    }
}

class ToggleButton extends Gui.Checkbox {
    Static __New() {
        super.Prototype.SetImg := PicButton.Prototype.SetImg
        Gui.Prototype.AddToggleButton := this.AddToggleButton
    }
    Static AddToggleButton(sOptions:="",sText:="") {
        ctl := this.Add("Checkbox",sOptions " +0x1000",sText)
        ctl.base := ToggleButton.Prototype
        return ctl
    }
    Type {
        get => "ToggleButton"
    }
}

class Edit_Ext extends Gui.Edit {
    Static __New() {
        For prop in this.Prototype.OwnProps()
            super.Prototype.%prop% := this.prototype.%prop%
    }
    Append(txt, top := false) {
        txtLen := SendMessage(0x000E, 0, 0,,this.hwnd)           ;WM_GETTEXTLENGTH
        pos := (!top) ? txtLen : 0
        SendMessage(0x00B1, pos, pos,,this.hwnd)           ;EM_SETSEL
        SendMessage(0x00C2, False, StrPtr(txt),,this.hwnd)    ;EM_REPLACESEL
    }
}
Here is the example:

Code: Select all

; AHK v2
#INCLUDE _GuiCtlExt.ahk

Global g

IL := IL_Create(2)
IL_Add(IL, "shell32.dll", 128)
IL_Add(IL, "shell32.dll", 129)
IL_Add(IL, "shell32.dll", 256)

g := Gui("-MinimizeBox -MaximizeBox","Test")
g.OnEvent("close",gui_close)
g.OnEvent("escape",gui_close)
ctl := g.Add("ListView","+Report w210 h100 vLV Checked Icon2",["test"])
ctl.SetImageList(IL,1)
ctl.Add("check Icon3","Row1"), hwnd := ctl.hwnd
ctl.Add("icon1","Row2")
ctl.Opt("+Report")
ctl.ModifyCol()

g.Add("ListBox","w100 h100 vLB",["ListBox Item 1","ListBox Item 2","ListBox Item 3"])
g.Add("ComboBox","x+10 yp w100 h100 vCB Section",["ComboBox Item 1","ComboBox Item 2","ComboBox Item 3","ComboBox Item 4"])

btn := g.AddPicButton("vPicBtn w24 h24","netshell.dll","Icon151 w20 h20")
btn.OnEvent("click",gui_events)

btn := g.Add("Button","vData x+0","Show Data")
btn.OnEvent("Click",gui_events)

btn := g.AddSplitButton("vDropBtn1 xs h32 w48","",gui_events) ; here the callback is only for clicking the split down arrow
btn.OnEvent("click",gui_events) ; this is for when you click the "normal" part of the button
btn.SetImg("netshell.dll","Icon151 w20 h20")

btn := g.AddToggleButton("vToggleBtn w48 h32","")
btn.OnEvent("click",gui_events)
btn.SetImg("netshell.dll","Icon151 w20 h20")

; Creating rectangles filled with a color
g.AddRectangle("x" 230 " y" 00 " w" 32 " h" 32 " cRed") 
g.AddRectangle("x" 262 " y" 0 " w" 32 " h" 32 " cGreen")
g.AddRectangle("x" 230 " y" 32 " w" 32 " h" 32 " cBlue")
g.AddRectangle("x" 262 " y" 32 " w" 32 " h" 32 " cYellow")

g.show()

gui_close(*) {
    ExitApp
}

gui_events(ctl, info) {
    Global g
    
    If (ctl.name = "DropBtn1") && IsObject(info) {
        m(info)
    } Else If (ctl.name = "DropBtn1") {
        msgbox "You clicked the button portion of the drop button.`r`n`r`nTry clicking the arrow."
    } Else If (ctl.Name = "PicBtn")
        msgbox "You clicked the pic btn."
    Else If (ctl.name = "Data") {
        LVr := 1, LBr := 2, CBr := 3, LBi := "", CBi := ""
        
        For item in g["LB"].GetItems()
            LBi .= (LBi?"`r`n`t":"`t") item 
        
        For item in g["CB"].GetItems()
            CBi .= (CBi?"`r`n`t":"`t") item 
        
        MsgBox "ListView`r`n`r`n"
             . "`tIconIndex Row " LVr ": " g["LV"].IconIndex(LVr) "`r`n"
             . "`tChecked Row " LVr ": " (g["LV"].Checked(LVr)?"true":"false") "`r`n"
             . "`trow count: " g["LV"].GetCount() "`r`n"
             . "`tsecond row text:  " g["LV"].GetText(2) "`r`n`r`n" ; original LV.GetText() still works as expected
             
             . "ListBox`r`n`r`n"
             . "`tItemText Row " LBr ": " g["LB"].GetText(LBr) "`r`n" ; .GetText() method added to ListBox
             . "`tRow Count: " g["LB"].GetCount() "`r`n`r`n"
             . "`tItems:`r`n" LBI "`r`n`r`n"
             
             . "ComboBox`r`n`r`n"
             . "`tItemText Row " CBr ": " g["CB"].GetText(CBr) "`r`n"
             . "`tRow Count: " g["CB"].GetCount() "`r`n`r`n"
             . "`tItems:`r`n" CBi
    } Else If (ctl.name = "ToggleBtn")
        Msgbox "Value: " ctl.Value
}

m(coords) {
    me := Menu()
    me.Add("Item 1",m_event)
    me.Add("Item 2",m_event)
    me.Show(coords.x, coords.y)
}

m_event(item, pos, m) {
    msgbox "You clicked: " item
}
Here is my try to add a method so the Opt method will also accept the c parameter, but this failed...

Code: Select all

    Opt(sOptions){
        Color := RegExReplace(sOptions, ".*\bc([^\s]*)\b.*", "$1", &ColorCount)
        if (ColorCount and Color != "") {
            sOptions := RegExReplace(sOptions, "(.*)\bc([^\s]*)\b\s?(.*)", "$1$3") " +0x4E"
            this.SetColor(Color)
        }
        this.Opt(sOptions)
    }
just me
Posts: 9407
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

18 Oct 2021, 05:19

@AHK_user:

Code: Select all

MainGui := Gui(, "Background Test")
MainGui.MarginX := 0
MainGui.MarginY := 0
MainGui.AddText("w200 h200 BackgroundRed")
MainGui.AddText("x+0 yp wp hp BackgroundGreen")
MainGui.AddText("xm wp hp BackgroundBlue")
MainGui.AddText("x+0 yp wp hp BackgroundYellow")
MainGui.Show()
MainGui.OnEvent("Close", (*) => ExitApp)
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

18 Oct 2021, 05:28

thanks @just me ... I was looking into WM_CTLCOLORSTATIC and other unnecessary stuff.

Didn't think of a text control.

Edit: fixed wm_ msg name.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

18 Oct 2021, 13:12

just me wrote:
18 Oct 2021, 05:19
@AHK_user:

Code: Select all

MainGui := Gui(, "Background Test")
MainGui.MarginX := 0
MainGui.MarginY := 0
MainGui.AddText("w200 h200 BackgroundRed")
MainGui.AddText("x+0 yp wp hp BackgroundGreen")
MainGui.AddText("xm wp hp BackgroundBlue")
MainGui.AddText("x+0 yp wp hp BackgroundYellow")
MainGui.Show()
MainGui.OnEvent("Close", (*) => ExitApp)
Genius in his simplicity! :shock: :shock: :shock:
Thanks for the tip, I will use it a lot improve my guis!!! :bravo:

:think: Maybe this is a nice trick to include in one of the gui examples in the documentation.
AHK_user
Posts: 515
Joined: 04 Dec 2015, 14:52
Location: Belgium

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

26 Oct 2021, 12:22

I have another proposal to add, adding cues to the Edit and combobox by adding the method SetCue() to the controls.

I added the setCue function to the edit and combobox to provide gray text when the control is empty.
I learned It from a post of @jNizM and advice from @Lexikos

One question, does somebody knows hot to change this so it is set by the property "CueText" and not by a method?
Like:
Edt01.CueText:= "Edit Control Cue Text"

This way you can only add one parameter, but It would be cool to know If this is possible.

Here is my proof of concept:

Code: Select all

; Thanks to jNizM for the interesting DllCalls
; https://www.autohotkey.com/boards/viewtopic.php?t=70852
class Edit_ext {
    Static __New() {
        Gui.Edit.Prototype.SetCue:= ObjBindMethod(this, "SetCue")
    }

    Static SetCue(_obj, string, option := true) {
        ; Links ....................:  https://docs.microsoft.com/en-us/windows/win32/controls/em-setcuebanner
        ; Description ..............:  Sets the textual cue, or tip, that is displayed by the edit control to prompt the user for information.
        ; Option ...................:  True  -> if the cue banner should show even when the edit control has focus
        ;                              False -> if the cue banner disappears when the user clicks in the control
        static ECM_FIRST := 0x1500
        static EM_SETCUEBANNER := ECM_FIRST + 1
        if (DllCall("user32\SendMessage", "ptr", _obj.hwnd, "uint", EM_SETCUEBANNER, "int", option, "str", string, "int"))
            return true
        return false
    }
}

class ComboBox_ext {
    Static __New() {
        Gui.ComboBox.Prototype.SetCue := ObjBindMethod(this, "SetCue")
    }

    Static SetCue(_obj, string, option := true) {
        ; Links ....................:  https://docs.microsoft.com/en-us/windows/win32/controls/cb-setcuebanner
        ; Description ..............:  Sets the cue banner text that is displayed for the edit control of a combo box.
        static CBM_FIRST := 0x1700
        static CB_SETCUEBANNER := CBM_FIRST + 3
        if (DllCall("user32\SendMessage", "ptr", _obj.hwnd, "uint", CB_SETCUEBANNER, "int", option, "str", string, "int"))
            return true
        return false
    }
}


MyGui := Gui()

Edt01 := MyGui.AddEdit("w300")
Edt01.NewMethod("Edit Control Cue Text")

Edt02 := MyGui.AddComboBox("w300", ["test 1", "test 2"])
Edt02.SetCue("Enter text here") 

MyGui.Show()
2021-10-26 19_15_06-tempCodeRunnerFile.ahk.png
2021-10-26 19_15_06-tempCodeRunnerFile.ahk.png (4.12 KiB) Viewed 5839 times
Last edited by AHK_user on 26 Oct 2021, 14:53, edited 1 time in total.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: GuiControl_Ex - Extending GuiControls - 2021/06/21 - beta.1

26 Oct 2021, 12:43

@AHK_user
I like this one! Thanks for the input :D ... I'll add that to my To-Do list.

I appreciate how short it is.

Return to “Scripts and Functions (v2)”

Who is online

Users browsing this forum: Skyeee and 30 guests