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!
Re: [Class] Toolbar - Create and modify
Posted: 22 Nov 2013, 20:19
by BGM
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 ?
Re: [Class] Toolbar - Create and modify
Posted: 22 Nov 2013, 20:47
by Pulover
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:
;Get the width of all the buttons, taking into account the width of separators, too.
GetToolbarWidth(){
global hMyToolbar
numberofbuttons := hMyToolbar.getcount()
totalwidth := 20 ;I'm not sure why this must be added, must be for padding or something (if you don't add it, the buttons on the end are partially cut off)
loop %numberofbuttons%
{
hMyToolbar.GetButtonPos(a_index, "", "", thisbuttonW)
totalwidth := totalwidth + thisbuttonW
}
return totalwidth
}
;Resize the main GUI to fit the length of the horizontal toolbar
ResizeMainGUI(){
global hMyToolbar, tbH, tbW, toolbarX, toolbarY, textworxtoolbar
tbW := GetToolbarWidth()
;controlmove,,,,%tbW%,,ahk_id %hMyToolbar%
guicontrol, move, ahk_id %hMyToolbar%, w%tbW%
Gui, 1:Show, w%tbW% ,%myMainGUI%
}
Re: [Class] Toolbar - Create and modify
Posted: 23 Nov 2013, 20:11
by BGM
Pulover, thanks for your help with the simpler export. I appreciate that. It's just what I needed.
Re: [Class] Toolbar - Create and modify
Posted: 25 Nov 2013, 06:45
by Learning one
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.
Re: [Class] Toolbar - Create and modify
Posted: 25 Nov 2013, 11:49
by Pulover
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.
Re: [Class] Toolbar - Create and modify
Posted: 25 Nov 2013, 16:26
by BGM
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.
Re: [Class] Toolbar - Create and modify
Posted: 25 Nov 2013, 16:55
by Pulover
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?
Re: [Class] Toolbar - Create and modify
Posted: 25 Nov 2013, 17:08
by BGM
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?
Re: [Class] Toolbar - Create and modify
Posted: 25 Nov 2013, 17:21
by Pulover
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.
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.
Re: [Class] Toolbar - Create and modify
Posted: 25 Nov 2013, 18:12
by Pulover
Here's something to illustrate my idea (press F2 to cycle through the presets):
#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...
Re: [Class] Toolbar - Create and modify
Posted: 25 Nov 2013, 18:33
by BGM
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?
Re: [Class] Toolbar - Create and modify
Posted: 25 Nov 2013, 22:54
by BGM
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.
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.
Re: [Class] Toolbar - Create and modify
Posted: 26 Nov 2013, 12:23
by Pulover
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.
Re: [Class] Toolbar - Create and modify
Posted: 26 Nov 2013, 12:41
by BGM
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.
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:
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
As you see, I make the index for the array using the variable allbuttoncounter (no I didn't really expect you to delve into my system, but I sure appreciate it).
;build an array of all the button numbers (which are also their labels).
allbuttons := []
allbuttoncounter := 0 ;use counter to create the index of the button labels
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.
}
}
Now, I totally missed the LabelToIndex() !!! Or I would have tried that.
So, using that, this does work!
loop, parse, thesebuttons, |
{
if(!a_loopfield)
myToolbar.Insert(a_index) ; insert separator at the right position
myToolbar.MoveButton(myToolbar.LabelToIndex(a_loopfield), a_index)
}
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!