Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
DiscussionsAccessExcelInfoPathOutlookPowerPointPublisherWord
DirectoryUser Groups
Related Topics
Outlook ExpressInternet ExplorerWindowsMS Server ProductsMore Topics ...

MS Office Forum / Word / Programming / October 2005

Tip: Looking for answers? Try searching our database.

Toggle macro button

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Guillermo - 17 Oct 2005 17:47 GMT
Hello all,

I'd like to know how a macro button can be turned into a toggle, like the bold button
in the format bar, for example.

TIA,

Guillermo
Greg - 17 Oct 2005 18:12 GMT
Guillermo,

I has nothing to do with the button but with the code the button causes
to execute.  For example, if you assigned the following code to a
macrobutton, toolbar button, menu item, shortcut key, etc., it would
toggle text formatted with automatic font color to red font color or
red font color to automatic.

Sub Toggle()
Dim oState As Long
oState = Selection.Range.Font.Color
If oState = -16777216 Then
 Selection.Range.Font.Color = 255
ElseIf oState = 255 Then
 Selection.Range.Font.Color = -16777216
End If
End Sub

The numbers associated with font colors can be determined using the
object browser and search for wdColor.
Guillermo - 17 Oct 2005 21:48 GMT
I see, so it all comes down to a conditional statement. I thought it was something else.

Thank you very much, Greg.

> Sub Toggle()
> Dim oState As Long
[quoted text clipped - 5 lines]
> End If
> End Sub
Charles Kenyon - 17 Oct 2005 23:43 GMT
You _can_ also change the appearance of the button, but this is a real
change in your toolbar, not just the button state.
Signature

Charles Kenyon

Word New User FAQ & Web Directory: http://addbalance.com/word

Intermediate User's Guide to Microsoft Word (supplemented version of
Microsoft's Legal Users' Guide) http://addbalance.com/usersguide

See also the MVP FAQ: http://word.mvps.org/FAQs/ which is awesome!
--------- --------- --------- --------- --------- ---------
This message is posted to a newsgroup. Please post replies
and questions to the newsgroup so that others can learn
from my ignorance and your wisdom.

>I see, so it all comes down to a conditional statement. I thought it was
>something else.
[quoted text clipped - 10 lines]
>> End If
>> End Sub
Klaus Linke - 19 Oct 2005 22:47 GMT
I wouldn't put it that way ;-)

With CommandBars.ActionControl
 .State = Not (.State)
End With

Regards,
Klaus

> You _can_ also change the appearance of the button, but this is a real
> change in your toolbar, not just the button state.
[quoted text clipped - 12 lines]
>>> End If
>>> End Sub
Charles Kenyon - 20 Oct 2005 02:46 GMT
Guess I don't know how to create buttons that have multiple states. I know
it works with the built-in ones.
Signature

Charles Kenyon

Word New User FAQ & Web Directory: http://addbalance.com/word

Intermediate User's Guide to Microsoft Word (supplemented version of
Microsoft's Legal Users' Guide) http://addbalance.com/usersguide

See also the MVP FAQ: http://word.mvps.org/FAQs/ which is awesome!
--------- --------- --------- --------- --------- ---------
This message is posted to a newsgroup. Please post replies
and questions to the newsgroup so that others can learn
from my ignorance and your wisdom.

>I wouldn't put it that way ;-)
>
[quoted text clipped - 21 lines]
>>>> End If
>>>> End Sub
Greg - 20 Oct 2005 12:40 GMT
Klaus,

If you don't mind, have a look at the pictures of the toolbar I created
for an addin.  There are three images  at the bottom of the page:

http://gregmaxey.mvps.org/Bookmark_Tool.htm

Before these I had one tool bar with all four buttons.  Helmut
suggested that I "dim" the "show" and "hide" buttons when the form was
closed.  I couldn't figure out how to do this so opted with the
interactive style as shown.  Unfortunately (and dimming may result the
same) everytime the addin is used and then I closed Word it would
trigger the "Do you want to save changes to BlahBlah.dot"

I got around that by adding  a blahblah.dot Saved flag in the close
routine.

Can you explain to us masses ;-) how to dim a command bar button and if
that would eliminate the problem of Word asking to save changes to the
addin?

Thanks
Klaus Linke - 24 Oct 2005 21:49 GMT
Hi Greg,

DIMming the button won't get rid of your code "dirtying" the template, I'm
afraid.
If you want to ignore just the greying or toggling of the button, you can
save/reset the .Saved state just for that piece of code.

If you don't know the template you'll put the code in (or want to be free to
move it), this will get a bit difficult though, because you'll have to find
out the template that's responsible for that special button.

