/**************************************************************************** * The VSSHELL Interfaces * Copyright (c) Microsoft Corporation, All Rights Reserved ****************************************************************************/ #ifndef INTEROPLIB // Imports - all imports should go here (inside the ifndef) import "oaidl.idl"; import "vsshell.idl"; import "vsshell2.idl"; import "vsshell80.idl"; import "vsshell90.idl"; import "vsshell100.idl"; import "vsshell110.idl"; import "vsshell120.idl"; import "vsshell140.idl"; import "vsshell150.idl"; import "vsshell164.idl"; import "objext.idl"; import "olecm.idl"; import "VsPlatformUI.idl"; import "basetsd.h"; import "oleidl.idl"; import "servprov.idl"; import "docobj.idl"; import "designer.idl"; import "textmgr.idl"; import "oleipc.idl"; #endif #include "vscookie.h" #include "vsshelluuids.h" // for uuid_VsPreserveSigAttribute /**************************************************************************** ***** General notes for updating this file ***** Proxy Stub If you modify anything in here, you may need to rebuild the proxy-stub, msenvXXXp.dll, and update its registration file, SetupAuthoring\env\Registry\msenvXXXp.ddr. To do that, once this file has been built and published, build from env\msenv\proxies and observe the build output. If you need to omit something from the proxy/stub file, then put it inside an #ifndef PROXYSTUB_BUILD/#endif block There is no need to define GUIDs in external header files such as vsshelluuids.h. Instead, define the GUID directly within the [uuid(...)] attribute and use __uuidof in native code. ***** Primary Interop Assemblies If you modify anything in here, you may need to rebuild the primary interop assemblies. To do that, once this file has been built and published, build from vscommon\pias using: 'msbuild pias.nativeproj' ***** PreserveSig Prefer "nopreservesig", which is the default for all new interfaces, because it creates cleaner managed code. Managed implementations are free to throw exceptions which will automatically be translated to HRESULTs in the CLR's COM interop layer. Native implementations will return HRESULTs and they will be converted to exceptions for managed callers. Do not create methods returning S_FALSE. Instead use an additional "[out] VARIANT_BOOL*" or "[out,retval] VARIANT_BOOL*" argument. ***** Interface inheritance You may derive new interfaces from existing ones, but avoid mixing "preservesig" (old) with "nopreservesig" (new). Derive from an older interface if all of the methods in your interface match the preservesig attributes of the older interface. Remember, when implementing a derived interface in C++, you must implement QueryInterface for the base interface(s) too. ***** Enumerators and bitwise flags passed as parameters: When a parameter must be exactly one of a set of values (a true enumerator), the values should be defined and used as follows: typedef enum __VSSAMPLETYPE { ST_THISTYPE = 0, // first value should be zero or one, except ST_THATTYPE = 1, // in special cases, and following values ST_THEOTHERTYPE = 2, // should use consecutive numbers } VSSAMPLETYPE; interface IVsSample : IUnknown { HRESULT SampleMethod([in] VSSAMPLETYPE stType); } When a parameter must be exactly one of a set of values (a true enumerator), and is considered a PROPID, the values should be defined and used as follows: enum __VSSAMPLEPROPID { VSSAMPPROPID_LAST = -7000, // first value should be a unique VSSAMPPROPID_This = -7000, // number not used by any other VSSAMPPROPID_That = -7001, // PROPID, and following values VSSAMPPROPID_FIRST = -7001, // should use consecutive numbers }; typedef LONG VSSAMPLEPROPID; interface IVsSample : IUnknown { HRESULT GetProperty([in] VSSAMPLEPROPID propid, [out,retval] VARIANT *pvar); HRESULT SetProperty([in] VSSAMPLEPROPID propid, [in] VARIANT var); } When a parameter can be none of or a combination of values (bitwise), the values should be defined and used as follows: enum __VSSAMPLEOPTS { SO_THISOPTION = 0x00000001, // first value should be one, SO_THATOPTION = 0x00000002, // following values should use SO_THEOTHEROPTION = 0x00000004, // consecutive powers of two }; typedef DWORD VSSAMPLEOPTS; interface IVsSample : IUnknown { HRESULT SampleMethod([in] VSSAMPLEOPTS grfOptions); } ***** Defining properties Define properties as follows: interface IVsSample : IUnknown { [propget] HRESULT Foo([out, retval] BSTR *pbstrFoo); [propput] HRESULT Foo([in] LPCOLESTR strFoo); } Using [propget], [propput] and [out, retval] makes the interface easier to implement and consume in managed code. Note: The example above shows a case where the get/put methods accept slightly different argument types (BSTR versus LPCOLESTR). As long as the equivalent interop types are the same, this is fine (MarshalAs[..] attributes will be added as necessary). However, this is typically seen only for string arguments. ***** Array typed args Pass array type arguments (both in and out) using [] and size_is when the corresponding size argument is present. You must have the array size as an argument for interop to work correctly. interface IVsSample : IUnknown { HRESULT MethodPassesInArray([in] int cItems, [in, size_is(cItems)] int prgiItems[]); } DO NOT use [in] int piItems[]. For simple element types, consider using SAFEARRAY: e.g. SAFEARRAY(VARIANT_BOOL), SAFEARRAY(BSTR), SAFEARRAY(INT), etc. because they interop cleanly to managed code, but note that there is additional memory allocation and it may not be appropriate for high- performance methods. Also see the following note. ******* SAFEARRAY(IVsFoo*) SAFEARRAY(IVsFoo*) will cause MIDL warning 2456: SAFEARRAY(interface pointer) doesn't work using midl generated proxy If you know for sure that implementions will never will never need to be called cross apartment (cross thread/process), then you can add [local] to the method. Alternatively, consider creating a custom IEnumXXX interface. ****** Strings Use "[in] LPCOLESTR" instead of "[in] BSTR" for faster marshaling and more convenience to native callers. (But continue to use "[out] BSTR*" for out args.) Generally, you don't need to specify [in,string] for NUL-terminated strings because most of the "pointer to character" typedefs are already attributed with [string]. (e.g. "typedef [string] const OLECHAR *LPCOLESTR") ******* Boolean Use VARIANT_BOOL instead of BOOL because it interops as System.Boolean instead of System.Int However, exercise caution when assigning or comparing to/from C++ bool in native code because VARIANT_BOOL is typedef'd as a short and VARIANT_TRUE is ((short)-1) ******* Optional (may be null) args Use [in,unique] for optional input arguments which may be NULL. Note that pointer_default(unique) does NOT do this automatically. Do not use [out,unique] because unique cannot be applied to [out]-only top-level pointer parameters. However, you can use [in,out,unique]. Do not use [optional]. It only works with VARIANT anyway and it's not obvious for managed coders. ******* [out] NonNullableType* Note that arguments of the type "[out] Foo* pFoo", where Foo is a "non-nullable type" such as int, double, VARIANT_BOOL, BSTR, will be converted to "out Foo[] pFoo" in managed code. This is a non-standard conversion applied by an IL transformation step during the build for the interop assembly. ******* Service GUIDs Define service GUIDs via an empty interface derived from IUnknown and put it inside an #ifndef PROXYSTUB_BUILD/#endif block ******* HWNDs, HANDLE, and other non-marshalable types Take care if you define an interface with HWND, HGDIOBJ or other Win32 handle types. These typically need to be marked [local] since they cannot cross apartment (specifically, process) boundaries. ******* WPARAM, LPARAM, LRESULT, *_PTR types Currently any of the types listed above is translated incorreclty in to PIA. As all of them are pointer types, we want them to be IntPtr type but PIA generation uses int32 or int64 based on build architecture so it is suggested to use "HANDLE" type when INTEROPLIB is defined. TODO: Figure out how to properly build these types in both header, typelib and interop. ****************************************************************************/ //------------------------------------------------------------------------------------------------------------ // IVsEditorFactory4 // Editor factories can provide the data and view for a document in a hierarchy without initializing an editor //------------------------------------------------------------------------------------------------------------ [uuid(5F149946-406A-4B77-A334-9314CDBACD2F)] interface IVsEditorFactory4 : IUnknown { // Gets a document data object for the document HRESULT GetDocumentData( [in] VSCREATEEDITORFLAGS grfCreate, // Flags that define the conditions under which to create the editor [in] LPCOLESTR pszMkDocument, // String form of the moniker identifier of the document in the project system [in] IVsHierarchy* pHier, // Pointer to the IVsHierarchy interface [in] VSITEMID itemid, // UI hierarchy item identifier for the editor [out, retval] IUnknown** ppunkDocData); // Pointer to the IUnknown interface for the DocData object // Gets a document view object for the document // Also provides the flags for window creation HRESULT GetDocumentView( [in] VSCREATEEDITORFLAGS grfCreate, // Flags that define the conditions under which to create the editor [in] LPCOLESTR pszPhysicalView, // Name of the physical view [in] IVsHierarchy* pHier, // Pointer to the IVsHierarchy interface [in] IUnknown* punkDocData, // Docdata object that is registered in the Running Document Table (RDT) [in] VSITEMID itemid, // UI hierarchy item identifier for the editor [out, retval] IUnknown** ppunkDocView); // Pointer to the IUnknown interface for the DocView object // Get the editor caption and optionally, the command UI for the document's window creation HRESULT GetEditorCaption( [in] LPCOLESTR pszMkDocument, // String form of the moniker identifier of the document in the project system [in] LPCOLESTR pszPhysicalView, // Name of the physical view [in] IVsHierarchy* pHier, // Pointer to the IVsHierarchy interface [in] IUnknown* punkDocData, // Docdata object that is registered in the Running Document Table (RDT) [out] GUID* pguidCmdUI, // Command UI GUID that can optionally be set. This GUID is active when this editor is activated [out, retval] BSTR* pbstrEditorCaption);// Initial caption defined by the document editor for the document window // Determines if the initialization of the editor should be deferred for this document until intellisense is ready HRESULT ShouldDeferUntilIntellisenseIsReady( [in] VSCREATEEDITORFLAGS grfCreate, // Flags that define the conditions under which to create the editor [in] LPCOLESTR pszMkDocument, // String form of the moniker identifier of the document in the project system [in] LPCOLESTR pszPhysicalView, // Name of the physical view [out, retval] VARIANT_BOOL* pShouldDefer); // 'True' if the initialization should be deferred, 'False' otherwise } //-------------------------------------------------------------------------------------------- // Extending __VSHPROPID10 (vsshell163.idl). // See previous version of vsshellXX.idl for previous enumeration values. //-------------------------------------------------------------------------------------------- enum __VSHPROPID11 { // VARIANT_BOOL [optional] Gets whether or not the hierarchy is supported for load. VSHPROPID_IsSupportedInCodespace = -2178, // GUID [optional] When in Codespaces, identifies remote project across solution (essentially a local copy of VSHPROPID_ProjectIDGuid). // When not in Codespaces, the property is not set and retrieving it will fail. VSHPROPID_RemoteProjectIDGuid = -2179, // !!!! NOTE !!!! THIS MUST BE THE SAME AS THE LAST PROP DEFINED // when this is extended in the next version idl, uses of it must be changed to the new value VSHPROPID_FIRST11 = -2179 }; enum __VSADDVPFLAGS4 { /********************************* defined in vsshell.idl ADDVP_AddToProjectWindow = 0x00000001, ADDVP_ExcludeFromBuild = 0x00000002, ADDVP_ExcludeFromDebugLaunch = 0x00000004, ADDVP_ExcludeFromDeploy = 0x00000008, ADDVP_ExcludeFromSCC = 0x00000010, ADDVP_ExcludeFromEnumOutputs = 0x00000020, ADDVP_ExcludeFromCfgUI = 0x00000040, *********************************/ /********************************* defined in vsshell121.idl ADDVP_ReloadOnProjectFileChanged = 0x00000080, // Enable Solution to watch for file changes to project file and reload on external change. *********************************/ /********************************* defined in vsshell140.idl ADDVP_InvisibleInternalProject = 0x0000016E, // Invisible project that never interferes with the user adding a project of the same name. // Normally any newly added project has to have a unique name that does not clash with existing // projects. ADDVP_InvisibleInternalProject projects are Virtual Projects that are either "place holder" // projects which listen for SolutionEvents (e.g. OnBeforeProjectRegisteredInRunningDocumentTable // or OnAfterOpenProject) and auto remove themselves to not interfere with the user added project // or they are non-traditional internal (e.g. files imported by projects only like MSBuild targets // files, Shared.projitems files or VC .filters files) that are never opened as normal projects directly. // NOTE: ADDVP_InvisibleInternalProject includes the following flags: // ADDVP_ExcludeFromBuild | ADDVP_ExcludeFromDeploy | ADDVP_ExcludeFromDebugLaunch | ADDVP_ExcludeFromEnumOutputs | ADDVP_ExcludeFromCfgUI // and is not expected to be used in combination with ADDVP_AddToProjectWindow flag. *********************************/ ADDVP_NotSelectProject = 0x00000200 // Indicate not selecting the project node in solution. }; typedef DWORD VSADDVPFLAGS4;