Title: VSL Deep Dive
1VSL Deep Dive
- Josh Heitzman - Senior Software Design Engineer
2VSL is
- Acronym for Visual Studio Library
- Modern C library targeting the Visual Studio
Platform. - Styled after ATL and WTL.
- Comprised only of header files. No binaries.
- Extensible and customizable (macros can be
overriden to change core behavior). - Not a framework like MFC, MPF, .Net Framework,
etc.. - Not a complete offering for the entire VS Platform
3VSL Effect
Code Lines Comment Lines Characters Semi-colons Functions
Feature equivalent
C Tool Window 828 508 53,858 228 34
C Tool Window 844 724 63,686 433 49
C Menus Commands 178 222 18,996 38 11
C Menus Commands 227 201 20,498 90 10
C Services 315 320 28,230 78 15
C Services 270 289 26,773 101 13
C Single View Editor 2,653 1,203 130,689 879 142
C Single View Editor 3,253 1,620 251,990 1,147 276
Not feature equivalent
C Package 81 201 13,648 7 3
C Package 204 261 22,284 72 17
4Resources
- ltSDK Rootgt\VisualStudioIntegration\Common\Source\C
PP\VSL - VSLArchitecture.htm class diagrams
- Include VSL header files
- MockInterfaces Windows and Visual Studio
Platform Interface mocks - UnitTest\VSLUnitTest.sln solution with all of
the VSL unit tests. - Questions/Issues
- http//forums.microsoft.com/msdn/showforum.aspx?fo
rumid57siteid1 - Prefix post title with VSL
- Feedback/Suggestions
- http//forums.microsoft.com/MSDN/ShowPost.aspx?Pos
tID123359SiteID1 - Blog
- http//blogs.msdn.com/josh_heitzman/
5VSL Design Principles
- Minimize coupling
- Avoid feature creep
- Exploit the C language and the Microsoft Visual
C compiler - Facilitate unit testing
- Re-use without obstruction
- Responsive to requests
6Minimize coupling
- Narrowly scoping the functionality of classes
- Implement one interface
- Wrap one VS Service
- Wrap one related set of Win32 APIs
- Use of C templates to reduce hard dependencies
between classes.
- templatelt
- class Derived_T,
- class VsSiteCache_T VsSiteCacheLocalgt
- class IVsWindowPaneImpl
- public IVsWindowPane
- template ltclass Derived_Tgt
- class IExtensibleObjectImpl
- public IExtensibleObject
7Avoid feature creep
- Only the functionality required for the task at
hand is implemented. - Avoid investing resources in features that may
not be needed.
- class VsOutputWindowUtilities
-
- void
- OutputMessage(
- const wchar_t const szMessage)
- void
- OutputMessageWithPreAndPostBarsOfEquals(
- const wchar_t const szMessage)
-
8Exploit the C language and the Visual C
compiler
- When possible, fail at compile time rather then
runtime - Make use of C exceptions
- Use C templates and when necessary C
pre-processor macros to minimize code redundancy
and maximize reuse - Use of an extended version of the Resource
Allocation Is Initialization paradigm
- template lt
- class Type_T,
- size_t NumberOfElements_Tgt
- class StaticArray
-
- C_ASSERT(
- NumberOfElements_T gt 0)
-
- __if_exists(Derived_TGetViewObject)
-
- __if_exists(Derived_T
- GetLocalRegistryCLSIDViewObject)
-
- // Can't speceify both an object and
- // a clsid
- C_ASSERT(0)
-
- pViewObject
- rDerived.GetViewObject()
9Resource Allocation Is Initialization (RAII)
- RAII is used with all resources to ensure their
lifetime is properly managed in the face of
exceptions.
- template lt...gt
- class Resource
-
- ResourceType m_Resource
- Resource()
- m_Resource(ValuesGetNullValue())
-
- Resource(ResourceType resource)
- m_Resource(resource)
-
- Resource()
-
- Free()
-
- void Free()
- ResourceType Detach()
- operator CastType() const
10eXtendened Resource Allocation Is Initialization
(XRAII)
- class Suspend
-
- Suspend(This rThis)
- m_rThis(rThis)
-
- m_rThis.SendMessage(WM_SETREDRAW, FALSE,
0) - m_dwMaskToRestore
- static_castltDWORDgt(m_rThis.SendMessage(
- EM_SETEVENTMASK, 0, ENM_NONE))
-
- SuspendDrawAndNotifications()
-
- m_rThis.SendMessage(
- EM_SETEVENTMASK, 0, m_dwMaskToRestore)
- m_rThis.SendMessage(WM_SETREDRAW, TRUE, 0)
-
- This m_rThis
- DWORD m_dwMaskToRestore
-
- RAII is extended to any set of calls that need
balancing.
11Facilitate unit testing
- Mocks for nearly all VS Platform interfaces
- Mocks for many Windows Platform interfaces
- Wrapper classes around some sets of Win32 APIs
- Mocks for those classes
- Cursor
- CursorMock
- File
- FileMock
- Keyboard
- KeyboardMock
- Window
- WindowMock
12Re-use without obstruction
- Many classes take template parameters
- Allows you to provide your own custom
implementation for a dependency - Some template defaults will be correct for 99 of
cases - A couple of classes using policy based design
- a smart pointer and a smart resource
- Optional statically bound call backs into a
derived class - This is accomplished via __if_exists and
__if_notexists - Numerous macros that can be overridden
13Responsive to requests
- VS SDK release cycle is short
- CTP monthly
- RTW every 4 months
- Designs are never perfect the first time
- Even more so when on short cycle
- Breaking changes will be made as the demand
arises - Short cycle means there wont be a lot of BCs
with any given release
14VSL provides help with
- Error and exception handling
- Unit testing
- Functors and delegates
- Comparing various things
- Managing resources
- The basics necessary to create a VS Package
- Command handling
- VS Service consumption
- Creating a VS Window that hosts a dialog or Win32
control - Creating a VS Document / VS Editor
- Automation and VS Macro recording
- VS Hierarchies
15Error and exception handling
- Error handling macros that convert errors to
exceptions - Exception handling macros that catch and convert
exceptions to HRESULTs - VSL_BEGIN_MSG_MAP message map that catches
exceptions - Header files
- VSLErrorHandlers.h
- VSLExceptionHandlers.h
- VSL_STDMETHODTRY
- VSL_CHECKHANDLE_GLE(GetDC(hWnd))
- VSL_STDMETHODCATCH()
- return VSL_GET_STDMETHOD_HRESULT()
16Unit testing
- Unit testing framework
- Mocks for nearly all VS Platform interfaces
- Mocks for many Windows Platform interfaces
- Mocks for wrapper classes around some sets of
Win32 APIs - Including some of ATLCWindow
- Header files
- VSLUnitTest.h
- class UnitTest
- public UnitTestBase
-
- UnitTest(
- const char const szTestName)
- UnitTestBase(szTestName)
-
- UTCHK(false)
-
-
- int _cdecl _tmain(int, _TCHAR)
-
- UTRUN(UnitTest)
- return VSLFailureCounterGet()
17Functors and delegates
- Classes
- Functor
- FunctionPointerFunctor
- MemberFunctionPointerFunctor
- Delegate
- Header Files
- VSLCommon.h
- FunctionPointerFunctorltvoid ()gt
- functor(OnEvent1)
- Delegateltvoid ()gt event1
- event1 functor
- event1()
- event1 - functor()
18Comparing various things
- Implemented primarily for the interface mocks
- IsStringLessThen can be used with STL algorithms
- Header files
- VSLComparison.h
19Managing resources
- Policy based resource managers
- Pointer
- Resource
- Header files
- VSLCommon.h
- VSLFont.h
- typedef PointerltCoTaskMemPointerTraitsgt
CoTaskMemPointer - CoTaskMemPointer pBuffer CoTaskMemAlloc(iBuffe
rByteSize) - CHKPTR(static_castltLPVOIDgt(pBuffer),
E_OUTOFMEMORY) - CHK(0 memcpy_s(pBuffer, iBufferByteSize,
GetFileName(), iBufferByteSize), E_FAIL) - ppszFilename static_castltLPOLESTRgt(pBuffer.Deta
ch())
20The basics necessary to create a VS Package
- Classes
- IVsPackageImpl
- IVsInstalledProductImpl
- Registry map macros
- Header files
- VSLPackage.h
- class Package
- public IVsPackageImpllt
- Package,
- CLSID_Packagegt,
- public IVsInstalledProductImpllt
- IDS_PRODUCT_NAME,
- IDS_PRODUCT_IDENTIFIER,
- IDS_PRODUCT_DETAILS,
- IDI_ LOGOgt
-
- VSL_BEGIN_REGISTRY_MAP(IDR_PACKAGE_RGS)
- ...
- VSL_END_REGISTRY_MAP()
21VsSiteCache
- Can be local or global
- IVsPackageImpl uses the global VsSiteCache by
default - Once a package is sited anything can then use the
global cache by creating an instance of
VsSiteCacheGlobal or utilizing the static methods
of VsIServiceProviderUtilities directly or via
the macros - VSQS - VsIServiceProviderUtilitiesltgtQueryService
- VSQCS - VsIServiceProviderUtilitiesltgtQueryCached
Service - IVsPaneWindow uses the local VsSiteCache by
default - Once window is sited can correctly get context
sensitive services like SID_STrackSelection and
SID_SVsWindowFrame
22Command handling
- Classes
- IOleCommandTargetImpl
- Command map macros
- VsFontCommandHandling
- Header files
- VSLCommandTarget.h
- Samples
- Menus and Commands
- Services
- Tool Window
- Single View Editor
- class MenuAndCommandsPackage
- ...
- public IOleCommandTargetImpllt
MenuAndCommandsPackagegt, - ...
- VSL_BEGIN_COMMAND_MAP()
- VSL_COMMAND_MAP_ENTRY(
- GUID_MenuAndCommandsCmdSet,
- cmdidMyCommand, NULL,
- MenuCommandCallback)
- VSL_COMMAND_MAP_ENTRY_WITH_FLAGS(
- GUID_MenuAndCommandsCmdSet,
- cmdidDynVisibility2, NULL,
- MenuVisibilityCallback,
- OLECMDF_SUPPORTED OLECMDF_ENABLED
- OLECMDF_INVISIBLE)
- VSL_END_VSCOMMAND_MAP()
- ...
23VS Service consumption
- Header files
- VSLPackage.h
- Samples
- Menus and Command
- Services
- Tool Window
- Single View Editor
- Wrapped VS Services
- VsOutputWindowUtilities
- ProfferServiceUtilities
- OleComponentUIManagerUtilities
- Can use global or local VsSiteCache.
- OleComponentUIManagerUtilitiesltgtShowMessage(
- L"Title",
- L"Message")
24Creating a VS Window that hosts a dialog
- Classes
- IVsWindowPaneImpl
- Window
- VsWindowPaneFromResource
- Header files
- VSLWindows.h
- class Form
- public VsWindowPaneFromResourcelt
- Form,
- MAKEINTRESOURCE(IDD_DLG)gt
25Creating a VS Window that hosts a Win32 control
- Classes
- IVsWindowPaneImpl
- Window
- ListViewWin32Control
- RichEditWin32Control
- Win32ControlContainer
- Header files
- VSLControls.h
- VSLWindows.h
- class Document
- public Win32ControlContainerlt
- RichEditWin32Controlltgt gt
- class Report
- public Win32ControlContainerlt
- ListViewWin32Controllt
- ReportViewTraitslt
- false,
- falsegt gt gt
26Fully integrating a VS Window
- Classes
- VsWindowFrameEventSink
- ISelectionContainerImpl
- ISelectionContainerSingleItemImpl
- Header files
- VSLWindows.h
- class WindowPane
- public IVsWindowPaneImplltWindowPanegt,
- public VsWindowFrameEventSinkltWindowPanegt,
- public ISomeInterface,
- public ISelectionContainerSingleItemImpllt
- WindowPane,
- ISomeInterfacegt
27Creating a VS Document / VS Editor
- Classes
- IVsEditorFactoryImpl
- IVsFindTargetImpl
- SingleViewFindInFilesOutputWindowIntegrationImpl
- File
- DocumentPersistanceBase
- Header Files
- VSLFile.h
- VSLFindAndReplace.h
- VSLWindow.h
- Samples
- Single View Editor
28Automation and VS Macro recording
- Classes
- IExtensibleObjectImpl
- VsMacroRecorder
- Header Files
- VSLAutomation.h
- Samples
- Single View Editor
- void RecordCommand(
- wchar_t szCommand)
-
- if(m_Recorder.IsRecording(
- GetVsSiteCache()))
-
- CStringW strLine
- L"ActiveDocument.Object."
- strLine szCommand
- m_Recorder.RecordLine(
- strLine)
-
29- Classes
- IVsHierarchyImpl
- IVsUIHierarchyImpl
- IVsHierarchyEventsDelegate
- VsHierarchyRootItemBase
- VsHierarchyItemBase
- VsUIHierarchyItemBase
- VsHierarchyRootItemBase
- HierarchyNode
- C Interfaces
- IVsHierarchyItem
- IVsUIHierarchyItem
- IVsHierarchyRootItem
- IVsUIHierarchyRootItem
- Header Files
- VSLHierarchy.h
- VSLHierarchyNode.h
- Samples
- Extensiblity Explorer
30Miscellaneous Win32 Resource Managers/Wrappers
- Classes
- Library HMODULEs from LoadLibrary
- DeviceContext HDCs from GetDC
- Cursor HCURSOR from LoadCursor
- Keyboard
- These classes only provide what was necessary for
the reference samples, but can be easily expanded
as needed. For example - Library has no methods (just constructor/destructo
r) - DeviceContext only has EnumFontFamiliesExW
- Cursor only has Activate
- Keyboard only has IsKeyDown
31Data Collection
- Do you
- Have existing packages written in C?
- Use VSL in C packages?
- Plan to use VSL in C packages in the future?
- Unit test existing C packages?
- Use VSL for unit testing C packages?
- Plan to use VSL for unit testing C packages in
the future? - Plan to write new packages in C in the future?
- What kind of package (project system, editor,
designer, etc.)? - Plan to expand add additional features in C?
- What type of features?
- Want better tools for creating scenario tests?
- Want sample scenario tests?
32Data Collection continued
- Plan to migrate existing C package to managed?
- C/CLI?
- C?
- Other?
- Over what time frame?