Maybe I missed an easy way to determine the template that created the button
(and saves any changes to it)...
Anyway, the code below, looping all active templates, should work:

 Dim myCBB As CommandBarButton
 Dim myButtonTemplate As Template, myTemplate As Template
 Dim boolSaved As Boolean
 ' If the code is in the macro is the one that is run by the button:
 Set myCBB = CommandBars.ActionControl
 ' Which template put that button there anyway?
 For Each myTemplate In Application.Templates
   If myCBB.Parent.Context = myTemplate.FullName Then
     Set myButtonTemplate = myTemplate
   End If
 Next myTemplate
 boolSaved = myButtonTemplate.Saved
 ' Do your dirty work...
 myCBB.State = Not (myCBB.State)
 ' myCBB.Enabled = Not (myCBB.Enabled)
 ' ... and then reset the .Saved state:
 myButtonTemplate.Saved = boolSaved

It would be nice if you could wrap that in a macro that toggles any button:
Call ToggleButtonState(myCBB)
(without changing the .Saved state of the template it comes from)
... but I don't think you can pass controls as arguments.
Would be great if someone knows how to do that!

Regards,
Klaus

> Klaus,
>
[quoted text clipped - 18 lines]
>
> Thanks
Greg Maxey - 24 Oct 2005 23:17 GMT
Klaus,

Thanks.

Greg Maxey/Word MVP
See:
http://gregmaxey.mvps.org/word_tips.htm
For some helpful tips using Word.

> Hi Greg,
>
[quoted text clipped - 59 lines]
>>
>> Thanks
Tony Jollans - 25 Oct 2005 00:53 GMT
Hi Klaus,

1. Providing the CommandBar belongs to a Template you can (using your
variable names) ..

Set myButtonTemplate = Templates(myCBB.Parent.Context)

(If it belongs to a document then use Documents(myCBB.Parent.Context) of
course)

2. I don't have any problem passing a button to a procedure something like
this (to toggle any boolean property)

Sub ToggleState(myControl As CommandBarControl, myState As String)

Dim SavedState As Boolean
Dim OldState As Boolean
Dim ControlTemplate As Template

Set ControlTemplate = Templates(myControl.Parent.Context)
SavedState = ControlTemplate.Saved

OldState = CallByName(myControl, myState, VbGet)
CallByName myControl, myState, VbLet, Not OldState

ControlTemplate.Saved = SavedState
Set ControlTemplate = Nothing

End Sub

which can be called like

ToggleState myCBB, "Enabled"

Greg .. Note (if you didn't pick it up from Klaus' post) it is the Enabled
property which controls dimming.

--
Enjoy,
Tony

> Hi Greg,
>
[quoted text clipped - 60 lines]
> >
> > Thanks
Greg Maxey - 25 Oct 2005 01:15 GMT
Tony,

Yes I did pick that up.  I decided that for my purposes I liked the
show/hide approach better.

Signature

Greg Maxey/Word MVP
See:
http://gregmaxey.mvps.org/word_tips.htm
For some helpful tips using Word.

> Hi Klaus,
>
[quoted text clipped - 99 lines]
>>>
>>> Thanks
Greg Maxey - 25 Oct 2005 01:44 GMT
Tony,

Your code is a bit over my head.  Could you provide a little more detail as
to how I would create the toolbar with a button to be enabled and disabled
and then actually enabled and disabled using your code?

Thanks.

Signature

Greg Maxey/Word MVP (who freely admits he still has a lot to learn)
See:
http://gregmaxey.mvps.org/word_tips.htm
For some helpful tips using Word.

> Hi Klaus,
>
[quoted text clipped - 99 lines]
>>>
>>> Thanks
Tony Jollans - 25 Oct 2005 02:14 GMT
Hi Greg,

You create the toolbar as normal. You can use my code with your existing
toolbar.

Drop the Sub into your template somewhere (do you  have a module for common
routines? No, you don't - I've just looked so drop it into the Bookmarker
module)

Then when you want to change one of your buttons call it. For example, you
could change your Sub Hide() like this:

Sub Hide()
oFrm.Hide
ToggleState CommandBars("Bookmarker").Controls("Show"), "Visible"
ToggleState CommandBars("Bookmarker").Controls("Hide"), "Visible"
End Sub

That simply toggles the visible state of each of the two controls - assuming
the Hide one is visble and the Show one isn't, then it will change it so
that the Show one is visible and the Hide one isn't.

