Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm working on a few projects for work using Excel and VBA, so I have no choice but to use the Microsoft Visual Basic editor. I normally wouldn't mind, but I can't figure out how to set a custom colour for the editor (I can only choose from the default palette).

To change the colour currently, I go to Tools -> Options -> Editor Format... However, your choices are only limited to the default (and basic) 16 colours - and when I say basic, I mean basic, like pink, blue, black, white, etc...

Does anyone know how to either specify a custom colour, or at the very least, change some of the colours that show up in the default palette?

share|improve this question
    
I looked around again, as someone had asked a similar question either on here or SO, but I couldn't dig it up. In that general arena, there is MZ-Tools which seems to have everything but the kitchen sink, except for highlighting. People seem to claim they use Notepad++, and I found a VB specific highlighting mode for that, but I don't know if that will suffice for VBA. –  jonsca Jul 21 '11 at 19:43
    
@jonsca, that's what I've been using for the time being - it's just a pain because of the lack of auto-complete (for my functions/variables and the built-in Excel objects), and the fact that I'm constantly copying and pasting between editors. I'm open to using VBA addons, but I have tried MZ-Tools and it does not have custom syntax highlighting. :( –  Breakthrough Jul 21 '11 at 19:45
1  
Yeah, it seems to be a vexing problem for a lot of people. Wish I had had something better to report. –  jonsca Jul 21 '11 at 21:42

5 Answers 5

up vote 12 down vote accepted
+50

VBA reads the settings for the colors from these registry keys:

HKEY_CURRENT_USER\Software\Microsoft\VBA\6.0\Common\CodeForeColors HKEY_CURRENT_USER\Software\Microsoft\VBA\6.0\Common\CodeBackColors

Each of these keys contains a list of values (separated by space) for each entry inside Tools -> Options -> Editor Format. For example, the first value inside CodeBackColors is the background color and the first value inside CodeForeColors is the foreground color for normal text. The values are the internal id for the color, 0 means AUTO coloring, 11 shows cyan, 5 red etc.

To give it a try: Close Excel, change the first value of CodeBackColors to 5 and restart Excel. The background of the code editor will now be red.

The problem is that the VBA Editor does only support these internal values and the highest number it understands is 16. Any other value will not be accepted and it defaults back to AUTO.

I have tried several options of entering different values (e.g. 128255128, 16777215, #aaffee, 255 or "170,255,238") and none of them worked.

Therefore I think it is technically not possible to assign other colors.

share|improve this answer
1  
Thanks for the answer. IIRC, you can't withdraw a bounty, but if you literally cannot do this, then I shall award it to you for the most correct answer. I want to wait a bit more to see if any more answers are posted, but thanks for your response, +1. –  Breakthrough Jul 27 '11 at 10:29
1  
I have to admit, that sounds even better :) –  TeX HeX Jul 27 '11 at 10:42
    
"Total Visual CodeTools" (fmsinc.com/vb6/CodingTools.html) from FMS has a tool "VBE Color Scheme manager to easily see and set colors for your editor". If you download the user manual (a PDF) it shows screenshots that while making it easier to set colors is still limited to a 16 color palette. Would think if there was a direct way to use custom colors they would have included it in this tool. Looks like Tex Hex is correct. –  Brian Aug 1 '11 at 14:25

TeX HeX is spot on. However, it IS possible to change the 16 built-in colors with your own. It just requires a bit of hex editing. Here's a step-by-step guide. (Note: This is for VB6 SP6, file version 6.0.97.82).

  1. Backup your VB6.EXE file in your VB98 program folder. (Optional, but recommended).

  2. Fire up your favorite hex editor (shout out to HxD) and open VB6.EXE.

  3. Jump to address 0xE22F4. This is the start of the color table.

You should see four zeros. This represents the color black in RRGGBBAA format (alpha isn't supported so it's really just RRGGBB00 format). The next four bytes specify the next color and so on until you get to FFFFFF00 (white) ending at offset 0xE2333.

  1. Edit any of these four-byte values to your choosing. Just use the appropriate hex values in RGB format, followed by a zero byte. For example, RGB(64, 128, 192) would be 40 80 C0 00.

  2. Save your changes to the EXE and fire up VB6. You should see your new color(s) in the slots previously occupied by the built-in VB colors.

share|improve this answer
1  
Hmm, I searched with the tool everything on a system with office 2003 and it doesn't find any file named VB6.exe or a folder VB98. Is this answer only for Office 2007 like the OP has? However the version 6.0.97.82 is older than mine with Office 2003. –  nixda Feb 6 '13 at 19:49
1  
@nixda Nothing on my system either - I think Bond is referring to the VB6 application on his system, not the VBA integrated into Excel. I'm going to have a look through the Excel executable and some of the VBA DLLs, and see if I can find any colour tables. –  Breakthrough Feb 6 '13 at 21:05
    
