I have quite a few toolbar buttons that I've carried over from Word 2002 and probably before.
I still use them, but I'd like to find out what Word command or macro some of these buttons represent. (The purpose is to incorporate the underlying Word command in a new macro.)
Is there any way to reverse-engineer a toolbar button and find out which Word command/macro/font/style it represents? I tried Customization but couldn't find out the underlying command/macro/etc. of a button.
Is it possible to reverse-engineer a toolbar button?
-
- 4StarLounger
- Posts: 437
- Joined: 05 Nov 2012, 20:02
-
- Administrator
- Posts: 78483
- Joined: 16 Jan 2010, 00:14
- Status: Microsoft MVP
- Location: Wageningen, The Netherlands
Re: Is it possible to reverse-engineer a toolbar button?
If nobody else replies, I'll post a macro later.
Best wishes,
Hans
Hans
-
- NewLounger
- Posts: 22
- Joined: 24 Jul 2013, 17:55
- Location: Worldly
Re: Is it possible to reverse-engineer a toolbar button?
Why don't you just record a macro and find out what the command call is?
Alternatively you can loop through the CommandBar collection and print all the names:
It looks like the newer versions of Word changed from msoControls to msoControlTypes for the enumerations, which is why you also need the following function (which I used in the code above):
Then you should be able to call a specific control using one or a combo of the following:
(1.) Application.CommandBars(>>Name here<<).Controls(>>Name here<<)
(2.) Application.CommandBars(>>CommandBar Index here<<).Controls(>>CommandBarControl Index for the current CommandBar here<<)
Should be enough to get you started I think.
Alternatively you can loop through the CommandBar collection and print all the names:
Code: Select all
Sub PrintCommandBarInfo()
Dim cbr As CommandBar '// collection of CommandBar objects
Dim ctrl As CommandBarControl '// collection of CommandBarControl objects contained in a CommandBar object
'// Loop through each member (or index) of the CommandBar collection
For Each cbr In Application.CommandBars
Debug.Print "______________________________________________________________________"
Debug.Print "CommandBar:= " & cbr.Name
Debug.Print "CommandBars(Idx):= " & cbr.Index '// index of the CommandBars collection
Debug.Print "Type:= " & VBA.IIf(cbr.BuiltIn, "Built-in", "**Custom")
Debug.Print "______________________________________________________________________"
'// Loop through each member (or index) of the CommandBarControl collection for the current CommandBar
For Each ctrl In cbr.Controls
With ctrl
Debug.Print "----------------------------------------------------------------------"
Debug.Print "Parent:= " & """" & .Parent.Name & """"
Debug.Print "cbr.Controls(Idx):= " & .Index '// control index of the current CommandBar object
Debug.Print "ID:= " & .ID '// internal (Microsoft) unique identifier
Debug.Print "Type:= <" & .Type & "> " & GetControlTypeName(.Type)
Debug.Print "Caption:= " & .Caption
Debug.Print "TooltipText:= " & .TooltipText
Debug.Print "Description:= " & .DescriptionText
End With
Next ctrl '// In cbr.Controls
DoEvents
Next cbr '// In Application.CommandBars
End Sub
Code: Select all
Function GetControlTypeName(vType As MsoControlType) As String
Dim sType As String
Select Case vType
Case Is = MsoControlType.msoControlActiveX
sType = "ActiveX"
Case Is = MsoControlType.msoControlAutoCompleteCombo
sType = "Auto Complete Combo"
Case Is = MsoControlType.msoControlButton
sType = "Button"
Case Is = MsoControlType.msoControlButtonDropdown
sType = "Button Dropdown"
Case Is = MsoControlType.msoControlButtonPopup
sType = "Button Popup"
Case Is = MsoControlType.msoControlComboBox
sType = "Combo Box"
Case Is = MsoControlType.msoControlCustom
sType = "Custom"
Case Is = MsoControlType.msoControlDropdown
sType = "Dropdown"
Case Is = MsoControlType.msoControlEdit
sType = "Edit"
Case Is = MsoControlType.msoControlExpandingGrid
sType = "Expanding Grid"
Case Is = MsoControlType.msoControlGauge
sType = "Gauge"
Case Is = MsoControlType.msoControlGenericDropdown
sType = "Generic Dropdown"
Case Is = MsoControlType.msoControlGraphicCombo
sType = "Graphic Combo"
Case Is = MsoControlType.msoControlGraphicDropdown
sType = "Graphic Dropdown"
Case Is = MsoControlType.msoControlGraphicPopup
sType = "Graphic Popup"
Case Is = MsoControlType.msoControlGrid
sType = "Grid"
Case Is = MsoControlType.msoControlLabel
sType = "Label"
Case Is = MsoControlType.msoControlLabelEx
sType = "Label Ex"
Case Is = MsoControlType.msoControlOCXDropdown
sType = "OCX Dropdown"
Case Is = MsoControlType.msoControlPane
sType = "Pane"
Case Is = MsoControlType.msoControlPopup
sType = "Popup"
Case Is = MsoControlType.msoControlSpinner
sType = "Spinner"
Case Is = MsoControlType.msoControlSplitButtonMRUPopup
sType = "Split Button MRU Popup"
Case Is = MsoControlType.msoControlSplitButtonPopup
sType = "Split Button Popup"
Case Is = MsoControlType.msoControlSplitDropdown
sType = "Split Dropdown"
Case Is = MsoControlType.msoControlSplitExpandingGrid
sType = "Split Expanding Grid"
Case Is = MsoControlType.msoControlWorkPane
sType = "Work Pane"
Case Else
sType = "Unknown control type"
End Select
GetControlTypeName = sType
End Function
(1.) Application.CommandBars(>>Name here<<).Controls(>>Name here<<)
(2.) Application.CommandBars(>>CommandBar Index here<<).Controls(>>CommandBarControl Index for the current CommandBar here<<)
Should be enough to get you started I think.
-
- Administrator
- Posts: 78483
- Joined: 16 Jan 2010, 00:14
- Status: Microsoft MVP
- Location: Wageningen, The Netherlands
Re: Is it possible to reverse-engineer a toolbar button?
Thanks! Saves me a lot of work...
Best wishes,
Hans
Hans
-
- 4StarLounger
- Posts: 437
- Joined: 05 Nov 2012, 20:02
Re: Is it possible to reverse-engineer a toolbar button?
How is this supposed be run?
I ran PrintCommandBarInfo as a macro, but nothing. (I did copy the GetControlTypeName function as well.)
I ran PrintCommandBarInfo as a macro, but nothing. (I did copy the GetControlTypeName function as well.)
bjsatola wrote:Why don't you just record a macro and find out what the command call is?
Alternatively you can loop through the CommandBar collection and print all the names:
It looks like the newer versions of Word changed from msoControls to msoControlTypes for the enumerations, which is why you also need the following function (which I used in the code above):Code: Select all
Sub PrintCommandBarInfo() Dim cbr As CommandBar '// collection of CommandBar objects Dim ctrl As CommandBarControl '// collection of CommandBarControl objects contained in a CommandBar object '// Loop through each member (or index) of the CommandBar collection For Each cbr In Application.CommandBars Debug.Print "______________________________________________________________________" Debug.Print "CommandBar:= " & cbr.Name Debug.Print "CommandBars(Idx):= " & cbr.Index '// index of the CommandBars collection Debug.Print "Type:= " & VBA.IIf(cbr.BuiltIn, "Built-in", "**Custom") Debug.Print "______________________________________________________________________" '// Loop through each member (or index) of the CommandBarControl collection for the current CommandBar For Each ctrl In cbr.Controls With ctrl Debug.Print "----------------------------------------------------------------------" Debug.Print "Parent:= " & """" & .Parent.Name & """" Debug.Print "cbr.Controls(Idx):= " & .Index '// control index of the current CommandBar object Debug.Print "ID:= " & .ID '// internal (Microsoft) unique identifier Debug.Print "Type:= <" & .Type & "> " & GetControlTypeName(.Type) Debug.Print "Caption:= " & .Caption Debug.Print "TooltipText:= " & .TooltipText Debug.Print "Description:= " & .DescriptionText End With Next ctrl '// In cbr.Controls DoEvents Next cbr '// In Application.CommandBars End Sub
Then you should be able to call a specific control using one or a combo of the following:Code: Select all
Function GetControlTypeName(vType As MsoControlType) As String Dim sType As String Select Case vType Case Is = MsoControlType.msoControlActiveX sType = "ActiveX" Case Is = MsoControlType.msoControlAutoCompleteCombo sType = "Auto Complete Combo" Case Is = MsoControlType.msoControlButton sType = "Button" Case Is = MsoControlType.msoControlButtonDropdown sType = "Button Dropdown" Case Is = MsoControlType.msoControlButtonPopup sType = "Button Popup" Case Is = MsoControlType.msoControlComboBox sType = "Combo Box" Case Is = MsoControlType.msoControlCustom sType = "Custom" Case Is = MsoControlType.msoControlDropdown sType = "Dropdown" Case Is = MsoControlType.msoControlEdit sType = "Edit" Case Is = MsoControlType.msoControlExpandingGrid sType = "Expanding Grid" Case Is = MsoControlType.msoControlGauge sType = "Gauge" Case Is = MsoControlType.msoControlGenericDropdown sType = "Generic Dropdown" Case Is = MsoControlType.msoControlGraphicCombo sType = "Graphic Combo" Case Is = MsoControlType.msoControlGraphicDropdown sType = "Graphic Dropdown" Case Is = MsoControlType.msoControlGraphicPopup sType = "Graphic Popup" Case Is = MsoControlType.msoControlGrid sType = "Grid" Case Is = MsoControlType.msoControlLabel sType = "Label" Case Is = MsoControlType.msoControlLabelEx sType = "Label Ex" Case Is = MsoControlType.msoControlOCXDropdown sType = "OCX Dropdown" Case Is = MsoControlType.msoControlPane sType = "Pane" Case Is = MsoControlType.msoControlPopup sType = "Popup" Case Is = MsoControlType.msoControlSpinner sType = "Spinner" Case Is = MsoControlType.msoControlSplitButtonMRUPopup sType = "Split Button MRU Popup" Case Is = MsoControlType.msoControlSplitButtonPopup sType = "Split Button Popup" Case Is = MsoControlType.msoControlSplitDropdown sType = "Split Dropdown" Case Is = MsoControlType.msoControlSplitExpandingGrid sType = "Split Expanding Grid" Case Is = MsoControlType.msoControlWorkPane sType = "Work Pane" Case Else sType = "Unknown control type" End Select GetControlTypeName = sType End Function
(1.) Application.CommandBars(>>Name here<<).Controls(>>Name here<<)
(2.) Application.CommandBars(>>CommandBar Index here<<).Controls(>>CommandBarControl Index for the current CommandBar here<<)
Should be enough to get you started I think.
-
- Administrator
- Posts: 78483
- Joined: 16 Jan 2010, 00:14
- Status: Microsoft MVP
- Location: Wageningen, The Netherlands
Re: Is it possible to reverse-engineer a toolbar button?
The code produces output in the Immediate window in the Visual Basic Editor. Press Ctrl+G in the Visual Basic Editor to activate this window.
The following version will create a new document and fill it:
This version replaces the macro PrintCommandBarInfo posted by BJSatola. You need to keep the GetControlTypeName function.
The following version will create a new document and fill it:
Code: Select all
Sub PrintCommandBarInfo()
Dim doc As Document
Dim cbr As CommandBar '// collection of CommandBar objects
Dim ctrl As CommandBarControl '// collection of CommandBarControl objects contained in a CommandBar object
Application.ScreenUpdating = False
Set doc = Documents.Add
'// Loop through each member (or index) of the CommandBar collection
For Each cbr In Application.CommandBars
doc.Content.InsertAfter "______________________________________________________________________"
doc.Content.InsertParagraphAfter
doc.Content.InsertAfter "CommandBar:= " & cbr.Name
doc.Content.InsertParagraphAfter
doc.Content.InsertAfter "CommandBars(Idx):= " & cbr.Index '// index of the CommandBars collection
doc.Content.InsertParagraphAfter
doc.Content.InsertAfter "Type:= " & VBA.IIf(cbr.BuiltIn, "Built-in", "**Custom")
doc.Content.InsertParagraphAfter
doc.Content.InsertAfter "______________________________________________________________________"
doc.Content.InsertParagraphAfter
'// Loop through each member (or index) of the CommandBarControl collection for the current CommandBar
For Each ctrl In cbr.Controls
With ctrl
doc.Content.InsertAfter "----------------------------------------------------------------------"
doc.Content.InsertParagraphAfter
doc.Content.InsertAfter "Parent:= " & """" & .Parent.Name & """"
doc.Content.InsertParagraphAfter
doc.Content.InsertAfter "cbr.Controls(Idx):= " & .Index '// control index of the current CommandBar object
doc.Content.InsertParagraphAfter
doc.Content.InsertAfter "ID:= " & .ID '// internal (Microsoft) unique identifier
doc.Content.InsertParagraphAfter
doc.Content.InsertAfter "Type:= <" & .Type & "> " & GetControlTypeName(.Type)
doc.Content.InsertParagraphAfter
doc.Content.InsertAfter "Caption:= " & .Caption
doc.Content.InsertParagraphAfter
doc.Content.InsertAfter "TooltipText:= " & .TooltipText
doc.Content.InsertParagraphAfter
doc.Content.InsertAfter "Description:= " & .DescriptionText
doc.Content.InsertParagraphAfter
End With
Next ctrl '// In cbr.Controls
DoEvents
Next cbr '// In Application.CommandBars
Application.ScreenUpdating = True
End Sub
Best wishes,
Hans
Hans
-
- 4StarLounger
- Posts: 437
- Joined: 05 Nov 2012, 20:02
Re: Is it possible to reverse-engineer a toolbar button?
Ok, it now works as a macro and outputs the result in a document.
But the only identifiable information in the result is the "ID" of the button. Caption, TooltipText and Description don't provide which command/style they represent. (The exception is macro. The result displays the underlying macro in Caption and TooltipText.)
But the only identifiable information in the result is the "ID" of the button. Caption, TooltipText and Description don't provide which command/style they represent. (The exception is macro. The result displays the underlying macro in Caption and TooltipText.)
-
- Administrator
- Posts: 78483
- Joined: 16 Jan 2010, 00:14
- Status: Microsoft MVP
- Location: Wageningen, The Netherlands
Re: Is it possible to reverse-engineer a toolbar button?
I'm afraid this is as much information as you can get. (If someone else has a better solution, I'll gladly concede my error)
Best wishes,
Hans
Hans
-
- 4StarLounger
- Posts: 437
- Joined: 05 Nov 2012, 20:02
Re: Is it possible to reverse-engineer a toolbar button?
I found this. I think the lists contain the Control IDs that your macro will reveal.HansV wrote:I'm afraid this is as much information as you can get. (If someone else has a better solution, I'll gladly concede my error)
http://www.microsoft.com/en-us/download ... px?id=3582" onclick="window.open(this.href);return false;
Last edited by New Daddy on 04 Feb 2014, 22:02, edited 1 time in total.
-
- NewLounger
- Posts: 22
- Joined: 24 Jul 2013, 17:55
- Location: Worldly
Re: Is it possible to reverse-engineer a toolbar button?
You just need to scroll over the buttons you are wanting to reference from within Word and then do an equivalent search within the *.doc file that was previously outputted (thanks Hans) to find the appropriate matches.
So you can search, for instance, "Save (Ctrl+S)"
And you quickly find that the control's ID:= 3, and turns up in more than one CommandBar collection (e.g. "Standard", "Outlook Send Mail" etc.).
It is just a control and can be re-used by other CommandBars, which is why you need to also reference the appropriate CommandBar that uses it to get the action that you are looking for.
At least that is my thinking... I did a few searches, and it seems to work for me.
So you can search, for instance, "Save (Ctrl+S)"
And you quickly find that the control's ID:= 3, and turns up in more than one CommandBar collection (e.g. "Standard", "Outlook Send Mail" etc.).
It is just a control and can be re-used by other CommandBars, which is why you need to also reference the appropriate CommandBar that uses it to get the action that you are looking for.
At least that is my thinking... I did a few searches, and it seems to work for me.