The VB6 IDE has an annoying quirk when it comes to the case of Enum members. Unlike with other identifiers, the IDE doesn't enforce the case of an Enum member as it was declared in the Enum block. That occasionally causes an Enum member that was manually written to lose its original case, unless a coder typed it carefully enough. The prevalent workaround for this bug is to redeclare the identifiers inside an #If...Then...#End If directive:
Code:
Private Enum Constants
Const1
Const2
Const3
End Enum
#If False Then
Dim Const1, Const2, Const3
#End If
However, if a project contains a lot of Enums and/or a particular Enum has a lot of members, redeclaring the members in each of them can get quite tedious fast. Nobody seems to have submitted yet a routine to automate this process here in the VB6 CodeBank, so I'm sharing this code snippet I've had for some time now.
Code:
Attribute VB_Name = "modLockEnumCase"
Option Explicit
'modLockEnumCase.bas usage:
'1. Add to project.
'2. Select entire Enum block.
'3. Copy to Clipboard.
'4. Run LockEnumCase() from the Immediate Window. Optionally *suggest* length of each line.
'5. Paste after the Enum block.
'6. Remove from project when no longer needed.
Public Sub LockEnumCase(Optional ByVal LineLen As Integer = 80) 'Adjust length of output lines as desired
Attribute LockEnumCase.VB_Description = "Enforces the case of Enumerations via Conditional Compiler Directives."
Dim sBlock As String, sLine As String, sText As String, oMatch As Object 'Match
'See if there's anything to process; quit if no text was copied
If Clipboard.GetFormat(vbCFText) Then sText = Clipboard.GetText Else Exit Sub
'Prepend the conditional compiler directive that is set to False
sBlock = "#If False Then" & vbNewLine
'Dimension variables that reuses the Enum members' names
sLine = "Dim "
With CreateObject("VBScript.RegExp") 'New RegExp
.Global = True
.MultiLine = True
'Strip all comments
.Pattern = " +'.*$"
sText = .Replace(sText, vbNullString)
'Exclude Enum statements
.Pattern = "(\b(Private|Public)? Enum [A-Za-z]\w*\b)|(\bEnd Enum\b)"
sText = .Replace(sText, vbNullString)
'Split multiple expressions in a single line into their own lines
If InStrB(sText, ":") Then sText = Replace(sText, ":", vbNewLine)
'This should match most Enum member names, including those enclosed with []
.Pattern = "^ *([A-Za-z]\w*|\[.+\]) *(?:=|$)"
For Each oMatch In .Execute(sText)
sLine = sLine & (oMatch.SubMatches(0&) & ", ")
'Check if the string being built is exceeding
'the *suggested* limit of each output line
If Len(sLine) >= LineLen Then
'If so, commit this line to the output string
sBlock = sBlock & (sLine & "_")
'Begin anew at the next line
sLine = vbNewLine
End If
Next
End With
'Finish the conditional compiler directive block, removing empty lines as needed
sBlock = sBlock & (IIf(sLine <> vbNewLine, sLine, vbNullString) _
& vbNewLine & "#End If" & vbNewLine)
'Overwrite the last comma with a space
Mid$(sBlock, InStrRev(sBlock, ",")) = " "
'Try to erase the last underscore on the last line, if present
On Error Resume Next
Mid$(sBlock, InStrRev(sBlock, "_" & vbNewLine & "#")) = " "
On Error GoTo 0
'Copy back to the Clipboard
Clipboard.Clear
Clipboard.SetText sBlock
End Sub
EDIT
The code above is now available as an IDE add-in as well. Just compile the ActiveX DLL project in the attached LockEnumCase.zip archive below to a permanent location (e.g., the VB6 IDE's directory). Then load and unload the add-in as needed via the Add-In Manager dialog box. Usage is as simple as selecting the entire Enum block, right-clicking and then choosing the "Lock Enum Case" context menu item. Holding down either Shift key while clicking the menu item will bring up an InputBox that prompts for the suggested output line length.
Last edited by Bonnie West; May 28th, 2015 at 03:13 AM.
Reason: Attached add-in version
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Re: [VB6] modLockEnumCase.bas - Enforce Case of Enums
Hey, that's always been an annoyance of mine for years.
I love your idea of the "#If False".
I've never had much need for the compiler directives, but this is actually one I'll use. Nice idea.
Re: [VB6] modLockEnumCase.bas - Enforce Case of Enums
If there is a lot of Enums in the project, I will definitely use this routine. For one or two enums, the "#IF FALSE" solution is charming.
Is it possible to use it as a plugin or something? As I read from the usage here, it still involves adding the module to the project, copying text, running the routine, pasting text, and removing module. For lazy people such as me, perhaps a 'hotkey' that responds to this 'routine' will be ideal ....
Re: [VB6] modLockEnumCase.bas - Enforce Case of Enums
Originally Posted by bPrice
Is it possible to use it as a plugin or something? As I read from the usage here, it still involves adding the module to the project, copying text, running the routine, pasting text, and removing module. For lazy people such as me, perhaps a 'hotkey' that responds to this 'routine' will be ideal ....
You can, of course, compile that code as a Standard EXE (just call that subroutine from Sub Main). You could then create a shortcut to the EXE and assign it a hotkey of your choice. You could optionally pass the LineLen argument as a command line parameter. Another possible option is to compile that code as an IDE add-in and expose that command via a toolbar button, context menu, shortcut key or all of them.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Re: [VB6] modLockEnumCase.bas - Enforce Case of Enums
Originally Posted by Bonnie West
Another possible option is to compile that code as an IDE add-in and expose that command via a toolbar button, context menu, shortcut key or all of them.
How about some step-by-step tutorial
Never made a IDE add-in before
Re: [VB6] modLockEnumCase.bas - Enforce Case of Enums
Originally Posted by bPrice
How about some step-by-step tutorial
Never made a IDE add-in before
Sorry, I haven't played yet with IDE add-ins either. The VB6 doc has a tutorial on building one though, if you're really interested.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Re: [VB6] modLockEnumCase.bas - Enforce Case of Enums
I just came across the add-in version today, extremely helpful. I just wanted to note, that if you don't like the case lock code blocks in your module headers, you can put the case lock code at the end of the module, as-is, and it will work and not generate any errors (at first i thought i might need to add Sub.. but turns out that's not needed),
To do this, in m_CommandBarControl_Click, simply replace: