[Class] Toolbar - Create and modify (Updated Aug, 9, 2020)

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
Pulover
Posts: 612
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: [Class] Toolbar - Create and modify

27 Nov 2013, 11:34

Nice to hear that you found a way! Good luck with the project. :D
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
Pulover
Posts: 612
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: [Class] Toolbar - Create and modify

16 Mar 2016, 19:54

Update:
  • If the button label is not a valid label, a function can be passed instead. Parameters can be passed to the OnMessage method.
  • Updated class for new AHK Object methods.
The main example has been updated to demonstrate how to call a function from a button and how to pass parameters to it.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

13 Nov 2017, 09:23

Sorry for the necro; tried posting this in Ask for Help and got no takers.

I'm getting starting teaching myself to make toolbars with this library, and have immediately run into the problem that I can't get the toolbar to appear anywhere except the upper-left corner of the GUI, which is messing with some other elements. I suspect it might have something to do with the way I am doing the GUI as a child window but I'm not sure. Here is my code:

Code: Select all

ILA := IL_Create(4, 2, False)
	IL_Add(ILA, "shell32.dll", 127)
	IL_Add(ILA, "shell32.dll", 128)
	IL_Add(ILA, "shell32.dll", 129)
	IL_Add(ILA, "shell32.dll", 130)

	WinActivate, ahk_exe Product.exe
	WinWaitActive, ahk_exe Product.exe
	hParent := WinExist()
	
	Gui, +HwndhChild1 -Caption
	; TBSTYLE_FLAT     := 0x0800 Required to show separators as bars.
	; TBSTYLE_TOOLTIPS := 0x0100 Required to show Tooltips.
	; CCS_NODIVIDER    := 0x0040 Removes the separator line above the toolbar.
	Gui, Add, Picture, w40 h20, % SharedDataDir . "title2.png"
	Gui, Add, Custom, ClassToolbarWindow32 hwndhToolbar 0x0800 0x0100 0x0040 h20 x100
	DllCall("SetParent", "ptr", hChild1, "ptr", hParent)
	Gui, Show, x0 y150 NA	; This uses CLIENT location
	
	WinSet, Style, -0x80000000, ahk_id %hChild1% ; Remove WS_POPUP style
	WinSet, Style, -0x40000000, ahk_id %hChild1% ; Remove WS_CHILD style
	
	; Initialize Toolbars.
	; The variable you choose will be your handle to access the class for your toolbar.
	MyToolbar := New Toolbar(hToolbar)

	; Set ImageList.
	MyToolbar.SetImageList(ILA)

	; Add buttons.
	MyToolbar.Add("", "Label1=Button 1:1", "Label2=Button 2:2", "Label3=Button 3:3", "MyFunction=Button 4:4")

	; Removes text labels and show them as tooltips.
	MyToolbar.SetMaxTextRows(0)
	return
The result of this is that the toolbar completely overlaps the image. Oddly, the toolbar also seems to ignore the "h20" bit and overlaps things below it as well. If I remove the picture from the GUI, the toolbar starts behaving at least as far as what height it is supposed to be. The "x100" command doesn't do anything no matter what. >.<
User avatar
Pulover
Posts: 612
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

13 Nov 2017, 10:34

; CCS_NOPARENTALIGN := 0x0008 - Allows positioning and moving toolbars.
; CCS_NORESIZE := 0x0004 - Allows resizing toolbars.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
MaxAstro
Posts: 557
Joined: 05 Oct 2016, 13:00

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

13 Nov 2017, 15:45

~facepalm~

Thank you. I thought I'd read the example more carefully then that...
think
Posts: 136
Joined: 09 Feb 2014, 05:20

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

04 Jan 2019, 13:18

Hi, is there a way to make the toolbar background transparent or change it's background color? Part of my window is colored with a another color and would like to show the toolbar over it.

Or is there a better alternative to create image buttons?
User avatar
joedf
Posts: 8940
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

04 Jan 2019, 18:48

this is pretty cool for styling btns in general
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

10 Jan 2019, 00:10

Ah, I removed this humongous post because I solved the problem.

I was loading an icon with an empty value, then when I went to delete the icons I didn't want in the toolbar, since it had a value of 0, the class_toolbar deleted them all. Finally found the culprit. Now I know to test for a value before I delete the buttons.
Last edited by BGM on 11 Jan 2019, 13:02, edited 1 time in total.
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

10 Jan 2019, 00:29

Also, you gave me this example earlier in the thread. I changed the labels to numbers, but every button provides a popup saying: "MsgBox, You selected 400" even if I click on the other buttons. Isn't that weird? Maybe I need to restart my computer (Windows 7).

