vsl deep dive

32
1 VSL Deep Dive Josh Heitzman - Senior Software Design Engineer

Upload: jasia

Post on 31-Jan-2016

129 views

Category:

Documents


1 download

DESCRIPTION

VSL Deep Dive. Josh Heitzman - Senior Software Design Engineer. VSL 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. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: VSL Deep Dive

1

VSL Deep Dive

Josh Heitzman - Senior Software Design Engineer

Page 2: VSL Deep Dive

2

VSL 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

Page 3: VSL Deep Dive

3

VSL 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

Page 4: VSL Deep Dive

4

Resources

<SDK Root>\VisualStudioIntegration\Common\Source\CPP\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?forumid=57&siteid=1•Prefix post title with “VSL”

Feedback/Suggestions:http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=123359&SiteID=1

Blog:http://blogs.msdn.com/josh_heitzman/

Page 5: VSL Deep Dive

5

VSL 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

Page 6: VSL Deep Dive

6

Minimize 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.

template<

class Derived_T,

class VsSiteCache_T = VsSiteCacheLocal>

class IVsWindowPaneImpl :

public IVsWindowPane

template <class Derived_T>

class IExtensibleObjectImpl :

public IExtensibleObject

Page 7: VSL Deep Dive

7

Avoid 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);

};

Page 8: VSL Deep Dive

8

