テキスト エディターでキーの押下を記録して再生できる Visual Studio 拡張機能を作成しようとしています。
作成中の新しいテキスト エディターにコマンド フィルターを追加するIVsTextViewCreationListener
呼び出しがあります。AddCommandFilter()
public class VsTextViewCreationListener : IVsTextViewCreationListener
{
public void VsTextViewCreated(IVsTextView textViewAdapter)
{
var filter = new MyCommandFilter();
IOleCommandTarget next;
if (ErrorHandler.Succeeded(textViewAdapter.AddCommandFilter(filter, out next)))
filter.Next = next;
}
}
コマンド フィルターは次のようになります。
public class MyCommandFilter : IOleCommandTarget
{
public IOleCommandTarget Next { get; set; }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
{
if (nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
{
// Save values of pguidCmdGroup, nCmdID, nCmdexecopt and GetTypedChar(pvaIn)
// ...
}
return Next.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
}
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
{
return Next.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
}
public void Playback()
{
// Resend the values
var pvaIn = Marshal.AllocCoTaskMem(4);
Marshal.GetNativeVariantForObject((ushort)savedChar, pvaIn);
Next.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, IntPtr.Zero);
}
private static char GetTypedChar(IntPtr pvaIn)
{
return (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
}
}
(リスト内の値を保持するコードの部分を切り取っています)
キーの押下をキャプチャして再生するという意味では機能しますが、再生すると Visual Studio が頻繁に (常にではありません) クラッシュし、クラッシュはネイティブ コードで発生するため、エラーに関するデータはあまりありません。
私は以前にVS拡張機能を書いたことがなく、確かに私がやっていることはせいぜい大ざっぱです...
(おそらく、割り当てられたメモリを解放する必要がありますAllocCoTaskMem()
-試してみましたが、まだクラッシュしていました。この時点では、解放しなくても害はないと思いました)。
アイデアをいただければ幸いです。