Re: Unicode setting question
"Giovanni Dicanio" <giovanni.dicanio@invalid.com> ha scritto nel messaggio
news:%23AKWmhkwIHA.5096@TK2MSFTNGP02.phx.gbl...
I wrote a macro for VS2008 (I hope it works for older IDEs, too) to make
things a little better.
[...]
This new version allows decoration using _T() or TEXT().
(A little refactoring of the previous version...)
<code>
'****************************************************************************
' Macro for Visual Studio 2008, to decorate C/C++ literal strings using _T()
' to make them "Unicode-aware".
'
' By Giovanni Dicanio
' 2008, May 30th
'
'
' Usage
' -----
'
' Position the cursor on the left or on the right of the closing " of
' the string to decorate, and then run this macro.
'
' Valid cursor positions [<cursor> = cursor position in the editor]:
'
' "ciao"<cursor>
'
' "ciao<cursor>"
'
'
' Supports UNDO.
'
' There are two macros available: UnicodeTDecorator.DecorateT and
' UnicodeTDecorator.DecorateText.
' DecorateT decorates using _T().
' DecorateText decorates using TEXT().
'
'****************************************************************************
Imports System
Imports EnvDTE
Imports System.Diagnostics
Public Module UnicodeTDecorator
'========================================================================
' Macro to decorate an undecorated string using _T().
'========================================================================
Public Sub DecorateT()
UnicodeDecorate("_T(")
End Sub
'========================================================================
' Macro to decorate an undecorated string using TEXT().
'========================================================================
Public Sub DecorateText()
UnicodeDecorate("TEXT(")
End Sub
'========================================================================
' This is the "core" routine to performan decoration job.
' The string prefix to be used on the left (opening) side is passed
' as input parameter
'========================================================================
Private Sub UnicodeDecorate(ByVal openDecoration As String)
' The quote " character
Const QuoteChar As Char = Chr(34)
' Access current cursor position (EditPoint)
Dim ts As TextSelection = DTE.ActiveDocument.Selection
Dim ep As EditPoint = ts.ActivePoint.CreateEditPoint
' This will point to the closing "
Dim epEnd As EditPoint = ep.CreateEditPoint
' Error Message-box Title
Dim errorTitle As String = _
"[Unicode String Decorator] *** ERROR ***"
Try
' This macro can work in both cases of cursor
' on the left or on the right of closing quote:
'
' "ciao"<cursor>
' "ciao<cursor>"
'
' Check that the cursor is on the right of closing "
If (epEnd.GetText(-1) <> QuoteChar) Then
' Check that the cursor is on the left of closing "
If (epEnd.GetText(1) <> QuoteChar) Then
' Bad position
MsgBox( _
"Cursor is in bad position." & vbCrLf & _
"The cursor must be on the left or on" & vbCrLf & _
"the right of the ending string quote.", _
MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation, _
errorTitle)
Exit Sub
End If
Else
' The cursor is on the right of closing " .
'
' Move a position back, we want it on the
' left of " to start algorithm
epEnd.CharLeft()
End If
' *** Debug
' Write(" Character at curr pos = " & epEnd.GetText(1))
' Move leftwards until we find matching " (the opening ")
Dim openQuoteFound As Boolean = False
Dim epStart As EditPoint = epEnd.CreateEditPoint
While (Not epStart.AtStartOfLine)
' Move one position on the left
epStart.CharLeft()
' If we found " , it is the opening " ,
' so we can stop looping
If (epStart.GetText(1) = QuoteChar) Then
openQuoteFound = True
Exit While
End If
End While
' Check that we exited from the loop because we found
' the opening ", and not for begin-of-line condition
If openQuoteFound = False Then
' No matching opening " found
MsgBox( _
"No opening string quote found.", _
MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation, _
errorTitle)
Exit Sub
End If
' We have just found where the string begins, and where it ends.
' *** Debug
' Write("Opening quote at : " & epStart.LineCharOffset)
' Write("Closing quote at : " & epEnd.LineCharOffset)
' Support for Undo
Dim undoWasOpen As Boolean = False
If DTE.UndoContext.IsOpen = True Then
undoWasOpen = True
Else
' Extract the the string we are decorating
epStart.CharRight()
Dim stringToDecorate As String = epStart.GetText(epEnd)
epStart.CharLeft()
Dim undoContextName As String
undoContextName = "Unicode String Decoration : " & _
QuoteChar & stringToDecorate & _
QuoteChar & _
" (line: " & epStart.Line & ")"
' *** Debug
' Write(undoContextName)
DTE.UndoContext.Open(undoContextName, False)
End If
'
' *** Insert Unicode _T() or TEXT() decoration ***
'
' Decorate string start
epStart.Insert(openDecoration)
' Decorate string end
epEnd.CharRight()
epEnd.Insert(")")
' Move after the closing )
ts.MoveToPoint(epEnd)
' Close the undo context only if it has been opened by us here
If undoWasOpen = False Then
' Close the undo object to commit changes
DTE.UndoContext.Close()
End If
' *** ALL RIGHT *** !
Catch ex As Exception
' Display any exception error message ...
MsgBox( _
ex.Message, _
MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation, _
errorTitle)
End Try
End Sub
'========================================================================
' Helpers for Output/Log
' May be useful during debugging and development.
'========================================================================
'------------------------------------------------------------------------
' Name: Write
' Desc: Write a "log" line
'------------------------------------------------------------------------
Private Sub Write(ByVal s As String)
Dim out As OutputWindowPane = GetOutputWindowPane("MACRO OUTPUT", _
True)
out.OutputString(s)
out.OutputString(vbCrLf)
End Sub
Private Function GetOutputWindowPane(ByVal Name As String, _
Optional ByVal show As Boolean = True) _
As OutputWindowPane
Dim win As Window = DTE.Windows.Item( _
EnvDTE.Constants.vsWindowKindOutput)
If show Then win.Visible = True
Dim ow As OutputWindow = win.Object
Dim owpane As OutputWindowPane
Try
owpane = ow.OutputWindowPanes.Item(Name)
Catch e As System.Exception
owpane = ow.OutputWindowPanes.Add(Name)
End Try
owpane.Activate()
Return owpane
End Function
End Module
</code>
Giovanni