What the code does is grab a reference to the template which 'owns' the
control and saves the "Saved" setting. Then it gets the (in this example,
Visible) setting of the control and sets it to the opposite. Then it resets
the Saved property of the template to what it saved before, releases the
template object and that's it. All you have to do is pass it a reference to
the control and the name of the property as a string - it will work for any
boolean property of a control (Visible, Enabled, State, etc.). The
CallByName construct is just a way of using a string for a property name
instead of having to code a reference to it - the string gets resolved at
runtime instead of compile time.

--
Enjoy,
Tony

> Tony,
>
[quoted text clipped - 113 lines]
> >>>
> >>> Thanks
Greg Maxey - 25 Oct 2005 03:08 GMT
Tony,

Ok thanks.  I see how I could use this to toggle the show and hide buttons

Sub ToggleShowHide()
ToggleState CommandBars("Bookmarker").Controls("Show"), "Visible"
If CommandBars("Bookmarker").Controls("Hide").Visible = True Then
 oFrm.Hide
Else
 oFrm.Show vbModeless
End If
ToggleState CommandBars("Bookmarker").Controls("Hide"), "Visible"
End Sub

Sub ToggleState(myControl As CommandBarControl, myState As String)
Dim SavedState As Boolean
Dim OldState As Boolean
Dim ControlTemplate As Template
Set ControlTemplate = Templates(myControl.Parent.Context)
SavedState = ControlTemplate.Saved
OldState = CallByName(myControl, myState, VbGet)
CallByName myControl, myState, VbLet, Not OldState
ControlTemplate.Saved = SavedState
Set ControlTemplate = Nothing
End Sub

With both the Open/Close and Show/Hide buttons being set to toggle, I think
I am going to play it safe and leave my code as is in this case.  In the
future I can keep this method in mind.  For now I am going to stick with old
saw "If it isn't broke, don't fix it."  Thanks again.

Signature

Greg Maxey/Word MVP
See:
http://gregmaxey.mvps.org/word_tips.htm
For some helpful tips using Word.

> Hi Greg,
>
[quoted text clipped - 151 lines]
>>>>>
>>>>> Thanks
Tony Jollans - 25 Oct 2005 09:45 GMT
I agree -  if it ain't broke don't fix it.

I'm not sure I'd actually use it in its current form - I just posted it in
response to Klaus' post saying he didn't know how to do it.

--
Enjoy,
Tony

> Tony,
>
[quoted text clipped - 188 lines]
> >>>>>
> >>>>> Thanks
Greg Maxey - 25 Oct 2005 10:59 GMT
Tony,

