home *** CD-ROM | disk | FTP | other *** search
/ BUG 4 / BUGCD1997_05.BIN / aplic / visualj / vjtrial.exe / RCDATA / CABINET / sample.dsm < prev    next >
Text File  |  1997-01-10  |  25KB  |  768 lines

  1. '------------------------------------------------------------------------------
  2. 'FILE DESCRIPTION: SAMPLE.DSM is a collection of sample editor macros.
  3. '------------------------------------------------------------------------------
  4.  
  5. 'This routine has many uses if you are trying to determine the type of source 
  6. '    file.
  7. 'Return value:  0 Unknown file type
  8. '               1 C-related file, this includes .c, .cpp, .cxx, .h, .hpp, .hxx
  9. '               2 Java-related file, this includes .jav, .java
  10. '               3 ODL-style file, .odl, .idl
  11. '               4 Resource file, .rc, .rc2
  12. '               5 HTML-style file, this includes .html, and .htm
  13. '               6 VBS-style file, .dsm
  14. '               7 Def-style file, .def
  15. 'USE: Pass this function the document that you wish to get information for.
  16. Function FileType (ByVal doc)
  17.     ext = doc.Name
  18.     FileType = 0
  19.     pos = Instr(ext, ".")
  20.     if pos > 0 then
  21.         Do While pos <> 1
  22.             ext = Mid(ext, pos, Len(ext) - pos + 1)
  23.             pos = Instr(ext, ".")
  24.         Loop
  25.         ext = LCase(ext)
  26.     end if
  27.     If ext = ".rc" Or ext = ".rc2" Then
  28.         FileType = 4
  29.     ElseIf doc.Language = dsCPP Then
  30.         FileType = 1
  31.     ElseIf doc.Language = dsJava Then
  32.         FileType = 2
  33.     ElseIf doc.Language = dsIDL Then
  34.         FileType = 3
  35.     ElseIf doc.Language = dsHTML_IE3 Or doc.Language = dsHTML_RFC1866 Then
  36.         FileType = 5  
  37.     ElseIf doc.Language = dsVBSMacro Then ' 
  38.         FileType = 6  
  39.     ElseIf ext = ".def" Then
  40.         FileType = 7
  41.     Else 
  42.         FileType = 0
  43.     End If 
  44. End Function
  45.  
  46.  
  47. 'This routine has many uses if you are trying to determine if an identifier
  48. '  is a valid C identifier.
  49. '  These identifiers do not include qualification syntax, for example:
  50. '  foo.bar is not valid
  51. '  foo i valid
  52. 'Parameters:    String to test for a valid C identifier.
  53. 'Return value:  True: passed parameter is a valid C identifier.
  54. '               False: passed parameter is not a valid C identifier.
  55. Function ValidId(Id)
  56.     ValidId = True
  57.  
  58.     'Don't permit an empty string
  59.     ' (how can you identify nothing with something?)
  60.     if Id = "" then 
  61.       ValidID = False
  62.       Exit Function
  63.     End If
  64.  
  65.     For i = 1 To Len(Id)
  66.       if Mid(Id, i, 1) < "a" Or Mid(Id, i, 1) > "z" Then
  67.         if Mid(Id, i, 1) < "A" Or Mid(Id, i, 1) > "Z" Then
  68.             if Mid(Id, i, 1) < "0" Or Mid(Id, i, 1) > "9" Then
  69.                 if Mid(Id, i, 1) <> "_" Then
  70.                     ValidId = False
  71.                 End if
  72.             End If
  73.         End If    
  74.       End If
  75.     Next
  76.     If IsNumeric(Left(Id, 1)) = True Then
  77.         ValidId = False
  78.     End If
  79. End Function
  80.  
  81.  
  82. Dim ParamArr ()  ' Dynamic array to store function arguments.
  83.  
  84. Sub AddFunctionDescription ( )
  85.  
  86. 'DESCRIPTION: Creates a comment block for the currently selected C/C++ function prototype
  87.  
  88.     'Throughout this file, ActiveDocument.Selection is used in place 
  89.     'of ActiveDocument.Selection.Text.  The two are equivalent, and can 
  90.     'be used interchangeably. The reason for the equivalence is that
  91.     'Text is regarded as the default property to use. All uses of
  92.     'ActiveDocument.Selection without any other property default to the Text
  93.     'property.
  94.     if ActiveDocument.Language = dsCPP Then
  95.         Header = StripTabs(Trim(ActiveDocument.Selection))
  96.  
  97.         'Get the function return type.
  98.         if Header <> "" then
  99.             Reti = InStr(Header, " ")
  100.             Loc = InStr(Header, "(")
  101.             if Reti < Loc Then
  102.               RetTp = Left(Header, Reti)
  103.               Header = Right(Header, Len(Header) - Reti)
  104.             End If
  105.  
  106.             'Get the function name.
  107.             Loc = InStr(Header, "(") - 1
  108.             Loc2 = InStr(Header, ")")
  109.             if Loc > 0 And Loc2 > 0 then 'make sure there is a '(' and a ')'
  110.                 fcName = Left(Header, Loc)
  111.                 Header = Right(Header, Len(Header) - Len(fcName))
  112.  
  113.                 'Do we have storage type on the return type?
  114.                 Trim (fcName)
  115.                 If InStr(fcName," ") <> 0 Then
  116.                     retTp = retTp + Left(fcName,InStr (fcName," "))
  117.                     fcName = Right(fcName, Len(fcName) - InStr(fcName," "))
  118.                 End If
  119.  
  120.                 'Get the function parameters.
  121.                 iPrm = 0
  122.                 iPrmA = 0
  123.                 prms = Header 
  124.  
  125.                 'Count the number of parameters. 
  126.                 Do While InStr(prms, ",") <> 0
  127.                     iPrm = iPrm + 1
  128.                     prms = Right(prms, Len(prms) - InStr(prms, ",")) 
  129.                 Loop 
  130.                 
  131.                 'Store the parameter list in the array.
  132.                 If iPrm > 0 Then  ' If multiple params.
  133.                     iPrm = iPrm + 1
  134.                     iPrmA = iPrm
  135.                     Redim ParamArr(iPrm)
  136.                     Do While InStr(header, ",") <> 0
  137.                         ParamArr(iPrm) = Left(Header, InStr (Header, ",") - 1)
  138.                         'Remove brace from first parameter.
  139.                         If InStr(ParamArr(iPrm), " (") <> 0 Then
  140.                             ParamArr(iPrm) = Right(ParamArr(iPrm), _
  141.                                     Len(ParamArr(iPrm))-InStr(ParamArr(iPrm)," ("))
  142.                             Trim(ParamArr(iPrm))
  143.                         End If
  144.                         Header = Right(Header, Len(Header) - InStr(Header,","))
  145.                         iPrm = iPrm - 1 
  146.                         Loop 
  147.                     ParamArr(iPrm) = Header 
  148.                     'Remove trailing brace from last parameter.
  149.                     If InStr(ParamArr(iPrm), ")") <> 0 Then
  150.                         ParamArr(iPrm) = Left(ParamArr(iPrm), _
  151.                                 InStr(ParamArr(iPrm), ")") - 1)
  152.                         Trim(ParamArr(iPrm))
  153.                     End If
  154.                 Else 'Possibly one param.
  155.                     Redim ParamArr(1)
  156.                     Header = Right(Header, Len(Header) - 1) ' Strip the first brace.
  157.                     Trim(Header)
  158.                     ParamArr(1) = StripTabs(Header)
  159.                     If InStr(ParamArr(1), ")") <> 1 Then
  160.                         ParamArr(1) = Left(ParamArr(1), InStr(ParamArr(1), ")") - 1)
  161.                         Trim(ParamArr(1))
  162.                         iPrmA = 1
  163.                     End If
  164.                 End If
  165.  
  166.                 'Position the cursor one line above the selected text.
  167.                 ActiveDocument.Selection.LineUp
  168.                 ActiveDocument.Selection.LineDown
  169.                 ActiveDocument.Selection.StartOfLine
  170.                 ActiveDocument.Selection = vbLf
  171.  
  172.                 Descr = "// Function name    : " + fcName + _
  173.                         vbLf + "// Description        : " + _ 
  174.                         vbLf +  "// Return type        : " + RetTp + vbLf
  175.                 
  176.                 'Print the parameter list. 
  177.                 Last = iPrmA
  178.                 Do While iPrmA <> 0
  179.                     'Remove a line feed from any of the arguments.
  180.                     If InStr(ParamArr(iPrmA), vbLf) <> 0 Then
  181.                         ParamArr(iPrmA) = Right(ParamArr(iPrmA), _
  182.                                 (Len(ParamArr(iPrmA)) - _
  183.                                 InStr(ParamArr(iPrmA), vbLf)))
  184.                         Trim(ParamArr(iPrmA))
  185.                     End If
  186.                     ParamArr(iPrmA) = StripTabs(ParamArr(iPrmA))
  187.                     'If there are 2+ parameters, the first parameter will 
  188.                     'have a '(' prepended to it, remove it here:
  189.                     if iPrmA = Last AND Last <> 1 then
  190.                       ParamArr(iPrmA) = Right(ParamArr(iPrmA), _
  191.                             Len(ParamArr(iPrmA)) - 1)
  192.                     End If
  193.                     Descr = Descr + "// Argument         : " + _
  194.                             ParamArr(iPrmA) + vbLf
  195.                     iPrmA = iPrmA - 1
  196.                 Loop
  197.                 ActiveDocument.Selection = Descr
  198.             Else
  199.                 MsgBox("It is possible that the function you are trying to"+_
  200.                         " work with has a syntax error.")
  201.             End if
  202.         End If
  203.     Else
  204.         MsgBox("You need to have an active C/C++ document open"+ _
  205.                 vbLF+"with the function prototype selected.")
  206.     End If
  207. End Sub
  208.  
  209. 'Strips the leading tab spaces. 
  210. Function StripTabs (ByVal MyStr)
  211.     Do While InStr(MyStr, vbTab) <> 0
  212.         MyStr = Right(MyStr, Len(MyStr) - InStr(MyStr, vbTab)) 
  213.     Loop 
  214.     StripTabs = Trim(MyStr)
  215. End Function
  216.  
  217. Sub ToggleCommentStyle ( )
  218. 'DESCRIPTION: Toggles between comment styles /* and //.
  219.  
  220.     TmpBlock = ""
  221.     CmtBlock = ActiveDocument.Selection
  222.     TypeOfFile = FileType(ActiveDocument)
  223.     If TypeOfFile > 0 And TypeOfFile < 5 Then   'C/C++ style comment.
  224.         'Get the first two characters of the comment block.
  225.         Trim(CmtBlock)
  226.         If Instr(CmtBlock,"//") <> 0 Then 
  227.             Do While Instr (CmtBlock,"//") <> 0
  228.                 TmpBlock = TmpBlock + Left (CmtBlock, Instr (CmtBlock,"//") - 1)
  229.                 CmtBlock = Right(CmtBlock, (Len(CmtBlock) - (Instr(CmtBlock,_
  230.                         "//") + 1)))
  231.             Loop
  232.             CmtBlock = "/*" + TmpBlock + CmtBlock + "*/"
  233.         ElseIf Instr(CmtBlock, "/*") <> 0 Then 
  234.             CmtBlock = Right(CmtBlock, Len(CmtBlock) - (Instr(CmtBlock,"/*")_
  235.                     + 1))
  236.             Do While Instr (CmtBlock, vbLf) <> 0
  237.                 TmpBlock = TmpBlock + Left (CmtBlock, Instr(CmtBlock, vbLf))_
  238.                         + "//"
  239.                 CmtBlock = Right(CmtBlock, (Len(CmtBlock) - (Instr(CmtBlock,_
  240.                         vbLf))))
  241.             Loop
  242.             CmtBlock = "//" + TmpBlock + Trim(CmtBlock)
  243.             CmtBlock = Left(CmtBlock, Instr(CmtBlock,"*/")-1)
  244.         End If
  245.         ActiveDocument.Selection.Delete
  246.         ActiveDocument.Selection = CmtBlock
  247.     Else
  248.         MsgBox "This macro does not work on this type of file."
  249.     End If
  250.     
  251. End Sub
  252.  
  253.  
  254.  
  255. Sub AddRevisionMarks ( )
  256. 'DESCRIPTION: Adds comments to a file that describe the changes made.
  257.  
  258.     'This routine adds a new comment block to the top of a file, where the 
  259.     ' programmer can place revision marks to describe the changes made to the file.
  260.     'The rules this routine uses are as follows:
  261.     ' 1) Start at the top of the file.
  262.     ' 2) Scan through each line; if the current line starts with a comment,
  263.     '      advance to the next line..
  264.     ' 3) If we are currently in a group comment block, keep advancing until
  265.     '     the end of the block is found.
  266.     ' 4) If we are in a line item comment (e.g.: //, ', rem, etc), keep advancing
  267.     '     until a line that does not start with a comment is found.
  268.     '     By 'start with a comment', it is meant a line, where after
  269.     '     stripping off spaces and tabs from the beginning, the first set of
  270.     '     characters is not a comment delimiter.
  271.     ' 5) Insert a blank line; this allows the next invocation of this macro
  272.     '     to place the newer revision mark before all others.
  273.     ' 6) Insert the revision block.
  274.  
  275.     'Change this to the programmer's name for a default.
  276.     DefaultUserName = "..."
  277.  
  278.     'Because the user may not have closed a comment (e.g. a /* without a */),
  279.     ' try to protect ourselves from an infinite loop...
  280.     BreakAfter = 10 'Max number of lines to look at scan before aborting
  281.     CurrentCount = 1
  282.  
  283.     BeginComment = "" 'The token for the specified language for the beginning
  284.                         ' of a comment.
  285.     EndComment = ""   'Same, except for the end of a comment.
  286.     EveryLine = ""    'Does the comment mark need to be placed on every line
  287.                         ' (VBS, DEF types)?
  288.  
  289.     'First, make sure the active document is a text window
  290.     ' (Not really necessary, but good practice).
  291.     If ActiveDocument.Type = "Text" Then
  292.         TypeOfFile = FileType(ActiveDocument)
  293.     
  294.         'Set ourselves at the very top of the document.
  295.         'This also clears any selection made.
  296.         ActiveDocument.Selection.StartOfDocument
  297.         ActiveDocument.Selection.SelectLine
  298.         CurrText = ActiveDocument.Selection
  299.         CurrText = LTrim(CurrText)
  300.     
  301.         'All of the following do relatively the same thing, 
  302.         ' except they look for different comment types.
  303.         If TypeOfFile > 0 And TypeOfFile < 5 Then       'C/C++ family of code
  304.             ContSearch = True
  305.             BeginComment = "/*"
  306.             EndComment = "*/"
  307.             EveryLine = " "
  308.  
  309.             'In C/C++ style code, we need to look for a //;
  310.             '  if not found, then look for a /*.
  311.             Do
  312.                 ActiveDocument.Selection = CurrText
  313.                 If InStr(CurrText, "//") = 1 Then   'is a "//" available?
  314.                     ActiveDocument.Selection.SelectLine
  315.                     CurrText = LTrim(ActiveDocument.Selection) 'Remove whitespace.
  316.                     ContSearch = False   ' Looking at // style comments, 
  317.                                             'don't look for a /* style.
  318.                 Else
  319.                     Exit Do
  320.                 End If
  321.             Loop
  322.  
  323.             If ContSearch = False Then
  324.                 ActiveDocument.Selection.LineUp
  325.             End If
  326.  
  327.             'When the method ActiveDocument.Selection.SelectLine is called,
  328.             '  it is the same as when you click the mouse in the margin; it
  329.             '  selects the whole line, including the carriage return.
  330.             '  Because of this, the cursor comes down to the next line, which
  331.             '  can really confuse this algorithm. So in a number of places, 
  332.             '  you will see a grouping of LineUp/LineDown commands. By executing
  333.             '  these commands, the cursor is moved down, which clears the current
  334.             '  selection (including getting us past the carriage return),
  335.             '  then moves us back up, thus putting us on the same line. This
  336.             '  removesthe danger of skipping a line (which is what will
  337.             '  happen without the LineUp/LineDown combination).
  338.             If ContSearch = True Then
  339.                 ActiveDocument.Selection.StartOfDocument
  340.                 'Prime the loop with the first line.
  341.                 ActiveDocument.Selection.SelectLine
  342.                 CurrText = ActiveDocument.Selection           
  343.                 ActiveDocument.Selection.LineDown
  344.                 ActiveDocument.Selection.LineUp
  345.                 'Remove leading whitespace.
  346.                 CurrText = LTrim(CurrText)      
  347.                 'Does line start with a /*?              
  348.                 If InStr(CurrText,"/*") = 1 Then
  349.                     while (InStr(CurrText, "*/") = 0) And _
  350.                           (BreakAfter > CurrentCount)
  351.                         ActiveDocument.Selection.SelectLine
  352.                         CurrText = ActiveDocument.Selection
  353.                         CurrText = LTrim(CurrText)                              
  354.                         ActiveDocument.Selection.LineDown
  355.                         ActiveDocument.Selection.LineUp    
  356.                         CurrentCount = CurrentCount + 1
  357.                     wend
  358.                     If (BreakAfter > CurrentCount) Then
  359.                         'Exit the loop because the search has gone on for an 
  360.                         '  unreasonable number of lines.
  361.                         MsgBox "Could not find a closing comment mark"
  362.                     End If
  363.                 End If
  364.             End If
  365.  
  366.         'The code for these is really just a copy of that from the 
  367.         '  C/C++ section...
  368.           
  369.         ElseIf TypeOfFile = 5 Then                      'HTML code
  370.             BeginComment = "<!--"
  371.             EndComment = "-->"
  372.             EveryLine = "    "
  373.             If InStr(CurrText,"<!--") = 1 Then
  374.                 If InStr(CurrText,"-->") <> 0 Then
  375.                     ActiveDocument.Selection.LineDown
  376.                 Else
  377.                     Do
  378.                         ActiveDocument.Selection.SelectLine
  379.                         CurrText = ActiveDocument.Selection
  380.                         CurrText = Left(CurrText, Len(CurrText) - 2)
  381.                         ActiveDocument.Selection = CurrText + vbLf
  382.                         If InStr(CurrText, "-->") Then
  383.                             Exit Do
  384.                         End If
  385.                     Loop
  386.                 End If
  387.             End If 
  388.  
  389.         ElseIf TypeOfFile = 6 Then                      'VBS code
  390.             BeginComment = "'"
  391.             EndComment = "'"
  392.             EveryLine = "'"
  393.             Do
  394.                 ActiveDocument.Selection = CurrText
  395.                 If InStr(CurrText, "'") = 1 Or _
  396.                    InStr(LCase(CurrText), "Rem") = 1 Then
  397.                     ActiveDocument.Selection.SelectLine
  398.                     CurrText = LTrim(ActiveDocument.Selection)
  399.                     ContSearch = False
  400.                 Else
  401.                     Exit Do
  402.                 End If
  403.             Loop
  404.             If ContSearch = False Then
  405.                 ActiveDocument.Selection.LineUp
  406.             End If
  407.  
  408.         ElseIf TypeOfFile = 7 Then                      'DEF code
  409.             BeginComment = ";"
  410.             EndComment = ""
  411.             EveryLine = ";"
  412.             Do
  413.                 ActiveDocument.Selection = CurrText
  414.                 If InStr(CurrText, ";") = 1 Then
  415.                     ActiveDocument.Selection.SelectLine
  416.                     CurrText = LTrim(ActiveDocument.Selection)
  417.                     ContSearch = False
  418.                 Else
  419.                     Exit Do
  420.                 End If
  421.             Loop
  422.             If ContSearch = False Then
  423.                 ActiveDocument.Selection.LineUp
  424.             End If      
  425.         End If
  426.  
  427.         If TypeOfFile = 0 Then                          'Unknown type of code.
  428.             MsgBox("Unable to add revision marks. Unrecgonized file type")
  429.         ElseIf (CurrentCount < BreakAfter) Then
  430.             'The BeginComment, EveryLine, and EndComment were set as
  431.             ' avoid duplicating this section...
  432.             ' just insert the generalized block, with the comment markers.
  433.             ActiveDocument.Selection.StartOfLine(True)
  434.             'This is added with one assignment statement, which enables the user
  435.             ' to hit undo once, and remove the entire change.
  436.             ActiveDocument.Selection = vbLf + _
  437.             BeginComment + "***********************************" + vbLf + _
  438.             EveryLine    + " REVISION LOG ENTRY" + vbLf + _
  439.             EveryLine    + " Revision By: " + DefaultUserName + vbLf + _
  440.             EveryLine    + " Revised on " + CStr(Now) + vbLf + _
  441.             EveryLine    + " Comments: ..." + vbLf + _
  442.             EveryLine    + "***********************************" + _
  443.             EndComment + vbLf + vbLf
  444.         End If
  445.     End If
  446. End Sub
  447.  
  448.  
  449. Sub CloseExceptActive () 
  450. 'DESCRIPTION: Closes all editor windows except the current one.
  451.  
  452.     'Windows.Item(1) is always the currently active window. So to close all
  453.     ' the windows except the active one, keep looping until there is no 
  454.     ' longer a Windows.Item(2).
  455.     do while Windows.Count > 1
  456.         Windows.Item(2).Close(dsSaveChangesPrompt)
  457.     Loop
  458. End Sub
  459.  
  460.  
  461. Sub CommentOut ()
  462. 'DESCRIPTION: Comments out a selected block of text.
  463.     Dim win
  464.     set win = ActiveWindow
  465.     if win.type <> "Text" Then
  466.       MsgBox "This macro can only be run when a text editor window is active."
  467.     else
  468.         TypeOfFile = FileType(ActiveDocument)  
  469.         If TypeOfFile > 0 And TypeOfFile < 5 Then    'C & Java use the same 
  470.                                                         'style of comments.
  471.             ActiveDocument.Selection = "/*" + ActiveDocument.Selection + "*/"
  472.         ElseIf TypeOfFile = 5 Then
  473.             ActiveDocument.Selection = "<!-- " + ActiveDocument.Selection + " -->"
  474.         ElseIf TypeOfFile = 6 Or TypeOfFile = 7 Then
  475.             'There is no group comment like there is in the other file types, 
  476.             'so we need to iterate through each line, and prepend a ' to the line.
  477.             'Also, because VBS/DEF does not have a 'end the comment at this 
  478.             'particular column' delimiter, entire lines of code must be 
  479.             'commented out, not sections.
  480.             If TypeOfFile = 6 Then 
  481.                 CommentType = " ' "
  482.             Else
  483.                 CommentType = " ; "
  484.             End If
  485.      
  486.             StartLine = ActiveDocument.Selection.TopLine
  487.             EndLine = ActiveDocument.Selection.BottomLine
  488.             If EndLine < StartLine Then
  489.                 Temp = StartLine
  490.                 StartLine = EndLine
  491.                 EndLine = Temp
  492.             End If
  493.  
  494.             If EndLine = StartLine Then
  495.                 ActiveDocument.Selection = CommentType + ActiveDocument.Selection
  496.  
  497.             Else 
  498.                 For i = StartLine To EndLine
  499.                     ActiveDocument.Selection.GoToLine i
  500.                     ActiveDocument.Selection.SelectLine
  501.                     ActiveDocument.Selection = CommentType + _
  502.                         ActiveDocument.Selection
  503.                 Next
  504.             End If
  505.         Else
  506.             MsgBox("Unable to comment out the highlighted text" + vbLf + _
  507.                     "because the file type was unrecognized." + vbLf + _
  508.                     "If the file has not yet been saved, " + vbLf + _
  509.                     "please save it and try again.")
  510.         End If
  511.     End If
  512. End Sub
  513.  
  514.  
  515. Sub MultiplePaste () 
  516. 'DESCRIPTION: Performs a paste of what is on the clipboard a multiple number of times.
  517.  
  518.     NumPastes = InputBox("Number of pastes to make", "Multiple Paste Macro",_
  519.                          "1")
  520.     For i = 1 To CInt(NumPastes)
  521.         ActiveDocument.Selection.Paste
  522.         'Because the selection remains active, the following two lines
  523.         'clear the selection, while keeping the cursor in the same place.
  524.         ActiveDocument.Selection.LineUp
  525.         ActiveDocument.Selection.LineDown
  526.         ActiveDocument.Selection = vbLf    
  527.     Next
  528. End Sub
  529.  
  530.  
  531. Sub PrintAllOpenDocuments ()
  532. 'DESCRIPTION: Prints all open, active documents.
  533.  
  534.     'Small, quick macro, but it can be usefull.
  535.     for each doc in Application.Documents
  536.         Doc.PrintOut
  537.     next
  538. End Sub
  539.  
  540.  
  541. Sub PoundDefOut (ifndef)
  542.     If ifndef = true Then
  543.         PoundType = "#ifndef "
  544.     Else
  545.         PoundType = "#ifdef "
  546.     End If
  547.     
  548.     If FileType(ActiveDocument) <> 1 Then
  549.         MsgBox ("This macro only works on" + vbLf + _
  550.                 ".c, .cpp, .cxx, .h, .hpp, or .hxx files")
  551.     Else
  552.         ControlVarName = InputBox("What should the control variable be?" + _
  553.             vbLf + vbLf + "Example: #ifdef ControlVariable", PoundType + _
  554.             " out a section of code")
  555.         OK = True
  556.         If ValidId (ControlVarName) = False Then
  557.             Ok = False
  558.             MsgBox("""" + ControlVarName + """" + _ 
  559.                 " is not a valid C identifier." + _
  560.                 vbLf + "please re-run the macro with a valid C identifier")
  561.         End If
  562.         
  563.         
  564.         Sel = ActiveDocument.Selection
  565.         For i = 1 To Len(Sel) - 1
  566.             If Mid(Sel, i, 1) = vbLf Then
  567.                 Sel = Left(Sel,i) + vbTab + Right(Sel, Len(Sel)-i)
  568.             End If
  569.         Next
  570.         If ControlVarName <> "" And Ok = True Then
  571.             Sel = vbLf + PoundType + ControlVarName + vbLf + vbTab + Sel + _
  572.                 vbLf+ "#endif //" + ControlVarName
  573.             If Right(Sel,1) <> vbLf Then
  574.                 Sel = Sel + vbLf
  575.             End If
  576.             ActiveDocument.Selection = Sel
  577.         End If
  578.     End If
  579. End Sub
  580.  
  581. 'The next two macros are exactly the same, except one uses ifndef and the
  582. '  other ifdef. We recycle the same code and just use a different 
  583. '  preprocessor directive.
  584. Sub ifdefOut ()
  585. 'DESCRIPTION: #ifdef / #endif out a section of code.
  586.  
  587.     PoundDefOut (False)
  588. End Sub
  589.  
  590. Sub ifndefOut ()
  591. 'DESCRIPTION: #ifndef / #endif out a section of code.
  592.  
  593.     PoundDefOut (True)
  594. End Sub
  595.  
  596. 'Allows the user to make sure the current header file is included only once. 
  597. ' There are two ways to do this, using the #pragma once directive or 
  598. ' surrounding the entire file in a #ifndef/#endif structure. The first way
  599. ' is much cleaner, but it is VC++ specific, and therefore not portable. If 
  600. ' you plan on compiling your code with other compilers, use the 
  601. ' #ifndef/#endif method, otherwise, the #pragma once option is preferrable.
  602. Sub OneTimeInclude ()
  603. 'DESCRIPTION: Adds code to the current header file so it is included only once per c/cpp file.
  604.     
  605.     ext = ActiveDocument.Name
  606.     If ext = "" Then
  607.         If MsgBox("The file you are working with does not have a file extension." + _
  608.                 vbLF + "Are you sure this is a C/C++ header file?", 4) = vbCancel Then
  609.             Exit Sub
  610.         End If
  611.         ext = "nofilenamegiven.h"
  612.     End If
  613.     DocName = UCase(ext)
  614.     pos = Instr(ext, ".")
  615.     Do While pos <> 1
  616.         ext = Mid(ext, pos, (Len(ext) - pos + 1))
  617.         pos = Instr(ext, ".")
  618.     Loop
  619.     ext = LCase(ext)
  620.     pos = Instr(DocName, ".")
  621.     If ext = ".h" Or ext = ".hpp" Then
  622.         'Warn user that this will not work with a compiler other than VC++.
  623.         If MsgBox("This macro uses the Visual C++ dependant #pragma once" + _
  624.                 vbLf + "Is the source to be portable across compilers?", 4) _
  625.                 = 6 Then
  626.             ActiveDocument.Selection.StartOfDocument (False)
  627.             Examp = "__" + Left(DocName, pos - 1) + "_" + _
  628.                 UCase(Right(ext, len(ext) - 1)) + "__"
  629.             ControlVarName = InputBox("What should the control variable be?" _
  630.                 + vbLf + vbLf + "Example: #ifdef " + _
  631.                 Examp, "One time header include protection", Examp)
  632.             If ValidId (ControlVarName) = True Then
  633.                 ActiveDocument.Selection = "#ifndef " + ControlVarName + _
  634.                     vbLf + "#define " + ControlVarName + vbLf
  635.                 ActiveDocument.Selection.EndOfDocument(False)
  636.                 ActiveDocument.Selection = vbLf + "#endif //" + _ 
  637.                     ControlVarName
  638.             Else
  639.                 MsgBox(ControlVarName + " is not a valid c identifier." + _
  640.                 vbLf + "please re-run the macro with a valid C identifier")
  641.             End If
  642.         Else
  643.             ActiveDocument.Selection.StartOfDocument(False)
  644.             ActiveDocument.Selection = "#pragma once" + vbLf + vbLf
  645.         End If
  646.     Else
  647.         MsgBox("This macro can only be run on .h or .hpp files")
  648.     End If
  649. End Sub
  650.  
  651.  
  652.  
  653. 'Auto completion macro
  654. Dim previousSelection
  655. Dim completionWords
  656. Dim completionWordsIndex
  657.  
  658. Sub AddToCompletionWords (word)
  659.     ' If the word is already there, abort
  660.     if InStr(1, completionWords, " " & word & " ", 1) <> 0 Then
  661.         Exit Sub
  662.     End If
  663.  
  664.     completionWords = completionWords & word & " "
  665. End Sub
  666.  
  667. Function ExtractNextCompletionWord()
  668.     ExtractNextCompletionWord = ""
  669.  
  670.     ' If no words yet, go away
  671.     if Len(completionWords) <= 1 Then
  672.         Exit Function
  673.     End If
  674.     
  675.     ' Wrap to beginning if necessary
  676.     if completionWordsIndex > Len(completionWords) Then
  677.         completionWordsIndex = 2
  678.     End If
  679.  
  680.     ' Find next <space>
  681.     Dim newIndex
  682.     newIndex = InStr (completionWordsIndex, completionWords, " ", 0)
  683.     if newIndex = 0 Then
  684.         Exit Function
  685.     End If
  686.  
  687.     ExtractNextCompletionWord = Mid(completionWords, completionWordsIndex, _ 
  688.         newIndex-completionWordsIndex)
  689.     completionWordsIndex = newIndex+1        'Skip over <space>
  690. End Function
  691.  
  692. Sub FillCompletionWords (word)
  693.     ' Find all words in this file which match word, and
  694.     '  add them, space separated, into completionWords
  695.     previousSelection = word
  696.     completionWords = " "
  697.     completionWordsIndex = 2
  698.     dim sel
  699.     set sel = ActiveDocument.Selection
  700.  
  701.     Dim searchString
  702.     searchString = "\{^\![^a-zA-Z0-9]\}" & word
  703.     Dim firstTime
  704.     firstTime = True
  705.     Dim firstLine, firstCol
  706.     Do while sel.FindText (searchString, dsMatchBackward + dsMatchRegExp)
  707.         if firstTime Then
  708.             firstLine = sel.TopLine
  709.             firstCol = sel.CurrentColumn
  710.             firstTime = False
  711.         ElseIf firstLine = sel.TopLine And firstCol = sel.CurrentColumn Then
  712.             Exit Do        ' Jump out of loop before repeat
  713.         End If
  714.         sel.WordRight
  715.         sel.WordLeft dsExtend
  716.         AddToCompletionWords Trim(sel.text)
  717.         sel.Cancel
  718.     Loop
  719. End Sub
  720.  
  721. Function SuggestNextCompletionWord()
  722.     SuggestNextCompletionWord = True
  723.     Dim word
  724.     word = ExtractNextCompletionWord()
  725.     if word <> "" then
  726.         ActiveDocument.Selection = word
  727.         previousSelection = word
  728.     end if
  729. End Function
  730.  
  731. Sub AutoCompleteFromFile()
  732. 'DESCRIPTION: Looks through the active file, searching for the rest of the word that you began to type.
  733.     Dim doc
  734.     set doc = ActiveDocument
  735.  
  736.     ' Be sure active document is a text document
  737.     if doc Is Nothing Then
  738.         Exit Sub
  739.     elseif doc.Type <> "Text" Then
  740.         Exit Sub
  741.     End If
  742.  
  743.     ' Get word to be completed
  744.     Dim sel
  745.     set sel = doc.Selection
  746.     sel.Cancel
  747.     dim origLine, origCol
  748.     origLine = sel.TopLine
  749.     origCol = sel.CurrentColumn
  750.     sel.WordLeft dsExtend
  751.  
  752.     'If the cursor is sitting just to the right of a space, an infinite loop
  753.     'results. This bit of code protects from that:
  754.     if Right(sel, 1) = " " then
  755.         sel.CharRight
  756.         Exit Sub
  757.     end If
  758.  
  759.     if sel <> previousSelection Or completionWords = "" Then
  760.         FillCompletionWords sel
  761.         sel.MoveTo origLine, origCol
  762.         sel.WordLeft dsExtend
  763.     End If
  764.  
  765.     SuggestNextCompletionWord
  766.  
  767. End Sub
  768.