Graying out icons

A

Art®

I have created a simple macro that adds a shadow to selected text (by
checking the appropriate box in the font dialog). I have assigned the macro
to a custom icon. I would like to have the icon display its normal colors
whenever the text has shadow selected, but turn gray when the selected text
does not have a shadow.

Can anyone point me in the right direction for this kind of icon toggle.
Thanks in advance.

Art
 
K

Klaus Linke

Hi Art,

I think you would need to write an event handler for the
WindowSelectionChange-event.
That's a pretty daunting task, and I don't know if it's worth it.

You can look at the VBA help and see if you can get something running.

http://msdn.microsoft.com/library/en-us/dnword2k2/html/odc_wdappevnt.asp
by Bill Coan may have further helpful info.

For the button, you'd toggle that CommandBarButton's state with
myCBB.Enabled = True
myCBB.Enabled = False
to toggle the button between pressed/unpressed, highlighted/normal (or
whatever your version of Word uses), depending on whether all of the
selection is formatted with "shadow" after the WindowSelectionChange-event.

Good luck!
....in case you are going to try it, you'll need it ;-)
Klaus
 
A

Art®

I have tried VBA help, read the articles by Bill Coan, searched the msdn
site, and searched using Google, but have not found anything that talks
about how to do this. Seems like a closely guarded secret : )

Art
 
M

Martin Seelhofer

Hi there
[...]
I have tried VBA help, read the articles by Bill Coan, searched the msdn
site, and searched using Google, but have not found anything that talks
about how to do this. Seems like a closely guarded secret : )
[...] --> full quote below

Well, the thing with attaching to the Word-event WindowSelectionChange
is not such a hard thing to do. Here's one way to do achieve what you want:

1. Create a new template and save it in Word's startup folder (such
a template is called an "AddIn")

2. Create a class module (you MUST use a class module!!!) which will
be attached to word events and handle the change of the button state:

' class module "clsSelectionObserver"
Option Explicit

' using "WithEvents" is crucial here!
Dim WithEvents m_wd As Word.Application
' [Note that you can't use WithEvents outside a class module,
' so we are forced to use one]

' get a reference to the running copy of the application
Private Sub Class_Initialize()
Set m_wd = Application
End Sub

' release the reference
Private Sub Class_Terminate()
Set m_wd = Nothing
End Sub

' handle the selection change event
Private Sub m_wd_WindowSelectionChange(ByVal Sel As Selection)
Dim cmd As CommandBarButton
' adjust the button on the command bar
' NOTE: update the following line to access the correct button
Set cmd = CommandBars("SelectionObserver").Controls(1)
' adjust the button state to the selection
cmd.State = IIf(Sel.Font.Shadow, msoButtonDown, msoButtonUp)
End Sub


3. create a code module to instantiate and release the observer class

Option Explicit

Dim MyObserver As clsSelectionObserver

Public Sub StartObserver()
Set MyObserver = New clsSelectionObserver
End Sub

Public Sub EndObserver()
Set MyObserver = Nothing
End Sub


4. update the ThisDocument-class module with the following code

Option Explicit

Private Sub Document_Open()
Call StartObserver
End Sub

Private Sub Document_Close()
Call EndObserver
End Sub


5. write/adjust the macro to switch the shadow-state of the selection,
such that it fires the selection change event (needed in order to
immediately update the button's state)

Public Sub applyShadow()
Selection.Font.Shadow = Not Selection.Font.Shadow
' force event to be fired in order to update the button
Selection.Range.Select
End Sub


6. copy/create the commandbar to/in the newly created template
and place a button for the macro applyShadow on it


7. Save the template, restart Word and enjoy the show :)



Cheers,

Martin
 
M

Martin Seelhofer

Hello again

A not beyond: Since I suggested touse a global template (an "AddIn")
you might have to use the old style Auto-Macros to get the things to work
(Document_Open is not run in a global template...).

Therefore, replace step 4 of my last posting with the following:

4. (updated) Add the following code:

' called automa(g)ically when Word is started
Sub AutoExec()
Call StartObserver
End Sub

' called automa(g)ically when Word is closed
Sub AutoExit()
Call EndObserver
End Sub


Cheers again,

Martin

Martin Seelhofer said:
Hi there
[...]
I have tried VBA help, read the articles by Bill Coan, searched the msdn
site, and searched using Google, but have not found anything that talks
about how to do this. Seems like a closely guarded secret : )
[...] --> full quote below

Well, the thing with attaching to the Word-event WindowSelectionChange
is not such a hard thing to do. Here's one way to do achieve what you want:

1. Create a new template and save it in Word's startup folder (such
a template is called an "AddIn")

2. Create a class module (you MUST use a class module!!!) which will
be attached to word events and handle the change of the button state:

' class module "clsSelectionObserver"
Option Explicit

' using "WithEvents" is crucial here!
Dim WithEvents m_wd As Word.Application
' [Note that you can't use WithEvents outside a class module,
' so we are forced to use one]