Sorry, yes, I am referring to the VB6 IDE. I was searching for a solution to VB6 when I stumbled across this thread. Both VB6 and VBA use the CodeForeColors and CodeBackColors strings. VB6 stores these strings at a slightly different location (HKEY_CURRENT_USER\Software\Microsoft\VBA\Microsoft Visual Basic) but the method is similar to VBA, so I'm sure you could do something similar there. If I get a chance, I'll try to do the same for VBA. –  Bond Feb 6 '13 at 21:44
1  
I have Office 2010 on my PC so I have VBE7.DLL, not VBE6.DLL, but it should be the same process. The colors are the same. If you look at the colors in the order they're displayed, they should be: Black = 00 00 00 00 Navy = 00 00 80 00 Green = 00 80 00 00 Turqoise = 00 80 80 00 Magenta = 80 00 00 00 Violet = 80 00 80 00 Olive = 80 80 00 00 Lgt Grey = C0 C0 C0 00 Drk Grey = 80 80 80 00 ... I've added the hex color codes next to each. So just open VBE6.DLL in a hex editor and search for the following hex string: –  Bond Feb 12 '13 at 16:13
1  
00000000000080000080000000808000800000008000800080800000C0C0C00080808000 It may occur multiple times but I've found that the first color table is all that needs to be modified. See if that works for you. –  Bond Feb 12 '13 at 16:16

As many have noted, Bond's solution (hex editing the colors table in VB6.exe) will work but you will have to go in and reset your colors in the options dialog every time you start up VB6. I've created an AutoIt script that will do all of the work for you, just edit it as necessary where all of the calls to SetSyntaxColoring() are made:

Opt("WinTitleMatchMode", 2)
Opt("MouseClickDelay", 1)
Opt("MouseClickDownDelay", 1)
Opt("MouseClickDragDelay", 1)
Opt("SendKeyDelay", 1)
Opt("SendKeyDownDelay", 1)

Const $NORMALTEXT = 0
Const $SELECTIONTEXT = 1
Const $SYNTAXERRORTEXT = 2
Const $EXECUTIONPOINTTEXT = 3
Const $BREAKPOINTTEXT = 4
Const $COMMENTTEXT = 5
Const $KEYWORDTEXT = 6
Const $IDENTIFIERTEXT = 7
Const $BOOKMARKTEXT = 8
Const $CALLRETURNTEXT = 9

Const $AUTO = 0
Const $BLACK = 1
Const $DARKBLUE = 2
Const $DARKGREEN = 3
Const $DARKRED = 4
Const $DARKBABYBLUE = 5
Const $DARKPINK = 6
Const $DARKYELLOW = 7
Const $LIGHTGRAY = 8
Const $DARKGRAY = 9
Const $BLUE = 10
Const $GREEN = 11
Const $BABYBLUE = 12
Const $RED = 13
Const $PINK = 14
Const $YELLOW = 15
Const $WHITE = 16

If WinExists( "Microsoft Visual Basic" ) Then
   WinActivate("Microsoft Visual Basic") ; activates the visual basic window
   Send("!+to") ; opens the options menu
   Sleep(10)
   WinMove("Options", "", 0, 0) ; moves the options menu to the upper left corner of the screen
   MouseClick("primary", 100, 50, 1, 0) ; clicks the editor tab

   SetSyntaxColoring($NORMALTEXT, $WHITE, $BLACK)
   SetSyntaxColoring($SELECTIONTEXT, $AUTO, $AUTO)
   SetSyntaxColoring($SYNTAXERRORTEXT, $BLACK, $YELLOW)
   SetSyntaxColoring($EXECUTIONPOINTTEXT, $AUTO, $YELLOW)
   SetSyntaxColoring($BREAKPOINTTEXT, $WHITE, $DARKRED)
   SetSyntaxColoring($COMMENTTEXT, $DARKGREEN, $BLACK)
   SetSyntaxColoring($KEYWORDTEXT, $GREEN, $BLACK)
   SetSyntaxColoring($IDENTIFIERTEXT, $WHITE, $BLACK)
   SetSyntaxColoring($BOOKMARKTEXT, $WHITE, $BLACK)
   SetSyntaxColoring($CALLRETURNTEXT, $WHITE, $GREEN)

   MouseClick("primary", 210, 340, 1, 0) ; hit the ok button to apply the changes
