[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

22 Nov 2013, 19:46

Yes, export() and presets.export() will do the same but the first will export the current layout and the latter can export multiple layouts stored in an object. If you don't need multiple layout presets you can just use export(). I was going to use the presets in PMC but after the long road I went through to implement the toolbars and rebars I dropped the idea...

Your idea of adding all buttons upon start then selecting the ones that should be visible is good and more appropriate in some cases. In fact that's how I do it in PMC. The examples in the demo are to illustrate ways to implement the features but are still suggestions, the coder might find other ways that suit him better.

Writing those two classes was crazy... I still need to consult that demo and the descriptions myself every time I want to use them! :P
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify

22 Nov 2013, 20:19

Ha ha! I've been there too. I like your sense of humour! Thanks for being so friendly.

In my application, I want LOTS of functions that a user can choose from to build several custom toolbars. But I don't like exporting all 200 buttons to a single line in the ini file - it just ain't clean. The user won't ever have more than 20 buttons on one bar.

My application adds all the buttons at start, so I don't need to know about all the buttons that are not visible.
I suppose that means I'll have to figure out my own export :(?
User avatar
Pulover
Posts: 612
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: [Class] Toolbar - Create and modify

22 Nov 2013, 20:47

This may not be so difficult. You can export the buttons to an array and create the ini as you want.
The exported object will be an array of other objects with named keys, for example:

Code: Select all

Buttons := MyToolbar.Export(1)
For each, button in Buttons
{
    msgbox % button.Label
          . "`n" button.Text
          . "`n" button.Icon
}
; or
Loop, 200
    msgbox % Buttons[A_index].Label
Untested but should work. I'm not sure but I think hidden buttons are not exported in this method.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify

23 Nov 2013, 20:11

I had an issue where I needed to resize my GUI to fit the toolbar (the gui IS the toolbar), so I came up with this (in case anyone is interested):
Spoiler
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify

23 Nov 2013, 20:11

Pulover, thanks for your help with the simpler export. I appreciate that. It's just what I needed.
User avatar
Learning one
Posts: 173
Joined: 04 Oct 2013, 13:59
Location: Croatia
Contact:

Re: [Class] Toolbar - Create and modify

25 Nov 2013, 06:45

Great job Pulover, thanks for sharing! :)
What are the terms of use for your [Class] Toolbar? Can it be used freely if appropriate credits are provided?
Btw, I think that putting a link to your Toolbar_demo_simple in the first post would help new users a lot to quickly learn how to use your [Class] Toolbar. ;)
User avatar
Pulover
Posts: 612
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: [Class] Toolbar - Create and modify

25 Nov 2013, 11:49

LearningOne wrote:Great job Pulover, thanks for sharing! :)
What are the terms of use for your [Class] Toolbar? Can it be used freely if appropriate credits are provided?
Thanks, LearningOne! Yes, everyone is allowed to use it, modify it and distribute it. And of course I'll be glad to receive the appropriate credits. There should be an update soon, Nazzal has sent me suggestions along with some code to add to the class, but I've been busy with other projects these days so I'll take a look in a week or two.
LearningOne wrote:Btw, I think that putting a link to your Toolbar_demo_simple in the first post would help new users a lot to quickly learn how to use your [Class] Toolbar. ;)
Yes, I was asked to do that earlier but forgot to. Just added another gist with it there.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify

25 Nov 2013, 16:26

Pulover, is myToolbar.Delete() supposed to delete ALL the buttons, or just the visible ones? Is there a routine to remove just the visible ones and put them back into the hidden collection?

I am trying to write my own method to switch buttonsets (presets) because I have a different system of fetching the names and saving.

So, say I want to remove all the currently visible buttons and replace them with different ones?

If I do myToolbar.Delete()
and then add the visible buttons
then add the invisible buttons
it seems to work when I first create everything.

But I am having difficulties switching midstream.
My plan is to use Delete()
and then Add()
but my non-visible buttons get doubled in the customization box, and my visible buttons won't display.
User avatar
Pulover
Posts: 612
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: [Class] Toolbar - Create and modify

25 Nov 2013, 16:55

Delete() is the same as hiding a button, all deleted buttons will be moved to the hidden buttons in the customize dialog.
You want to keep all the buttons available and show only the ones in the preset, right? I can't remember any method to directly add a hidden button but you could use Reset() to add all buttons to the toolbar in the default order and then Delete(N) right after for each button you want hidden (an array will do you just fine), and maybe MoveButton() to reorder. What do you think?
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify

25 Nov 2013, 17:08

Okay, so, to change buttonsets, I
Delete() the current set.
Now all my buttons are hidden.
I now need to get the next buttonset (preset is what you call it) visible.

If I use Add() again, the buttons won't become visible.
So, I need something like Show() so, instead of Add()ing them in order like you would at the start, I could Show() them in order as long as the buttons have already been Add()ed.

Does that make any sense?
User avatar
Pulover
Posts: 612
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: [Class] Toolbar - Create and modify

25 Nov 2013, 17:21

Yes but the problem is this Show() method... I don't know of anything like this (or I can't remember now). There is ModifyButton() but I don't think this will work because it's based on button's position on the toolbar. This is why I suggested you do the other way around. For example, supposing you have 4 buttons and you want to show a preset of buttons 1 and 3, the code below would add all buttons in your set and delete 2 of them, so it's the same as deleting all of them and adding the ones you want.

Code: Select all

MyToolbar.Reset()
MyToolbar.Delete(2)
MyToolbar.Delete(4)
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify

25 Nov 2013, 17:54

Okay, well, I LIKE deleting them all and adding them all over again.
I'm still not sure how to get it using the workaround.

