dcsimg
Results 1 to 9 of 9

Thread: [VB6] modLockEnumCase.bas - Enforce Case of Enums

  1. #1

    Thread Starter
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,057

    Post [VB6] modLockEnumCase.bas - Enforce Case of Enums

    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.
    Attached Files Attached Files
    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
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  2. #2
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    2,409

    Re: [VB6] modLockEnumCase.bas - Enforce Case of Enums

    Very helpful, thanks.

  3. #3
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    6,004

    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.

  4. #4
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    341

    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 ....

    Bonnie

  5. #5

    Thread Starter
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,057

    Re: [VB6] modLockEnumCase.bas - Enforce Case of Enums

    Quote Originally Posted by bPrice View Post
    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
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  6. #6
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    341

    Re: [VB6] modLockEnumCase.bas - Enforce Case of Enums

    Quote Originally Posted by Bonnie West View Post
    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

  7. #7

    Thread Starter
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,057

    Re: [VB6] modLockEnumCase.bas - Enforce Case of Enums

    Quote Originally Posted by bPrice View Post
    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
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  8. #8
    Hyperactive Member
    Join Date
    Sep 2014
    Posts
    341

    Re: [VB6] modLockEnumCase.bas - Enforce Case of Enums

    Bonnie:

    Haven't expected that you would further create an add-in for us. You really surprised me and, thanks for the efforts!!

    I've downloaded the project and will try it today.

  9. #9
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    2,409

    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:
    Code:
    .InsertLines EndLine, LockEnumCase(sText)
    with
    Code:
    .InsertLines .CountOfLines + 1, LockEnumCase(sText)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width