Code: Select all

#NoEnv
#SingleInstance, Force
#Include <Class_Toolbar>

; Create an ImageList.
ILA := IL_Create(4, 2, True)
IL_Add(ILA, "shell32.dll", 171)
IL_Add(ILA, "shell32.dll", 212)
IL_Add(ILA, "shell32.dll", 288)
IL_Add(ILA, "shell32.dll", 131)

; TBSTYLE_FLAT     := 0x0800 Required to show separators as bars.
; TBSTYLE_TOOLTIPS := 0x0100 Required to show Tooltips.
Gui, Add, Custom, ClassToolbarWindow32 hwndhToolbar 0x0800 0x0100
Gui, Add, Text, xm, Press F1 to customize.
Gui, Show,, Test

; Initialize Toolbars.
; The variable you choose will be your handle to access the class for your toolbar.
MyToolbar := New Toolbar(hToolbar)
MyToolbar.SetImageList(ILA)

; Add buttons.
MyToolbar.Add("", "100=Button 1:1", "200=Button 2:2", "300=Button 3:3", "400=Button 4:4")
MyToolbar.SetMaxTextRows(0)

; Set a function to monitor the Toolbar's messages.
WM_COMMAND := 0x111
OnMessage(WM_COMMAND, "TB_Messages")
; Set a function to monitor notifications.
WM_NOTIFY := 0x4E
OnMessage(WM_NOTIFY, "TB_Notify")

return

; This function will receive the messages sent by both Toolbar's buttons.
TB_Messages(wParam, lParam){
    Global ; Function (or at least the Handles) must be global.
    MyToolbar.OnMessage(wParam) ; Handles toolbar's messages.
}

; This function will receive the notifications.
TB_Notify(wParam, lParam){
    Global ; Function (or at least the Handles) must be global.
    ReturnCode := MyToolbar.OnNotify(lParam) ; Handles notifications.
    return ReturnCode
}

; Your labels.
100:
200:
300:
400:
MsgBox, You selected label %a_thislabel%
return

; Customizie dialog.
F1::MyToolbar.Customize()

