VisualStudio/VC++
VBマクロはよくわかりません
VisualStudioマクロ
古いマルチバイト文字セットのソースを(とりあえず)Unicode用にする
ネットでVC++のサンプルをほじくりかえしてると昔の非Unicodeのものがガンガンヒットする。が、VisualStudio 2005以降Unicodeが標準だしコンパイラの設定を変えてもいいけど、それもまた厄介なこともあるのでとりあえず通り一遍の置換えをするマクロを作った。
VisualStudio 2005用です。他の環境では試していません。マクロエクスプローラ右クリック→新しいマクロプロジェクト→マクロIDEに貼り付けてどうぞ。ReplaceForUnicodeAllで開いてるソースに対して実行します。ReplaceForUnicodeで選択範囲のみに実行します。
やってることとしては、
- _tWinMainに
- tchar.hをinclude
- VS2005以降警告の出る所を修正
- LPSTR系をLPTSTRに
- 文字列リテラルに_T()を付ける
- 文字列操作系APIを_tcsなんたらに置換え
あとlstrlen()を無言で置き換えてますがそのまま使うとやばい時があります。元のソースで
int length = lstrlen(lpStr);
だとしたら、
length = (lstrlen(lpStr))*sizeof(TCHAR);
としないといろんな長さが半分になって死にます。文字数を要求してる時は大丈夫ですが、バイト数を要求してるとバッファオーバーです。_tcsncpy()もまずい。ReadFile()の末端処理やGetWindowTextLength()なども。それでもうまい事いかなかったらあきらめてコンパイラの設定をマルチバイト文字にしてください。変えられるような置換えのはずなので。ちなみに他にもUnicode移行時にひっかかった所がありますがまた今度。
ところで、最新のVisualStudio用VBAの正規表現ヘルプがどこにあるのかわかりません。古いのはありましたが表現が変わっており、しかたなく全部試してました。VSマクロは難しいです。
'ReplaceUnicode.vb
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics
Public Module ReplaceUnicode
Sub ReplaceForUnicodeAll()
ReplacePattern(DTE, True)
End Sub
Sub ReplaceForUnicode()
ReplacePattern(DTE, False)
End Sub
Sub SelectRange(ByVal txtSel As TextSelection, ByVal topLine As Integer, ByVal diff As Integer)
txtSel.MoveToLineAndOffset(topLine, 1)
txtSel.LineDown(True, diff)
End Sub
Sub MySelect(ByVal txtSel As TextSelection, ByVal all As Boolean, ByVal topLine As Integer, ByVal diff As Integer)
If (all) Then
txtSel.SelectAll()
Else
SelectRange(txtSel, topLine, diff)
End If
End Sub
Sub ReplacePattern(ByVal dte As DTE, ByVal all As Boolean)
Dim txtSel As TextSelection = _
CType(dte.ActiveDocument.Selection, TextSelection)
Dim topLine As Integer = txtSel.AnchorPoint.Line
Dim endLine As Integer = txtSel.ActivePoint.Line
Dim diff As Integer = endLine - topLine
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("WinMain", "_tWinMain", vsFindOptions.vsFindOptionsMatchCase)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("\#include \<windows\.h\>", "\#include \<windows\.h\>\n\#include \<tchar\.h\>", vsFindOptions.vsFindOptionsRegularExpression)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("msg.wParam", "(int)msg.wParam")
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("wc.hbrBackground = GetStockObject", "wc.hbrBackground = (HBRUSH)GetStockObject")
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("(LPCSTR)", "")
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("LPSTR", "LPTSTR", vsFindOptions.vsFindOptionsMatchCase)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("LPCSTR", "LPCTSTR", vsFindOptions.vsFindOptionsMatchCase)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("char ", "TCHAR ", vsFindOptions.vsFindOptionsMatchCase)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("{[^\\]}""""", "\1_T("""")", vsFindOptions.vsFindOptionsRegularExpression)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("{[^\\]}{""([^""]|(\\""))*[^\\]""}", "\1_T(\2)", vsFindOptions.vsFindOptionsRegularExpression)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("strcpy", "lstrcpy", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("strlen", "lstrlen", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("strcat", "lstrcat", vsFindOptions.vsFindOptionsMatchWholeWord)
'#include <tchar.h>
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("sprintf", "wsprintf", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("strcmp", "_tcscmp", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("stricmp", "_tcsicmp", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("strncpy", "_tcsncpy", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("strstr", "_tcsstr", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("strrchr", "_tcsrchr", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("strchr", "_tcschr", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("strtok", "_tcstok", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("atof", "_tstof", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("atoi", "_tstoi", vsFindOptions.vsFindOptionsMatchWholeWord)
MySelect(txtSel, all, topLine, diff)
txtSel.ReplacePattern("itoa", "_itot", vsFindOptions.vsFindOptionsMatchWholeWord)
End Sub
End Module