' get a reference to the running copy of the application
Private Sub Class_Initialize()
Set m_wd = Application
End Sub

' release the reference
Private Sub Class_Terminate()
Set m_wd = Nothing
End Sub

' handle the selection change event
Private Sub m_wd_WindowSelectionChange(ByVal Sel As Selection)
Dim cmd As CommandBarButton
' adjust the button on the command bar
' NOTE: update the following line to access the correct button
Set cmd = CommandBars("SelectionObserver").Controls(1)
' adjust the button state to the selection
cmd.State = IIf(Sel.Font.Shadow, msoButtonDown, msoButtonUp)
End Sub


3. create a code module to instantiate and release the observer class

Option Explicit

Dim MyObserver As clsSelectionObserver

Public Sub StartObserver()
Set MyObserver = New clsSelectionObserver
End Sub

Public Sub EndObserver()
Set MyObserver = Nothing
End Sub


4. update the ThisDocument-class module with the following code

Option Explicit

Private Sub Document_Open()
Call StartObserver
End Sub

Private Sub Document_Close()
Call EndObserver
End Sub


5. write/adjust the macro to switch the shadow-state of the selection,
such that it fires the selection change event (needed in order to
immediately update the button's state)

Public Sub applyShadow()
Selection.Font.Shadow = Not Selection.Font.Shadow
' force event to be fired in order to update the button
Selection.Range.Select
End Sub


6. copy/create the commandbar to/in the newly created template
and place a button for the macro applyShadow on it


7. Save the template, restart Word and enjoy the show :)



Cheers,

Martin

Art® said:
I have tried VBA help, read the articles by Bill Coan, searched the msdn
site, and searched using Google, but have not found anything that talks
about how to do this. Seems like a closely guarded secret : )

Art
 
A

Art®

Thanks for the help. I have tried to follow your instructions, but am not
sure if I am doing everything correctly. So far, this is what I have:

-------------------------
In Class Modules, Class1:
-------------------------
Option Explicit
Dim WithEvents m_wd As Word.Application

Private Sub Class_Initialize()
Set m_wd = Application
End Sub

Private Sub Class_Terminate()
Set m_wd = Nothing
End Sub

Private Sub m_wd_WindowSelectionChange(ByVal Sel As Selection)
Dim cmd As CommandBarButton
Set cmd = CommandBars("SelectionObserver").Controls(1)
cmd.State = IIf(Sel.Font.Shadow, msoButtonDown, msoButtonUp)
End Sub

---------------------------
In Modules, New Macros:
---------------------------
Option Explicit
Dim MyObserver As clsSelectionObserver

Public Sub StartObserver()
Set MyObserver = New clsSelectionObserver
End Sub

Public Sub EndObserver()
Set MyObserver = Nothing
End Sub

Public Sub applyShadow()
Selection.Font.Shadow = Not Selection.Font.Shadow
Selection.Range.Select
End Sub

Sub AutoExec()
Call StartObserver
End Sub
Sub AutoExit()
Call EndObserver
End Sub

The problem is, that when I exit VBA or restart Word I get a message saying:
Compile error in hidden module: NewMacros

When I try to debug, the following is highlighted: MyObserver As
clsSelectionObserver
and an error message appears saying: Compile error: User-defined type not
defined

Any additional help would be appreciated. Also, I'm not sure I understand
how to do the following: 'NOTE: update the following line to access the
correct button"
Set cmd = CommandBars("SelectionObserver").Controls(1)

Thanks,
Art
 
A

Art®

Okay, I think I was supposed to name the class module:
"clsSelectionObserver"

I have done that and the compile error goes away.

I still need help, though, with the second part of my question:

'NOTE: update the following line to access the correct button"
Set cmd = CommandBars("SelectionObserver").Controls(1)

How do I modify the line above so the macro will know which icon needs to be
grayed in or out?

And do I need to create a new icon to be attached to the new macro(s) we
just created?

Thanks,

Art
 
M

Martin Seelhofer

Hi Art
'NOTE: update the following line to access the correct button"
Set cmd = CommandBars("SelectionObserver").Controls(1)

How do I modify the line above so the macro will know which icon needs to be
grayed in or out?

Just place the name of your command bar between the brackets
following CommandBars and place the position of your button
(as a number) in the brackets following Controls. If your command
bar is called "MyBar" and the button is the first one, use:

Set cmd = CommandBars("MyBar").Controls(1)

If your command bar is called "ShadowBar" and your button is
the second one, use:

Set cmd = CommandBars("ShadowBar").Controls(2)
And do I need to create a new icon to be attached to the new macro(s) we
just created?

Would be a good idea, yes. Place an icon to the macro applyShadow
on the commandbar, and use that icon's position in the code above (note
that separators do also count!)...


Cheers,

Martin
 
A

Art®

Martin,

Thank you, thank you, thank you! Both the macro and the "graying out" of the
icon work like a charm.

Thanks for your patience and persistence with your help.

Art

West Palm Beach, Florida
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top