EndIf

Func SetSyntaxColoring($syntax, $forecolor, $backcolor)
   SelectSyntax($syntax)
   SelectForecolor($forecolor)
   SelectBackcolor($backcolor)
EndFunc

Func SelectSyntax($syntax)
   ResetSyntaxList()
   RptSend("{DOWN}", $syntax)
EndFunc

Func SelectForecolor($color)
   ResetForecolorCbo()
   RptSend("{DOWN}", $color)
EndFunc

Func SelectBackcolor($color)
   ResetBackcolorCbo()
   RptSend("{DOWN}", $color)
EndFunc

Func ResetSyntaxList()
   MouseClick("primary", 50, 95, 1, 0)
   RptSend("{UP}", 9)
EndFunc

Func ResetForecolorCbo()
   MouseClick("primary", 50, 235, 1, 0)
   MouseClick("primary", 50, 235, 1, 0)
   RptSend("{UP}", 16)
EndFunc

Func ResetBackcolorCbo()
   MouseClick("primary", 125, 235, 1, 0)
   MouseClick("primary", 125, 235, 1, 0)
   RptSend("{UP}", 16)
EndFunc

Func RptSend($text, $rpt)
   For $i = 1 To $rpt
      Send($text)
   Next
EndFunc

I just keep it on my desktop and now whenever I have to open vb6 I just double click it and just like that syntax coloring is under my control.

Edit 1: Optimized the script a bit to make it run quicker. I am thinking about putting together a program that will edit VB6.EXE for you automatically to make color selection easier. I wonder if there's a way to ditch the AutoIt script by creating a plugin for VS?

Edit 2: Created a utility that allows you to edit the colors in the exe without having to use a hex editor: VbClassicColorEditor. That link goes to the public repository on bitbucket.

share|improve this answer
    
Thank you for the script and contribution! Any chance we could get an updated link on the VbClassicColorEditor? The one you posted has 404d... –  airstrike Nov 20 at 7:48

Taking the bait from dnissley's response (where he asks if someone could make an add-in), I've made an add-in for VB6. It's a little crude (and I'll explain why shortly), but it does do the job.

