2 using System
.Runtime
.CompilerServices
;
3 using System
.Runtime
.InteropServices
;
4 using Microsoft
.VisualStudio
;
5 using Microsoft
.VisualStudio
.Shell
.Interop
;
7 namespace %ProjectNamespace
%.%ProjectClass
%
9 // Last command type sent to the macro recorder. Note that there are more commands
10 // recorded than is implied by this list. Commands in this list (other than
11 // LastMacroNone) are coalesced when multiples of the same command are received
14 // This enum should be extended or replaced with your own command identifiers to enable
15 // Coalescing of commands.
21 DownArrowLineSelection
,
23 DownArrowParaSelection
,
29 LeftArrowCharSelection
,
31 LeftArrowWordSelection
,
33 RightArrowCharSelection
,
35 RightArrowWordSelection
,
42 [System
.Diagnostics
.CodeAnalysis
.SuppressMessage("Microsoft.Design", "CA1027:MarkEnumsWithFlags")]
43 [System
.Diagnostics
.CodeAnalysis
.SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")]
46 Character
= tom
.tomConstants
.tomCharacter
,
47 Word
= tom
.tomConstants
.tomWord
,
48 Line
= tom
.tomConstants
.tomLine
,
49 Paragraph
= tom
.tomConstants
.tomParagraph
53 /// The VSMacroRecorder class implementation and the IVsMacroRecorder Interface definition
54 /// were included here in this seperate class because they were not included in the
55 /// interop assemblies shipped with Visual Studio 2005.
57 /// When implementing a macro recorder this class should be copied into your own name space
58 /// and not shared between different 3rd party packages.
60 public class VSMacroRecorder
62 private IVsMacroRecorder m_VsMacroRecorder
;
63 private LastMacro m_LastMacroRecorded
;
64 private uint m_TimesPreviouslyRecorded
;
67 public VSMacroRecorder(Guid emitter
)
69 this.m_LastMacroRecorded
= LastMacro
.None
;
71 this.m_GuidEmitter
= emitter
;
74 // Compiler generated destructor is fine
78 m_LastMacroRecorded
= LastMacro
.None
;
79 m_TimesPreviouslyRecorded
= 0;
85 m_VsMacroRecorder
= null;
88 public bool IsLastRecordedMacro(LastMacro macro
)
90 return (macro
== m_LastMacroRecorded
&& ObjectIsLastMacroEmitter()) ? true : false;
93 public bool IsRecording()
95 // If the property can not be retreived it is assumeed no macro is being recorded.
96 VSRECORDSTATE recordState
= VSRECORDSTATE
.VSRECORDSTATE_OFF
;
98 // Retrieve the macro recording state.
99 IVsShell vsShell
= (IVsShell
)Microsoft
.VisualStudio
.Shell
.Package
.GetGlobalService(typeof(SVsShell
));
103 if (ErrorHandler
.Succeeded(vsShell
.GetProperty((int)__VSSPROPID
.VSSPROPID_RecordState
, out var)) && null != var)
105 recordState
= (VSRECORDSTATE
)var;
109 // If there is a change in the record state to OFF or ON we must either obtain
110 // or release the macro recorder.
111 if (recordState
== VSRECORDSTATE
.VSRECORDSTATE_ON
&& m_VsMacroRecorder
== null)
113 // If this QueryService fails we no macro recording
114 m_VsMacroRecorder
= (IVsMacroRecorder
)Microsoft
.VisualStudio
.Shell
.Package
.GetGlobalService(typeof(IVsMacroRecorder
));
116 else if (recordState
== VSRECORDSTATE
.VSRECORDSTATE_OFF
&& m_VsMacroRecorder
!= null)
118 // If the macro recording state has been switched off then we can release
119 // the service. Note that if the state has become paused we take no action.
123 return (m_VsMacroRecorder
!= null);
126 public void RecordLine(string line
)
128 m_VsMacroRecorder
.RecordLine(line
, ref m_GuidEmitter
);
132 public bool RecordBatchedLine(LastMacro macroRecorded
, string line
)
137 return RecordBatchedLine(macroRecorded
, line
, 0);
140 public bool RecordBatchedLine(LastMacro macroRecorded
, string line
, int maxLineLength
)
145 if (maxLineLength
> 0 && line
.Length
>= maxLineLength
)
147 // Reset the state after recording the line, so it will not be appended to further
149 // Notify the caller that the this line will not be appended to further
153 if(IsLastRecordedMacro(macroRecorded
))
155 m_VsMacroRecorder
.ReplaceLine(line
, ref m_GuidEmitter
);
156 // m_LastMacroRecorded can stay the same
157 ++m_TimesPreviouslyRecorded
;
161 m_VsMacroRecorder
.RecordLine(line
, ref m_GuidEmitter
);
162 m_LastMacroRecorded
= macroRecorded
;
163 m_TimesPreviouslyRecorded
= 1;
169 public uint GetTimesPreviouslyRecorded(LastMacro macro
)
171 return IsLastRecordedMacro(macro
) ? m_TimesPreviouslyRecorded
: 0;
174 // This function determines if the last line sent to the macro recorder was
175 // sent from this emitter. Note it is not valid to call this function if
176 // macro recording is switched off.
177 private bool ObjectIsLastMacroEmitter()
180 m_VsMacroRecorder
.GetLastEmitterId(out guid
);
181 return guid
.Equals(m_GuidEmitter
);
185 #region "IVsMacro Interfaces"
186 [StructLayout(LayoutKind
.Sequential
, Pack
= 4), ComConversionLoss
]
187 internal struct _VSPROPSHEETPAGE
191 [ComAliasName("vbapkg.ULONG_PTR")]
192 public uint hInstance
;
193 public ushort wTemplateId
;
194 public uint dwTemplateSize
;
196 public IntPtr pTemplate
;
197 [ComAliasName("vbapkg.ULONG_PTR")]
198 public uint pfnDlgProc
;
199 [ComAliasName("vbapkg.LONG_PTR")]
201 [ComAliasName("vbapkg.ULONG_PTR")]
202 public uint pfnCallback
;
204 public IntPtr pcRefParent
;
205 public uint dwReserved
;
206 [ComConversionLoss
, ComAliasName("vbapkg.wireHWND")]
207 public IntPtr hwndDlg
;
210 internal enum _VSRECORDMODE
213 VSRECORDMODE_ABSOLUTE
= 1,
214 VSRECORDMODE_RELATIVE
= 2
217 [ComImport
, ComConversionLoss
, InterfaceType(1), Guid("55ED27C1-4CE7-11D2-890F-0060083196C6")]
218 internal interface IVsMacros
220 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
221 void GetMacroCommands([Out
] IntPtr ppsaMacroCanonicalNames
);
224 [ComImport
, InterfaceType(1), Guid("04BBF6A5-4697-11D2-890E-0060083196C6")]
225 internal interface IVsMacroRecorder
227 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
228 void RecordStart([In
, MarshalAs(UnmanagedType
.LPWStr
)] string pszReserved
);
229 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
231 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
232 void RecordLine([In
, MarshalAs(UnmanagedType
.LPWStr
)] string pszLine
, [In
] ref Guid rguidEmitter
);
233 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
234 void GetLastEmitterId([Out
] out Guid pguidEmitter
);
235 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
236 void ReplaceLine([In
, MarshalAs(UnmanagedType
.LPWStr
)] string pszLine
, [In
] ref Guid rguidEmitter
);
237 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
239 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
241 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
243 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
244 void SetCodeEmittedFlag([In
] int fFlag
);
245 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
246 void GetCodeEmittedFlag([Out
] out int pfFlag
);
247 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
248 void GetKeyWord([In
] uint uiKeyWordId
, [Out
, MarshalAs(UnmanagedType
.BStr
)] out string pbstrKeyWord
);
249 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
250 void IsValidIdentifier([In
, MarshalAs(UnmanagedType
.LPWStr
)] string pszIdentifier
);
251 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
252 void GetRecordMode([Out
] out _VSRECORDMODE peRecordMode
);
253 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
254 void SetRecordMode([In
] _VSRECORDMODE eRecordMode
);
255 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
256 void GetStringLiteralExpression([In
, MarshalAs(UnmanagedType
.LPWStr
)] string pszStringValue
, [Out
, MarshalAs(UnmanagedType
.BStr
)] out string pbstrLiteralExpression
);
257 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
258 void ExecuteLine([In
, MarshalAs(UnmanagedType
.LPWStr
)] string pszLine
);
259 [MethodImpl(MethodImplOptions
.InternalCall
, MethodCodeType
= MethodCodeType
.Runtime
)]
260 void AddTypeLibRef([In
] ref Guid guidTypeLib
, [In
] uint uVerMaj
, [In
] uint uVerMin
);