One more question.  In setting up a toggle from scratch, I noticed that it
is a little tough to get the initial conditions set up (i.e., one showing
and one hidden).  I created a new toolbar with two buttons, one "hide" and
one "show" (of course) they are both showing and applied your code.  When  I
clicked on either both are hidden.  To get around this, I stetted out one of
the calls, executed the code and the cleared the stet (').  Is there a more
standard procedure?

Signature

Greg Maxey/Word MVP
See:
http://gregmaxey.mvps.org/word_tips.htm
For some helpful tips using Word.

>I agree -  if it ain't broke don't fix it.
>
[quoted text clipped - 200 lines]
>> >>>>>
>> >>>>> Thanks
Tony Jollans - 25 Oct 2005 11:10 GMT
Hi Greg,

When you creat the buttons you need to create the initail state - one hidden
and one shown.

That said, however, I think an optional parameter to my routine (True/False)
to force a setting rather than simply toggle might be helpful, something
like this (done quickly and not tested)

Sub ToggleState(myControl As CommandBarControl, myState As String, Optional
mySetting)

Dim SavedState As Boolean
Dim OldState As Boolean
Dim ControlTemplate As Template

Set ControlTemplate = Templates(myControl.Parent.Context)
SavedState = ControlTemplate.Saved

OldState = CallByName(myControl, myState, VbGet)  ' .Enabled = Not
cc.Enabled
If Not IsMissing(mySetting) Then
   If TypeName(mySetting) = "Boolean" Then OldState = Not mySetting
End If
CallByName myControl, myState, VbLet, Not OldState

ControlTemplate.Saved = SavedState

End Sub

This will (I hope!) force True or False if given as a third parameter.

--
Enjoy,
Tony

> Tony,
>
[quoted text clipped - 215 lines]
> >> >>>>>
> >> >>>>> Thanks
Greg - 25 Oct 2005 14:30 GMT
Tony,

<When you creat the buttons you need to create the initail state - one
hidden
<and one shown.

I created them by dragging then to a new toolbar.  I suppose I could
create the toolbar and the buttons with VBA and then achieve your
statement.

You lost me with your new code.  What is cc?  What is mySetting?

Using the following as an example, how would you apply your new code?

Sub ToggleShowHide()
ToggleState CommandBars("MyToggle").Controls("Bold On"), "Visible"
If CommandBars("MyToggle").Controls("Bold Off").Visible = True Then
 ActiveDocument.Range.Bold = True
Else
 ActiveDocument.Range.Bold = False
End If

ToggleState CommandBars("MyToggle").Controls("Bold Off"), "Visible"
End Sub
Sub ToggleState(myControl As CommandBarControl, myState As String)
Dim SavedState As Boolean
Dim OldState As Boolean
Dim ControlTemplate As Template
Set ControlTemplate = Templates(myControl.Parent.Context)
SavedState = ControlTemplate.Saved
OldState = CallByName(myControl, myState, VbGet)
CallByName myControl, myState, VbLet, Not OldState
ControlTemplate.Saved = SavedState
Set ControlTemplate = Nothing
End Sub

Thanks
Tony Jollans - 25 Oct 2005 15:50 GMT
Hi Greg,

Apologies - the cc is an overflow of a comment on the previous line which I
should have deleted - it's the remnants of earlier code and not relevant at
all. mySetting is also an overflow due to the line breaks added by the
system. I have reformatted in the code below to stop that happening (I
hope).

I just assumed you created your toolbar with VBA but if you've done it via
the UI then you can't make a control hidden. I guess I'd do it with a
one-off statement in the immediate window - whatever, it needs VBA.

The new code adds an optional override to the toggle setting so, for
example, you could do ..

ToggleState CommandBars("Bookmarker").Controls("Hide"), "Visible", False

to force the setting of visible to false (i.e. hide the control) instead of
toggling what was there before. myOverride might have been a better choice
of name than mySetting.

The extra parameter is optional so that the original still worked, in other
words ..

ToggleState CommandBars("Bookmarker").Controls("Hide"), "Visible"

still toggled the setting.

To use it (somewhat artificially) in your example you could be explicit in
what you set rather than toggling. I think you've got the check wrong so
I've changed it in this ..

Sub ToggleShowHide()
ToggleState CommandBars("MyToggle").Controls("Bold On"), "Visible", False
If CommandBars("MyToggle").Controls("Bold Off").Visible = False Then
 ActiveDocument.Range.Bold = True
Else
 ActiveDocument.Range.Bold = False
End If

ToggleState CommandBars("MyToggle").Controls("Bold Off"), "Visible", True
End Sub

Sub ToggleState(myControl As CommandBarControl, _
                         myState As String, _
                         Optional mySetting)

Dim SavedState As Boolean
Dim OldState As Boolean
Dim ControlTemplate As Template

Set ControlTemplate = Templates(myControl.Parent.Context)
SavedState = ControlTemplate.Saved

OldState = CallByName(myControl, myState, VbGet)
If Not IsMissing(mySetting) Then
   If TypeName(mySetting) = "Boolean" Then OldState = Not mySetting
End If
CallByName myControl, myState, VbLet, Not OldState

ControlTemplate.Saved = SavedState

End Sub

It's your code, but I would actually do it more simply ..

Sub ToggleShowHide()
With CommandBars("MyToggle")
   ActiveDocument.Range.Bold = .Controls("Bold On").Visible
   ToggleState .Controls("Bold On"), "Visible"
   ToggleState .Controls("Bold Off"), "Visible"
End With
End Sub

The possible permutations are endless - you could, perhaps, make the
ToggleState procedure automatically toggle two buttons at a time (as that's
what you're always doing - and probably always will) - or you could give it
two buttons and tell it to ensure one is true, the other false, etc., etc. -
the world, as they say, is your lobster (or something of the sort). As
already agreed, if it works don't fix it.

--
Enjoy,
Tony

> Tony,
>
[quoted text clipped - 33 lines]
>
> Thanks
Greg - 25 Oct 2005 16:26 GMT
Klaus Linke - 26 Oct 2005 00:18 GMT
Hi Tony,

> Set myButtonTemplate = Templates(myCBB.Parent.Context)

Aah, bingo! Thank you, I knew my code was overly complicated!

Though it probably had a logical error, too: Say an attached template or
global template has added a button to some built-in toolbar, then the Parent
would be Normal.dot, not that template. And I would want keep the template's
.Saved flag clean, not Normal.dots.

> Sub ToggleState(myControl As CommandBarControl, myState As String)

Strange, that is exactly what I tried yesterday. Not sure what I did wrong,
but glad it does work as expected.

Thanks!
Klaus
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.