5 /***************************************************************************
7 EditorDocument provides the implementation of a single view editor (as opposed to a
8 multi-view editor that can display the same file in multiple modes like the HTML editor).
10 %ProjectName%.pkgdef contains:
12 [$RootKey$\KeyBindingTables\{%DocumentGuid%}]
14 "AllowNavKeyBinding"=dword:00000000
15 "Package"="{%PackageGuid%}"
17 which is required for some, but not all, of the key bindings, which are located at the bottom of
18 %ProjectClass%UI.vsct, to work correctly so that the appropriate command handler below will be
21 ***************************************************************************/
23 // This is provided as a template parameter to facilitate unit testing
24 // One traits class is provided rather then multiple template arguments
25 // so that when an new type is added, it isn't necessary to update all
26 // instances of the template decleration
27 class EditorDocumentDefaultTraits
30 // The rich edit control needs to be contained in another window, as the list view will send
31 // it's notifications to it's parent window; however, if the VS frame window is subclassed, VS
32 // may stomp on the window proc we have set, so we have to provide our own parent window
34 typedef Win32ControlContainer
<RichEditWin32Control
<> > RichEditContainer
;
35 typedef VSL::Cursor Cursor
;
36 typedef VSL::Keyboard Keyboard
;
37 typedef VSL::File File
;
40 template <class Traits_T
= EditorDocumentDefaultTraits
>
41 class EditorDocument
:
42 // Use ATL to take care of common COM infrastructure
43 public CComObjectRootEx
<CComSingleThreadModel
>,
44 // IVsWindowPane is required to be a document
45 public IVsWindowPaneImpl
<EditorDocument
<Traits_T
> >,
46 // IOleCommandTarget is required to be a document that handles commands (as any editor will need to do)
47 public IOleCommandTargetImpl
<EditorDocument
<Traits_T
> >,
48 // DocumentPersistanceBase provides the persistance related interfaces: IVsPersistDocData,
49 // IVsDocDataFileChangeContro, IVsFileChangeEvents, IPersistFileFormat, and IVsFileBackup.
50 public DocumentPersistanceBase
<EditorDocument
<Traits_T
>, typename
Traits_T::File
>,
51 // ISelectionContainer is required for the properties windows to be updated.
52 // The document only has one item to display properties for, so ISelectionContainerSingleItemImpl
53 // is used rather then ISelectionContainerImpl
54 public ISelectionContainerSingleItemImpl
<EditorDocument
<Traits_T
>, ITextDocument
>,
55 // IVsToolboxUser is required for items be dragged from the toolbox on to the document
56 public IVsToolboxUser
,
57 // IVsStatusbarUser is required to update the line and character position on the status bar,
58 // as well as the insertion (INS at the right most end of the status bar) state.
59 public IVsStatusbarUser
,
60 // Custom automation interface used with macro recording and playback
61 public IDispatchImpl
<ISingleViewEditor
, &__uuidof(ISingleViewEditor
), &LIBID_
%ProjectClass
%Lib
>,
62 // IExtensibleObject or IVsExtensibleObject is required to be an automation object
63 // IExtensibleObject is newer and prefered.
64 public IExtensibleObjectImpl
<EditorDocument
<Traits_T
> >,
65 // IVsFindTarget, IVsTextImage, and IVsTextSpanSet are required for find and replace to work correctly
66 public IVsFindTargetImpl
<EditorDocument
<Traits_T
>, TRUE
>,
67 public IVsTextImageImpl
<>,
68 public IVsTextSpanSetImpl
,
69 // IVsTextView, IVsTextViewEvents, IVsCodeWindow, IVsTextLines along with the a connection point
70 // for IVsTextViewEvents, are required so that double-clicking on results of a find in files in the
71 // output window will correctly naviagate to the location in the document. That is the only
72 // scenario these interfaces are required for.
73 public SingleViewFindInFilesOutputWindowIntegrationImpl
<EditorDocument
<Traits_T
> >,
74 public ATL::IConnectionPointContainerImpl
<EditorDocument
<Traits_T
> >,
75 // This is required in addition to IConnectionPointContainer for the connection map to compile properly
76 // This interface is not included in the interface map though, so it can not be QI'ed for.
77 public ATL::IConnectionPointImpl
<EditorDocument
<Traits_T
>, &IID_IVsTextViewEvents
>,
78 // The container for the rich edit control is the actual window associated with IVsWindowPane
79 // rather then the rich edit control, as the the parent window of IVsWindowPane is owned by
80 // the Visual Studio IDE and can not be used as the parent window of the rich edit control,
81 // it it can not be reliably sub-classed (VS doesn't guarantee it will not overwrite the
83 public Traits_T::RichEditContainer
86 // COM objects typically should not be cloned, and this prevents cloning by declaring the
87 // copy constructor and assignment operator private (NOTE: this macro includes the decleration of
88 // a private section, so everything following this macro and preceding a public or protected
89 // section will be private).
90 VSL_DECLARE_NOT_COPYABLE(EditorDocument
)
94 typedef typename
Traits_T::File File
;
96 // Provides a portion of the implementation of IUnknown, in particular the list of interfaces
97 // the EditorDocument object will support via QueryInterface
98 BEGIN_COM_MAP(EditorDocument
)
99 COM_INTERFACE_ENTRY(IVsWindowPane
)
100 COM_INTERFACE_ENTRY(ISelectionContainer
)
101 COM_INTERFACE_ENTRY(IOleCommandTarget
)
102 COM_INTERFACE_ENTRY(IPersistFileFormat
)
103 COM_INTERFACE_ENTRY(IPersist
)
104 COM_INTERFACE_ENTRY(IVsPersistDocData
)
105 COM_INTERFACE_ENTRY(IVsFileChangeEvents
)
106 COM_INTERFACE_ENTRY(IVsDocDataFileChangeControl
)
107 COM_INTERFACE_ENTRY(IVsFileBackup
)
108 COM_INTERFACE_ENTRY(IVsToolboxUser
)
109 COM_INTERFACE_ENTRY(IVsStatusbarUser
)
110 COM_INTERFACE_ENTRY(IDispatch
)
111 COM_INTERFACE_ENTRY(ISingleViewEditor
)
112 COM_INTERFACE_ENTRY(IExtensibleObject
)
113 COM_INTERFACE_ENTRY(IVsFindTarget
)
114 COM_INTERFACE_ENTRY(IVsTextImage
)
115 COM_INTERFACE_ENTRY(IVsTextSpanSet
)
116 COM_INTERFACE_ENTRY(IVsTextBuffer
)
117 COM_INTERFACE_ENTRY(IVsTextView
)
118 COM_INTERFACE_ENTRY(IConnectionPointContainer
)
119 // IConnectionPoint is purposefully omitted
120 COM_INTERFACE_ENTRY(IVsTextViewEvents
)
121 COM_INTERFACE_ENTRY(IVsCodeWindow
)
122 COM_INTERFACE_ENTRY(IVsTextLines
)
125 // Defines the command handlers. IOleCommandTargetImpl will use these handlers to implement
126 // IOleCommandTarget.
127 VSL_BEGIN_COMMAND_MAP()
128 // Every command is identified by the shell using a GUID/DWORD pair, so every the definition of
129 // commands must contain this information.
131 // The following command map entries define a GUID/DWORD pair to identify the command and a
132 // callback for the command execution and status queries.
133 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidCopy
, &OnQueryCopy
, &OnCopy
)
134 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidCut
, &OnQueryCut
, &OnCut
)
135 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidDelete
, NULL
, &OnDelete
)
136 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidPaste
, &OnQueryPaste
, &OnPaste
)
137 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidBold
, &OnQueryBold
, &OnBold
)
138 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidItalic
, &OnQueryItalic
, &OnItalic
)
139 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidUnderline
, &OnQueryUnderline
, &OnUnderline
)
140 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidJustifyLeft
, &OnQueryJustifyLeft
, &OnJustifyLeft
)
141 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidJustifyRight
, &OnQueryJustifyRight
, &OnJustifyRight
)
142 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidJustifyCenter
, &OnQueryJustifyCenter
, &OnJustifyCenter
)
143 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidFontNameGetList
, &OnQueryFontNameGetList
, &OnFontNameGetList
)
144 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidFontName
, &OnQueryFontName
, &OnFontName
)
145 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidFontSizeGetList
, &OnQueryFontSizeGetList
, &OnFontSizeGetList
)
146 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidFontSize
, &OnQueryFontSize
, &OnFontSize
)
147 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet97
, cmdidPasteNextTBXCBItem
, &OnQueryPasteNextTBXCBItem
, &OnPasteNextTBXCBItem
)
148 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet2K
, ECMD_BULLETEDLIST
, &OnQueryBulletedList
, &OnBulletedList
)
149 VSL_COMMAND_MAP_ENTRY(CMDSETID_StandardCommandSet2K
, ECMD_INSERT
, &OnQueryInsert
, &OnInsert
)
150 VSL_COMMAND_MAP_ENTRY(CLSID_
%ProjectClass
%CmdSet
, commandIDStrike
, &OnQueryStrikeOut
, &OnStrikeOut
)
152 // Terminate the definition of the command map
153 VSL_END_VSCOMMAND_MAP()
155 VSL_BEGIN_MSG_MAP(EditorDocument
)
156 // Whenever the content changes, need to check and see if the file can be edited,
157 // if not then the changes will be rejected.
158 COMMAND_HANDLER(RichEditContainer::iContainedControlID
, EN_CHANGE
, OnContentChange
)
159 // Whenever the selection changes, need to update the Visual Studio UI (i.e. status bar, menus,
161 NOTIFY_HANDLER(RichEditContainer::iContainedControlID
, EN_SELCHANGE
, OnSelectionChange
)
162 // On this event the context menu will be shown if needed, and some keyboard commands will be
164 NOTIFY_HANDLER(RichEditContainer::iContainedControlID
, EN_MSGFILTER
, OnUserInteractionEvent
)
165 MESSAGE_HANDLER(WM_TIMER
, OnTimer
)
166 MESSAGE_HANDLER(WM_SETFOCUS
, OnSetFocus
)
167 // Let the rich edit container process all other messages
168 CHAIN_MSG_MAP(RichEditContainer
)
171 // This is necessary to implement the connection point for IVsTextViewEvents
172 // See comment above SingleViewFindInFilesOutputWindowIntegrationImpl
173 BEGIN_CONNECTION_POINT_MAP(EditorDocument
)
174 CONNECTION_POINT_ENTRY(IID_IVsTextViewEvents
)
175 END_CONNECTION_POINT_MAP()
177 // IVsWindowPane methods overriden or not provided by IVsWindowPaneImpl
179 STDMETHOD(CreatePaneWindow
)(
180 /*[in] */ _In_ HWND hwndParent
,
181 /*[in] */ _In_
int x
,
182 /*[in] */ _In_
int y
,
183 /*[in] */ _In_
int cx
,
184 /*[in] */ _In_
int cy
,
185 /*[out]*/ _Out_ HWND
*hwnd
);
186 STDMETHOD(GetDefaultSize
)(
187 /*[out]*/ _Out_ SIZE
*psize
);
188 STDMETHOD(ClosePane
)();
190 // IVsToolboxUser method
192 STDMETHOD(IsSupported
)(/*[in] */ _In_ IDataObject
* pDO
);
193 STDMETHOD(ItemPicked
)(/*[in] */ _In_ IDataObject
* pDO
);
195 // ISingleViewEditor - this is the object model exposed by the editor in order to
196 // facilitate macro recording.
198 STDMETHOD(get_DTE
)(/* [out] */ _Deref_out_ _DTE
** ppDTE
);
199 STDMETHOD(get_Parent
)(/* [out] */ _Deref_out_ _DTE
** ppDTE
);
200 STDMETHOD(get_DefaultTabStop
)(/* [out] */ _Out_
float* pdVal
);
201 STDMETHOD(put_DefaultTabStop
)(/* [in] */ float dVal
);
202 STDMETHOD(get_Range
)(/* [out] */ _Deref_out_
/*ITextRange*/IDispatch
** ppRange
);
203 STDMETHOD(get_Selection
)(/* [out] */ _Deref_out_
/*ITextSelection*/IDispatch
** ppSelection
);
204 STDMETHOD(get_Flags
)(/* [out] */ _Out_
long* plFlags
);
205 STDMETHOD(put_Flags
)(/* [in] */ long lFlags
);
206 STDMETHOD(FindText
)(/* [in] */ _In_ BSTR pStr
);
207 STDMETHOD(SetText
)(/* [in] */ _In_ BSTR pStr
);
208 STDMETHOD(TypeText
)(/* [in] */ _In_ BSTR pStr
);
213 /* [in] */ long lUnit
,
214 /* [in] */ long cUnit
);
216 /* [in] */ long lUnit
,
217 /* [in] */ long cUnit
,
218 /* [in] */ long lExtend
);
220 /* [in] */ long lUnit
,
221 /* [in] */ long cUnit
,
222 /* [in] */ long lExtend
);
224 /* [in] */ long lUnit
,
225 /* [in] */ long cUnit
,
226 /* [in] */ long lExtend
);
227 STDMETHOD(MoveRight
)(
228 /* [in] */ long lUnit
,
229 /* [in] */ long cUnit
,
230 /* [in] */ long lExtend
);
232 /* [in] */ long lUnit
,
233 /* [in] */ long lExtend
);
235 /* [in] */ long lUnit
,
236 /* [in] */ long lExtend
);
238 // IVsStatusbarUser methods
240 STDMETHOD(SetInfo
)();
242 // IVsFindTarget methods
244 STDMETHOD(GetProperty
)(
245 /* [in] */ VSFTPROPID propid
,
246 /* [out]*/ _Out_ VARIANT
* pvar
);
247 STDMETHOD(NavigateTo
)(
248 /* [in] */ const TextSpan
* pts
);
249 STDMETHOD(GetCurrentSpan
)(
250 /* [out]*/ _Out_ TextSpan
* pts
);
252 // IVsTextImage methods
254 STDMETHOD(GetLineSize
)(
255 /* [retval][out] */ _Out_ LONG
* pcLines
);
257 /* [in] */ DWORD dwFlags
,
258 /* [in] */ const TextSpan
* pts
,
260 /* [size_is][in] */ LPCOLESTR pchText
,
261 /* [retval][out] */ _Out_ TextSpan
* ptsChanged
);
262 STDMETHOD(GetSpanLength
)(
263 /* [in] */ const TextSpan
* pts
,
264 /* [retval][out] */ _Out_ LONG
* pcch
);
265 STDMETHOD(GetLineLength
)(
266 /* [in] */ LONG iLine
,
267 /* [retval][out] */ _Out_ LONG
* piLength
);
269 /* [in] */ DWORD grfGet
,
270 /* [in] */ LONG iLine
,
271 /* [in] */ LONG iStartIndex
,
272 /* [in] */ LONG iEndIndex
,
273 /* [retval][out] */ _Out_ LINEDATAEX
* pLineData
);
275 // IVsTextLines methods not provided by SingleViewFindInFilesOutputWindowIntegrationImpl
277 STDMETHOD(GetLengthOfLine
)(
278 /* [in] */ long iLine
,
279 /* [out] */ _Out_
long *piLength
);
280 STDMETHOD(GetLastLineIndex
)(
281 /* [out] */ _Out_
long *piLine
,
282 /* [out] */ _Out_
long *piIndex
);
284 // IVsTextView methods not provided by SingleViewFindInFilesOutputWindowIntegrationImpl
286 STDMETHOD(SetSelection
)(
287 /* [in] */ long iAnchorLine
,
288 /* [in] */ ViewCol iAnchorCol
,
289 /* [in] */ long iEndLine
,
290 /* [in] */ ViewCol iEndCol
);
292 // VSL base class statically bound call back methods
294 // Called by IExtensibleObjectImpl::GetAutomationObject
295 IDispatch
* GetNamedAutomationObject(_In_z_ BSTR bstrName
);
297 // Called by VSL::DocumentPersistanceBase::InitNew and VSL::DocumentPersistanceBase::Save
298 bool IsValidFormat(DWORD dwFormatIndex
);
300 // Called by VSL::DocumentPersistanceBase::FilesChanged
301 void OnFileChangedSetTimer();
303 // Called by VSL::DocumentPersistanceBase::GetClassID, which is also called by
304 // VSL::DocumentPersistanceBase::GetGuidEditorType)
305 const GUID
& GetEditorTypeGuid() const;
307 // Called by VSL::DocumentPersistanceBase::GetFormatList
308 void GetFormatListString(ATL::CStringW
& rstrFormatList
);
310 // Called indirectly by VSL::DocumentPersistanceBase::Load and VSL::DocumentPersistanceBase::Save
313 // Called indirectly by VSL::DocumentPersistanceBase::FilesChanged,
314 // VSL::DocumentPersistanceBase::IgnoreFileChanges, VSL::DocumentPersistanceBase::Load, and
315 // VSL::DocumentPersistanceBase::Save
316 void PostSetReadOnly();
318 // FUTURE - 3/17/2006 - could move the 2 following methods on to the Rich Edit control in VSL
320 // Called by the IPersistFileFormat::Load implementation on DocumentPersistanceBase
321 HRESULT
ReadData(File
& rFile
, BOOL bInsert
, DWORD
& rdwFormatIndex
) throw();
323 // Called indirectly by IPersistFileFormat::Save and IVsFileBackup::BackupFile implementations
324 // on DocumentPersistanceBase
325 void WriteData(File
& rFile
, DWORD
/*dwFormatIndex*/);
327 // Called by VSL::IVsFindTargetImpl::GetCapabilities and
328 // VSL::IVsFindTargetImpl::GetSearchImage
329 DWORD
GetCapabilityOptions();
333 typedef typename
Traits_T::RichEditContainer RichEditContainer
;
334 typedef typename
Traits_T::RichEditContainer::Control Control
;
335 typedef typename
Traits_T::Keyboard Keyboard
;
337 typedef typename IVsWindowPaneImpl
<EditorDocument
<Traits_T
> >::VsSiteCache VsSiteCache
;
339 typedef EditorDocument
<Traits_T
> This
;
349 VSL_ASSERT(m_bClosed
);
352 // Paranoid clean-up. Ignore return value, nothing to do if this fails,
353 // and execution should not have arrived here anyway.
358 // Called by the Rich Edit control during the processing of EM_STREAMOUT and EM_STREAMIN
359 template <bool bRead_T
>
360 static DWORD CALLBACK
EditStreamCallback(
361 _In_ DWORD_PTR dwpFile
,
362 _Inout_bytecap_(iBufferByteSize
) LPBYTE pBuffer
,
363 LONG iBufferByteSize
,
364 _Out_ LONG
* piBytesWritten
);
366 // Window Proc for the rich edit control. Necessary to implement macro recording.
367 static LRESULT CALLBACK
RichEditWindowProc(
373 #pragma warning(push)
374 #pragma warning(disable : 4480) // // warning C4480: nonstandard extension used: specifying underlying type for enum
375 enum TimerID
: WPARAM
377 // ID of timer message sent from OnFileChangedSetTimer
378 WFILECHANGEDTIMERID
= 1,
379 // ID of timer message sent from OnSetFocus
380 WDELAYSTATUSBARUPDATETIMERID
= 2,
386 // Windows message handlers
388 LRESULT
OnContentChange(WORD
/*iCommand*/, WORD
/*iId*/, _In_ HWND hWindow
, BOOL
& /*bHandled*/);
389 LRESULT
OnSelectionChange(int /*wParam*/, _In_ LPNMHDR
/*pHeader*/, BOOL
& /*bHandled*/);
390 LRESULT
OnUserInteractionEvent(int /*wParam*/, _In_ LPNMHDR pHeader
, BOOL
& /*bHandled*/);
391 LRESULT
OnTimer(UINT
/*uMsg*/, _In_ WPARAM wParam
, _In_ LPARAM
/*lParam*/, BOOL
& /*bHandled*/);
392 LRESULT
OnSetFocus(UINT
/*uMsg*/, _In_ WPARAM wParam
, _In_ LPARAM
/*lParam*/, BOOL
& bHandled
);
394 // Visual Studio command handlers
396 void OnCopy(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
397 void OnQueryCopy(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
398 void OnCut(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
399 void OnQueryCut(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
400 void OnDelete(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
401 void OnPaste(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
402 void OnQueryPaste(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
403 void OnBold(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
404 void OnQueryBold(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
405 void OnItalic(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
406 void OnQueryItalic(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
407 void OnUnderline(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
408 void OnQueryUnderline(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
409 void OnJustifyLeft(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
410 void OnQueryJustifyLeft(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
411 void OnJustifyRight(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
412 void OnQueryJustifyRight(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
413 void OnJustifyCenter(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
414 void OnQueryJustifyCenter(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
415 void OnFontNameGetList(_In_ CommandHandler
* /*pSender*/, DWORD flags
, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* pOut
);
416 void OnQueryFontNameGetList(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
417 void OnFontName(_In_ CommandHandler
* /*pSender*/, DWORD flags
, _In_ VARIANT
* pIn
, _Out_ VARIANT
* pOut
);
418 void OnQueryFontName(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
419 void OnFontSizeGetList(_In_ CommandHandler
* /*pSender*/, DWORD flags
, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* pOut
);
420 void OnQueryFontSizeGetList(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
421 void OnFontSize(_In_ CommandHandler
* /*pSender*/, DWORD flags
, _In_ VARIANT
* pIn
, _Out_ VARIANT
* pOut
);
422 void OnQueryFontSize(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
423 void OnPasteNextTBXCBItem(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
424 void OnQueryPasteNextTBXCBItem(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
425 void OnBulletedList(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
426 void OnQueryBulletedList(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
427 void OnInsert(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
428 void OnQueryInsert(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
429 void OnStrikeOut(_In_ CommandHandler
* /*pSender*/, DWORD
/*flags*/, _In_ VARIANT
* /*pIn*/, _Out_ VARIANT
* /*pOut*/);
430 void OnQueryStrikeOut(const CommandHandler
& /*rSender*/, _Inout_ OLECMD
* pOleCmd
, _Inout_ OLECMDTEXT
* /*pOleText*/);
432 // Rich Edit object model helper methods
434 void GetTextSelection(CComPtr
<ITextSelection
>& rspITextSelection
)
437 CHKHR(GetControl().GetITextDocument()->GetSelection(&rspITextSelection
));
438 CHKPTR(rspITextSelection
.p
, E_FAIL
);
441 void GetTextRange(CComPtr
<ITextRange
>& rspITextRange
)
444 CHKHR(GetControl().GetITextDocument()->Range(0, tomForward
, &rspITextRange
));
445 CHKPTR(rspITextRange
.p
, E_FAIL
);
448 void GetTextFont(CComPtr
<ITextFont
>& rspITextFont
)
450 CComPtr
<ITextSelection
> spITextSelection
;
451 GetTextSelection(spITextSelection
);
452 CHKHR(spITextSelection
->GetFont(&rspITextFont
));
455 void GetTextPara(CComPtr
<ITextPara
>& rspITextPara
)
457 CComPtr
<ITextSelection
> spITextSelection
;
458 GetTextSelection(spITextSelection
);
459 CHKHR(spITextSelection
->GetPara(&rspITextPara
));
462 // Helper function to obtain the ITextSelection flags
463 long GetTextSelectionFlags();
465 // Macro recording helper methods
467 // Last command type sent to the macro recorder. Note that there are more commands
468 // recorded than is implied by this list.
473 eLastMacroDownArrowLine
,
474 eLastMacroDownArrowLineSel
,
475 eLastMacroDownArrowPara
,
476 eLastMacroDownArrowParaSel
,
477 eLastMacroUpArrowLine
,
478 eLastMacroUpArrowLineSel
,
479 eLastMacroUpArrowPara
,
480 eLastMacroUpArrowParaSel
,
481 eLastMacroLeftArrowChar
,
482 eLastMacroLeftArrowCharSel
,
483 eLastMacroLeftArrowWord
,
484 eLastMacroLeftArrowWordSel
,
485 eLastMacroRightArrowChar
,
486 eLastMacroRightArrowCharSel
,
487 eLastMacroRightArrowWord
,
488 eLastMacroRightArrowWordSel
,
489 eLastMacroDeleteChar
,
490 eLastMacroDeleteWord
,
491 eLastMacroBackSpaceChar
,
492 eLastMacroBackSpaceWord
495 void RecordCommand(const wchar_t* szCommand
);
497 // Member functions used to interface with the shell macro recording service.
498 // Note that although macro recording may fail we do not return any errors.
499 void RecordKeyStroke(UINT msg
, _In_ WPARAM wParam
, _In_ LPARAM lParam
);
501 // This function outputs a line to the macro recorder in response to a
502 // delete or backspace key.
503 void RecordDelete(bool bBackspace
= false, bool bWord
= false);
505 // This function outputs a line to the macro recorder in response to an
506 // Up, Down, Left or Right Arrow.
510 Character
= tomCharacter
,
513 Paragraph
= tomParagraph
516 void RecordMove(LastMacro eState
, LPCWSTR szDirection
, MoveScope eScope
, bool bExtend
);
518 // Find and Replace helper methods
520 // IVsFindTarget helper to get selection string if it is only single line
521 void GetInitialPattern(_Deref_out_z_ BSTR
*pbstrSelection
);
523 // Format command handler helper methods
525 // Function to obtain and set Character and paragraph properties.
526 DWORD
GetFontFormatState(DWORD dwEffect
);
527 void SetFontFormatState(DWORD dwEffect
);
528 DWORD
QueryParagraphAlignmentState(long lState
);
529 DWORD
GetBulletState();
530 void SetParagraphAlignment(long iAlignment
);
531 void ToggleBulleted();
533 // Font command handler helper methods
535 typedef std::list
<BSTR
> FontNameList
;
537 // OleCommandTarget Helper functions for selecting font names and sizes.
538 void GetFontName(_Out_ VARIANT
*pvarOut
);
539 void GetFontSize(_Out_ VARIANT
*pvarOut
);
540 void SetFontName(_In_ VARIANT
*pvarNew
);
541 void SetFontSize(_In_ VARIANT
*pvarNew
);
543 // Helper function for query status for command cmdidPasteNextTBXCBItem
545 bool CanCycleClipboard();
546 void PasteClipboardObject();
548 // IVsToolboxUser helper
550 void IVsToolboxUserHelper(_In_ IDataObject
* pDataObject
, ATL::CComVariant
& vt
);
552 // Status bar helper functions
554 void StatusBarUpdatePos(_In_ IVsStatusbar
* pIVsStatusBar
= NULL
);
555 void StatusBarUpdateInsMode(_In_ IVsStatusbar
* pIVsStatusBar
= NULL
);
557 // Miscelanous helper methods
560 bool IsSelectionEmpty();
562 // Helper function to checkout file if necessary.
563 bool ShouldDiscardChange();
565 // Calls IVsUIShell method to tell the environment to update the state of
566 // the command bars (menus and toolbars).
567 void UpdateVSCommandUI();
569 void EnsureNotClosed()
571 CHK(!m_bClosed
, E_UNEXPECTED
);
576 // Simplifies macro recording
577 VsMacroRecorder
<&CLSID_
%ProjectClass
%EditorDocument
, LastMacro
, eLastMacroNone
> m_Recorder
;
579 // Window procedure pointer for the window containing the rich edit control
580 WNDPROC m_pWindowProc
;
582 // Buffer for text input during macro recording
583 CStringW m_strTextToRecord
;
585 // IVsWindowPane Data