Exploit 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 <class Type_T, size_t NumberOfElements_T>class StaticArray{ C_ASSERT( NumberOfElements_T > 0);…__if_exists(Derived_T::GetViewObject){__if_exists(Derived_T:: GetLocalRegistryCLSIDViewObject) { // Can't speceify both an object and // a clsid C_ASSERT(0); } pViewObject = rDerived.GetViewObject();}…

Page 9: VSL Deep Dive

9

Resource Allocation Is Initialization (RAII)

RAII is used with all resources to ensure their lifetime is properly managed in the face of exceptions.

template <...>class Resource{ ResourceType m_Resource; Resource(): m_Resource(Values::GetNullValue()) {} Resource(ResourceType resource): m_Resource(resource) {} ~Resource() { Free(); } void Free(); ResourceType Detach(); operator CastType() const;};

Page 10: VSL Deep Dive

10

eXtendened Resource Allocation Is Initialization (XRAII)

RAII is extended to any set of calls that need balancing.

class Suspend{ Suspend(This& rThis): m_rThis(rThis) { m_rThis.SendMessage(WM_SETREDRAW, FALSE, 0); m_dwMaskToRestore = static_cast<DWORD>(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;};

Page 11: VSL Deep Dive

11

Facilitate 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

CursorCursorMockFileFileMockKeyboardKeyboardMockWindowWindowMock

Page 12: VSL Deep Dive

12

Re-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

Page 13: VSL Deep Dive

13

Responsive 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 won’t be a lot of BCs with any given release

Page 14: VSL Deep Dive

14

VSL 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

Page 15: VSL Deep Dive

15

Error 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();

Page 16: VSL Deep Dive

16

Unit 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 ATL::CWindow

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 VSL::FailureCounter::Get();

}

Page 17: VSL Deep Dive

17

Functors and delegates

Classes:•Functor•FunctionPointerFunctor•MemberFunctionPointerFunctor•Delegate

Header Files:•VSLCommon.h

FunctionPointerFunctor<void ()>

functor(&OnEvent1);

Delegate<void ()> event1;

event1 += functor;

event1();

event1 -= functor();

Page 18: VSL Deep Dive

18

Comparing various things

•Implemented primarily for the interface mocks•IsStringLessThen can be used with STL algorithms

•Header files:•VSLComparison.h

Page 19: VSL Deep Dive

19

Managing resources

Policy based resource managers:•Pointer•Resource

Header files:•VSLCommon.h•VSLFont.h

typedef Pointer<CoTaskMemPointerTraits> CoTaskMemPointer;

CoTaskMemPointer pBuffer = ::CoTaskMemAlloc(iBufferByteSize);

CHKPTR(static_cast<LPVOID>(pBuffer), E_OUTOFMEMORY);

CHK(0 == ::memcpy_s(pBuffer, iBufferByteSize, GetFileName(), iBufferByteSize), E_FAIL);

*ppszFilename = static_cast<LPOLESTR>(pBuffer.Detach());

Page 20: VSL Deep Dive

20

The basics necessary to create a VS Package

Classes:•IVsPackageImpl•IVsInstalledProductImpl

Registry map macros

Header files:•VSLPackage.h

class Package :

public IVsPackageImpl<

Package,

&CLSID_Package>,

public IVsInstalledProductImpl<

IDS_PRODUCT_NAME,

IDS_PRODUCT_IDENTIFIER,

IDS_PRODUCT_DETAILS,

IDI_ LOGO>

{

VSL_BEGIN_REGISTRY_MAP(IDR_PACKAGE_RGS)

...

VSL_END_REGISTRY_MAP()

Page 21: VSL Deep Dive

21

VsSiteCache

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 - VsIServiceProviderUtilities<>::QueryService•VSQCS - VsIServiceProviderUtilities<>::QueryCachedService

IVsPaneWindow uses the local VsSiteCache by default•Once window is sited can correctly get context sensitive services like SID_STrackSelection and SID_SVsWindowFrame

Page 22: VSL Deep Dive

22

Command handling

Classes:•IOleCommandTargetImpl•Command map macros•VsFontCommandHandling

Header files:•VSLCommandTarget.h

Samples:•Menus and Commands•Services•Tool Window•Single View Editor

class MenuAndCommandsPackage : ... public IOleCommandTargetImpl< MenuAndCommandsPackage>,...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()...

Page 23: VSL Deep Dive

23

VS Service consumption

Wrapped VS Services:•VsOutputWindowUtilities•ProfferServiceUtilities•OleComponentUIManagerUtilities

Can use global or local VsSiteCache.

OleComponentUIManagerUtilities<>::ShowMessage(

L"Title",

L"Message");

Header files:•VSLPackage.h

Samples:•Menus and Command•Services•Tool Window•Single View Editor

Page 24: VSL Deep Dive

24

Creating a VS Window that hosts a dialog

Classes:•IVsWindowPaneImpl•Window•VsWindowPaneFromResource

Header files:•VSLWindows.h

class Form :

public VsWindowPaneFromResource<

Form,

MAKEINTRESOURCE(IDD_DLG)>

Page 25: VSL Deep Dive

25

Creating a VS Window that hosts a Win32 control

Classes:•IVsWindowPaneImpl•Window•ListViewWin32Control•RichEditWin32Control•Win32ControlContainer

Header files:•VSLControls.h•VSLWindows.h

class Document :

public Win32ControlContainer<

RichEditWin32Control<> >

class Report :

public Win32ControlContainer<

ListViewWin32Control<

ReportViewTraits<

false,

false> > >

Page 26: VSL Deep Dive

26

Fully integrating a VS Window

Classes•VsWindowFrameEventSink•ISelectionContainerImpl•ISelectionContainerSingleItemImpl

Header files•VSLWindows.h

class WindowPane :

public IVsWindowPaneImpl<WindowPane>,

public VsWindowFrameEventSink<WindowPane>,

public ISomeInterface,

public ISelectionContainerSingleItemImpl<

WindowPane,

ISomeInterface>

Page 27: VSL Deep Dive

27

Creating a VS Document / VS Editor

Classes:•IVsEditorFactoryImpl•IVsFindTargetImpl•SingleViewFindInFilesOutputWindowIntegrationImpl•File•DocumentPersistanceBase

Header Files:•VSLFile.h•VSLFindAndReplace.h•VSLWindow.h

Samples:•Single View Editor

Page 28: VSL Deep Dive

28

Automation 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);

}

}

Page 29: VSL Deep Dive

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

Page 30: VSL Deep Dive

30

Miscellaneous Win32 Resource Managers/Wrappers

Classes:•Library – HMODULE’s from ::LoadLibrary•DeviceContext – HDC’s 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/destructor)•DeviceContext only has EnumFontFamiliesExW•Cursor only has Activate•Keyboard only has IsKeyDown

Page 31: VSL Deep Dive

31

Data 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?

Page 32: VSL Deep Dive

32

Data Collection continued

•Plan to migrate existing C++ package to managed?•C++/CLI?•C#?•Other?•Over what time frame?