I created a new Add-In project in VB6 which gave me the default "frmAddin" form (which I don't use) and the "Connect" designer. I've added a Colour class myself which contains the following:

Option Explicit

Dim m_iForeColour As Integer
Dim m_iBackColour As Integer
Dim m_iIndicatorColour As Integer

Public Property Let ForeColour(ByVal iID As Integer)
    m_iForeColour = iID
End Property
Public Property Get ForeColour() As Integer
    ForeColour = m_iForeColour
End Property

Public Property Let BackColour(ByVal iID As Integer)
    m_iBackColour = iID
End Property
Public Property Get BackColour() As Integer
    BackColour = m_iBackColour
End Property

Public Property Let IndicatorColour(ByVal iID As Integer)
    m_iIndicatorColour = iID
End Property
Public Property Get IndicatorColour() As Integer
    IndicatorColour = m_iIndicatorColour
End Property

And then I've amended the code in the "Connect" Designer to be as follows:

Option Explicit

Public FormDisplayed          As Boolean
Public VBInstance             As VBIDE.VBE
Dim mcbMenuCommandBar         As Office.CommandBarControl
Dim mfrmAddIn                 As New frmAddIn
Public WithEvents MenuHandler As CommandBarEvents          'command bar event handler

Dim mcbToolbar As Office.CommandBarControl
Public WithEvents MenuHandler2 As CommandBarEvents

Dim codeColours() As Colour

'*****************************************************************************
' RunScript Sub
'-----------------------------------------------------------------------------
' DESCRIPTION:
'  Runs the code that sets the required colours for the code window in the
'  active IDE.
'  *** A PROJECT MUST BE LOADED BEFORE THIS WILL ACTUALLY WORK ***
'*****************************************************************************
Sub RunScript()
    ReadColoursFile

    ' Select Tools > Options
    SendKeys "%to", 5
    ' Go to tabs, select "Options"
    SendKeys "+{TAB}"
    SendKeys "{RIGHT}"

    ' Select listbox
    SendKeys "{TAB}"

    Dim colourSetting As Colour
    Dim iColour As Integer

    For iColour = 0 To 9
        SetColours iColour, codeColours(iColour)
    Next iColour

    SendKeys "~"
End Sub

'*****************************************************************************
' ReadColoursFile Sub
'-----------------------------------------------------------------------------
' DESCRIPTION:
'  Reads the colour file from disk and populates the codeColours array which
'  is used by the SetColour* methods for selecting the correct colours from
'  the options screen.
'*****************************************************************************
Sub ReadColoursFile()
    Dim colourLine As String
    Dim colourArray() As String
    Dim colourSetting As Colour
    Dim oFSO As FileSystemObject

    Set oFSO = New FileSystemObject

    If Not oFSO.FileExists(App.Path & "\VB6CodeColours.dat") Then
        MsgBox "VB6CodeColours.dat not found in " & App.Path, vbOKOnly, "VB6CodeColours Settings file not found!"
        Exit Sub
    End If

    Set oFSO = Nothing

    Open App.Path & "\VB6CodeColours.dat" For Input As #1
    ReDim codeColours(9) As Colour

    While Not EOF(1)
        Line Input #1, colourLine
        colourArray = Split(colourLine, ",")

        If IsNumeric(colourArray(0)) Then
            If codeColours(colourArray(0)) Is Nothing Then
                Set colourSetting = New Colour

                If IsNumeric(colourArray(1)) Then
                    colourSetting.ForeColour = CInt(colourArray(1))
                End If

                If IsNumeric(colourArray(2)) Then
                    colourSetting.BackColour = CInt(colourArray(2))
                End If

                If IsNumeric(colourArray(3)) Then
                    colourSetting.IndicatorColour = CInt(colourArray(3))
                End If

                Set codeColours(colourArray(0)) = colourSetting
            End If
        End If
    Wend

    Close #1

    Set colourSetting = Nothing
End Sub

'*****************************************************************************
' SetColours Sub
'-----------------------------------------------------------------------------
' DESCRIPTION:
'  Selects the colour item from the list and then iterates the colour selector
'  controls associated with that item and sets them according to the values
'  set in the VB6CodeColours.dat file.
'*****************************************************************************
Sub SetColours(ByVal iColour As Integer, ByRef colourSetting As Colour)
    Dim iKey As Integer

    SendKeys "{HOME}"

    For iKey = 1 To iColour
        SendKeys "{DOWN}"
    Next iKey

    SetColourSelector colourSetting.ForeColour
    SetColourSelector colourSetting.BackColour
    SetColourSelector colourSetting.IndicatorColour

    SendKeys "+{TAB}"
    SendKeys "+{TAB}"
    SendKeys "+{TAB}"
End Sub

'*****************************************************************************
' SetColourSelector Sub
'-----------------------------------------------------------------------------
' DESCRIPTION:
'  Sets the colour in the selector combo. Assumes the focus is on the
'  preceeding control before the code is run (first line tabs to the
'  assumed control).
'*****************************************************************************
Sub SetColourSelector(ByVal iColour As Integer)
    Dim iKey As Integer

    SendKeys "{TAB}"
    SendKeys "{HOME}"

    For iKey = 1 To iColour
        SendKeys "{DOWN}"
    Next iKey
End Sub

'*****************************************************************************
' AddinInstance_OnConnection Sub
'-----------------------------------------------------------------------------
' DESCRIPTION:
'  This method runs when the addin is loaded by the IDE
'*****************************************************************************
Private Sub AddinInstance_OnConnection(ByVal Application As Object, ByVal ConnectMode As AddInDesignerObjects.ext_ConnectMode, ByVal AddInInst As Object, custom() As Variant)
    On Error GoTo ErrorHandler

    'save the vb instance
    Set VBInstance = Application

    If ConnectMode  ext_cm_External Then
        Set mcbMenuCommandBar = AddToAddInCommandBar("VB6 Code Colouring")
        'sink the event
        Set Me.MenuHandler = VBInstance.Events.CommandBarEvents(mcbMenuCommandBar)

        Dim oStdToolbar As Office.CommandBar
        Dim oStdToolbarItem As Office.CommandBarControl

        Set oStdToolbar = VBInstance.CommandBars("Standard")
        Set oStdToolbarItem = oStdToolbar.Controls.Add(Type:=msoControlButton)
        oStdToolbarItem.Style = msoButtonCaption
        oStdToolbarItem.Caption = "Set IDE Colours"
        oStdToolbarItem.BeginGroup = True
        Set Me.MenuHandler2 = VBInstance.Events.CommandBarEvents(oStdToolbarItem)
    End If

    Exit Sub
ErrorHandler:
    MsgBox Err.Description
End Sub

'*****************************************************************************
' AddinInstance_OnDisconnection Sub
'-----------------------------------------------------------------------------
' DESCRIPTION:
'  This method runs when the addin is removed by the IDE and cleans up any
'  references etc.
'*****************************************************************************
Private Sub AddinInstance_OnDisconnection(ByVal RemoveMode As AddInDesignerObjects.ext_DisconnectMode, custom() As Variant)
    On Error Resume Next

    'delete the command bar entry
    mcbMenuCommandBar.Delete

    'shut down the Add-In
    If FormDisplayed Then
        SaveSetting App.Title, "Settings", "DisplayOnConnect", "1"
        FormDisplayed = False
    Else
        SaveSetting App.Title, "Settings", "DisplayOnConnect", "0"
    End If

    Unload mfrmAddIn
    Set mfrmAddIn = Nothing

    Set MenuHandler = Nothing
    Set MenuHandler2 = Nothing
End Sub

'*****************************************************************************
' MenuHandler_Click Sub
'-----------------------------------------------------------------------------
' DESCRIPTION:
'  This method performs the tasks needed when the menu item is clicked.
'*****************************************************************************
Private Sub MenuHandler_Click(ByVal CommandBarControl As Object, handled As Boolean, CancelDefault As Boolean)
    RunScript
End Sub

'*****************************************************************************
' MenuHandler2_Click Sub
'-----------------------------------------------------------------------------
' DESCRIPTION:
'  This method performs the tasks needed when the toolbar button is clicked.
'*****************************************************************************
Private Sub MenuHandler2_Click(ByVal CommandBarControl As Object, handled As Boolean, CancelDefault As Boolean)
    RunScript
End Sub

'*****************************************************************************
' AddToAddInCommandBar Sub
'-----------------------------------------------------------------------------
' DESCRIPTION:
'  Adds the specified item to the menu list.
'*****************************************************************************
Function AddToAddInCommandBar(sCaption As String) As Office.CommandBarControl
    Dim cbMenuCommandBar As Office.CommandBarControl  'command bar object
    Dim cbMenu As Object

    On Error Resume Next

    'see if we can find the Add-Ins menu
    Set cbMenu = VBInstance.CommandBars("Add-Ins")
    If cbMenu Is Nothing Then
        'not available so we fail
        Exit Function
    End If

    On Error GoTo ErrorHandler

    'add it to the command bar
    Set cbMenuCommandBar = cbMenu.Controls.Add(1)
    'set the caption
    cbMenuCommandBar.Caption = sCaption

    Set AddToAddInCommandBar = cbMenuCommandBar

    Exit Function
ErrorHandler:
    ' Exit gracefully
End Function

This code allows the application to read the colours I want from a file that resides in the same directory as the .dll (called VB6CodeColours.dat). This file contains the following (and it will vary based on which colours you replace in the VB6.EXE so a straight copy & paste probably won't work.

0,14,12,0
1,0,0,0
2,16,13,0
3,0,15,15
4,16,5,5
5,7,12,0
6,11,12,0
7,8,12,0
8,16,10,10
9,16,3,3

Looks gibberish, but I'll explain. It has the format "Code Colour","Foreground","Background",Indicator" so the top row will set the "Normal Text" to the 14th item in the combo for Foreground, the 12th for Background and the 1st for the Indicator.

Why I said it's a pretty crude solution: * It uses SendKeys. No further explanation needed there I'm sure :) * The user has to click the menu/toolbar option in order for it to take effect. * The code isn't best structured (in my opinion) but was based on the amount of time I could dedicate to it at the time. I aim to improve it in the future, but it works fine for me in the current state (so I'll probably leave it!)

Perhaps with a basis, someone can expand on it further.

share|improve this answer

Bond's solution (editing the color table in VB6.exe) works perfectly for modifying the color table in the VB6 IDE.

However, I found that when a modified color is selected and VB6 is shut down, VB6 is not able to properly save the modified color to the registry.

Normally, VB6 will write an index into the 16-value color table for each text item that can have its color modified.

The color indices are written to the registry here:

HKEY_CURRENT_USER\Software\Microsoft\VBA\Microsoft Visual Basic\CodeForeColors HKEY_CURRENT_USER\Software\Microsoft\VBA\Microsoft Visual Basic\CodeBackColors

For example, the CodeForeColors value will look something like this: 6 14 5 0 1 3 13 4 15 0 0 0 0 0 0 0

Values from 1 to 16 represent a color in the color table and 0 means 'Auto'.

BUT, when a modified color is selected, VB6 will write a number outside of the index range to the registry and the CodeForeColors value will look something like this:

5245006 14 5 0 1 3 13 4 15 0 0 0 0 0 0 0

The next time VB6 is started it will not be able to set the correct color for the item that had been set to the modified color.

I'm still trying to figure out a solution but wanted to post what I've found so far.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.