So, I tried this:
In my initiation, I used this: myToolbar.SetDefault() - to try and get a blank toolbar.
Then, when I switch,
myToolbar.Reset()
myToolbar.Delete()
But I need to get the new set visible - and I can't use Add() (right?) I don't want to use Insert() because I want to add them one by one.
I'm sorry I'm so hard headed here.
User avatar
Pulover
Posts: 612
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: [Class] Toolbar - Create and modify

25 Nov 2013, 18:12

Here's something to illustrate my idea (press F2 to cycle through the presets):

Code: Select all

#NoEnv
#SingleInstance, Force
#Include <Class_Toolbar>

N := 1

Preset := [[1,3,4],[2,4],[2,3,4],[1,2,3],[1,2,3,4]]

; Create an ImageList.
ILA := IL_Create(4, 2, True)
IL_Add(ILA, "shell32.dll", 127)
IL_Add(ILA, "shell32.dll", 128)
IL_Add(ILA, "shell32.dll", 129)
IL_Add(ILA, "shell32.dll", 130)

; 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)

; Set ImageList.
MyToolbar.SetImageList(ILA)

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

; Removes text labels and show them as tooltips.
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.
Label1:
Label2:
Label3:
Label4:
MsgBox, You selected %A_ThisLabel%
return

ShiftLabel:
MsgBox, You selected %A_ThisLabel%
return

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

F2::
MyToolbar.Reset()
If (N > 4)
	N := 1
Else
	N++
Buttons := ""
For i, k in Preset[N]
	Buttons .= k ","
Loop, 4
	If A_Index not in %Buttons%
		MyToolbar.Delete(A_Index)
return

GuiClose:
ExitApp
return
I still can't think of a better way, but it's been some time since I was really immersed in this code...
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify

25 Nov 2013, 18:33

Okay, let me ponder over that. Thanks for your time!

later...

Ah, so it looks like you are doing this:
1. add every possible button
2. Delete() all the ones you don't want to show.
3. You only need the button's index to delete it.

When you change toolbars, you repeat that.
Am I crazy, or is that what you are doing?
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify

25 Nov 2013, 22:54

Okay, I'm totally stumped with this.

So I build an array of all the possible buttons so that I know their button index as I create them.

Code: Select all

thesebuttons := "101|102|145|125|199"

       ;build an array of all the button numbers (which are also their labels).
	allbuttons := []
	allbuttoncounter := 0
	loop, 999
	{
		if( islabel(a_index) ){  ;only add the button if it has a corresponding label
		    allbuttoncounter++
		    allbuttons[allbuttoncounter] := a_index  ;store the label number in the correct index
		    AddToolbarButton(a_index,1)  ;this adds the button as visible, and fetches the label, text and icon, too.  It works.

		}
	}		


        myToolbar.Reset()	;I need this in case I am chainging presets
        ;now loop through all the possible buttons in the array, and see if any of them exist in my preset string.
        ;delete the buttons that are not in the preset
	loop % allbuttons.maxindex()
	{
		if(!instr(thesebuttons, allbuttons[a_index])){
			myToolbar.Delete(a_index)
                        alert(removed allbuttons[a_index])  ;this alert is always correct!  But the button isn't deleted.
                }
	}
Okay, now it should have added all the buttons and then deleted the ones not in the thesebuttons string, right?
Well, I think it should, but it doesn't. Where am I going wrong? It seems like the buttons don't get removed.
User avatar
Pulover
Posts: 612
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: [Class] Toolbar - Create and modify

26 Nov 2013, 12:23

Well, what I could notice is that InStr() won't work for this. When you check if 1 or 10 is in "101|102|145|125|199" it returns true. You need a different method to check.
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify

26 Nov 2013, 12:41

Thanks for looking at that! But isn't instr() supposed to find the substring?

When the allbuttons array is built, the values are always 3 digits, and greater than 100.
When I use the instr() routine, I search in thesebuttons to find a matching value that is allbuttons[a_index], which is always 3 digits.
The 3 digit number only appears once in the array.
Isn't instr supposed to find the entire substring? I don't understand why that wouldn't work.
When I use messageboxes to report the values, then they are correct. I checked the button index too, and it is correct.

Code: Select all

	myToolbar.Reset()	
	loop % allbuttons.maxindex()
	{
		if(instr(thesebuttons,allbuttons[a_index]) ){
			alert(isthere . " found: " . allbuttons[a_index] . " index=" . a_index)
		}else{
			;alert(allbuttons[a_index] . " should be deleted")
			myToolbar.Delete(a_index)
			alert(isthere . " not found: " . allbuttons[a_index] . " index=" . a_index)
		}
	}
You might be right, but I don't understand how.
User avatar
Pulover
Posts: 612
Joined: 29 Sep 2013, 19:51
Location: Brazil
Contact:

Re: [Class] Toolbar - Create and modify

26 Nov 2013, 19:00

I didn't know the labels had 3 digits... I'm not sure but are you trying to delete the buttons based on label? Because this wouldn't work. Delete() requires the button index, i.e. its position in the toolbar. If so you may use LabelToIndex() to get the correct value, something like:

Code: Select all

myToolbar.Delete(LabelToIndex(allbuttons[a_index]))
Rodolfo U. Batista
Pulover's Macro Creator - Automation Tool (Recorder & Script Writer)
User avatar
BGM
Posts: 507
Joined: 20 Nov 2013, 20:56
Contact:

Re: [Class] Toolbar - Create and modify

26 Nov 2013, 22:36

Pulover, no, you missed my point. In the first snippet I showed how I got the array. I understand you can't delete a button via the label, but you can with the button's index on the toolbar.
Spoiler
It works now! Thanks, Pulover!
Now, I can store my preset in the ini file like this: 100=Default|101|102||304|201||103
Thanks for your patience with me!

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: gwarble and 121 guests