GuiClose:
ExitApp
return
I think there is a bug somewhere (I've simplified the example you posted earlier. See how my labels are all different, but they all call only the last function. There seems to be some problem in gathering the labels. If you enter the customization panel, you will see the buttons in this order: Button 4 (with icon1), Button 2, Button 3 and Button 4. But they all call the same label for some reason. If you change the label numbers, you get different results.

Try this and it works:

Code: Select all

MyToolbar.Add("", "101=Button 1:1", "202=Button 2:2", "303=Button 3:3", "404=Button 4:4")

101:
202:
303:
404:
MsgBox, You selected label %a_thislabel%
return
The problem lies in the labels. Presume in the following examples that the labels are named properly and match what is in MyToolbar.Add()


This doesn't work:
MyToolbar.Add("", "101=Button 1:1", "201=Button 2:2", "301=Button 3:3", "401=Button 4:4")

This DOES work:
MyToolbar.Add("", "101=Button 1:1", "102=Button 2:2", "103=Button 3:3", "104=Button 4:4")
This works:
MyToolbar.Add("", "100=Button 1:1", "101=Button 2:2", "102=Button 3:3", "103=Button 4:4")

This does not work: Button 1 and 2 get lost - their label and command replaced with buttons 3 and 4
MyToolbar.Add("", "100=Button 1:1", "101=Button 2:2", "200=Button 3:3", "201=Button 4:4")
MyToolbar.Add("", "1000=Button 1:1", "1001=Button 2:2", "2000=Button 3:3", "2001=Button 4:4")
MyToolbar.Add("", "1100=Button 1:1", "1101=Button 2:2", "2100=Button 3:3", "2101=Button 4:4")
This configuration loses 100 and 101. They get replaced by 200 and 201. Same if they are 4-digits.
Here you see 100 gets replaced with 900
MyToolbar.Add("", "100=Button 1:1", "101=Button 2:2", "102=Button 3:3", "900=Button 4:4")
but not this way. This way works.
MyToolbar.Add("", "100=Button 1:1", "101=Button 2:2", "102=Button 3:3", "009=Button 4:4")
It's not only a problem with 0's - it's a problem with the pattern. This also only creates button 4.
MyToolbar.Add("", "101=Button 1:1", "201=Button 2:2", "301=Button 3:3", "401=Button 4:4")

This one is even worse to understand:
MyToolbar.Add("", "100=Button 1:1", "103=Button 2:2", "110=Button 3:3", "113=Button 4:4")
100 and 113 works; but 103 reports as 110 and so does 110.

What is the pattern here? There is a bug somewhere in the class_toolbar's label detector.
It's not a problem with ahk because if you call the labels with a gosub without using the toolbar, they work correctly.
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

10 Jan 2019, 17:11

Here's the fix for the code in class_toolbar()

Code: Select all

;=======================================================================================
;    Method:             StringToNumber
;    Description:        Returns a number based on a string to be used as Command ID.
;=======================================================================================
        StringToNumber(String)
        {
			if(!regexmatch(string,"\d+")){
				Loop, Parse, String
					Number += Asc(A_LoopField) + Number + SubStr(Number, -1)
				return SubStr(Number, 1, 4)
			}else{
				return string
			}
        }
The problem was that the function did not properly convert numbers. I was sending numbers and expecting them to be interpreted as strings, I suppose. Maybe it was my fault.

Actually, I'm not sure this is a good solution I have come up with. It looks like you are trying to build some sort of UUID. Is it diassembled anywhere? At any rate, it seems to ignore the first digit/letter in the string parameter.
fenchai
Posts: 292
Joined: 28 Mar 2016, 07:57

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

22 May 2019, 23:35

Does anyone know how to fix this? https://i.imgur.com/QpZeZNs.png it happens sometimes after Toolbar is created and always happens after I select a Menu Option from the dropdownlist. thanks

fixed: just needed to change the toolbar size lol
Sam_
Posts: 146
Joined: 20 Mar 2014, 20:24

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

12 Jul 2019, 09:01

I have been running into some issues while trying to use this class to add a Toolbar to my GUI. I believe I have traced the issues to the StringToNumber() method returning the same number for different strings (the Command IDs are not unique thus the target labels get messed up). It looks like this method is attempting to hash a string into a unique number, it just isn't very good at it (I am experiencing lots of collisions). My thought was to choose a better hashing function, and since I see that this value is later written as an Int using NumPut, I thought CRC-32 looked promising:

Code: Select all

StringToNumber(str){ ; 'Adapted' from jNizM's CRC32() https://www.autohotkey.com/boards/viewtopic.php?f=6&t=63052&p=269355
    Static table:=[]
    Loop, 256 {
        crc:=A_Index-1
        Loop, 8
            crc:=(crc&1)?(crc>>1)^0xEDB88320:(crc>>1)
        table[A_Index-1]:=crc
    }
    crc:=~0
    Loop, Parse, str
        crc:=table[(crc&0xFF)^Asc(A_LoopField)]^(crc>>8)
    Return Format("{:d}",~crc)
}
Unfortunately, this still doesn't work properly. I played around with it some more, and if I axe the 32-bit number down to a single word (16-bit), the target labels and text seem to work as intended.

Code: Select all

StringToNumber(str){ ; 'Adapted' from jNizM's CRC32() https://www.autohotkey.com/boards/viewtopic.php?f=6&t=63052&p=269355
    Static table:=[]
    Loop, 256 {
        crc:=A_Index-1
        Loop, 8
            crc:=(crc&1)?(crc>>1)^0xEDB88320:(crc>>1)
        table[A_Index-1]:=crc
    }
    crc:=~0
    Loop, Parse, str
        crc:=table[(crc&0xFF)^Asc(A_LoopField)]^(crc>>8)
    Return Format("{:d}",~crc)&0xFFFF
}
However, attempting to represent all possible strings as unique numbers in only 16 bits is a fool's errand. What's going on here and are there any suggestion on how I might go about improving this situation?

TIA,
Sam.
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

17 Jul 2019, 11:51

@Sam Did you try my fix just above yours? I had come to the same conclusion about the error in StringToNumber. I would be interested to see if it works out for you.
Sam_
Posts: 146
Joined: 20 Mar 2014, 20:24

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

17 Jul 2019, 13:46

BGM wrote:
17 Jul 2019, 11:51
@Sam Did you try my fix just above yours? I had come to the same conclusion about the error in StringToNumber. I would be interested to see if it works out for you.
I did try it, but it didn't help since I was trying to use strings, not numbers.
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

17 Jul 2019, 13:55

ah, okay then. Well, maybe someone will spend the time to figure it out completely.
User avatar
Pulover
Posts: 612
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: [Class] Toolbar - Create and modify (Updated 03/17/2016)

08 Sep 2020, 20:40

Looking back now, using a function that converts a string to a 4 digits number was a stupid choice to generate the CommandID... :oops: :P :lol:

This ID can be any number of 1 to 4 digits, so I just updated the class with a simple random number generator method.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 118 guests