Skip to content

Commit

Permalink
Added CTime & CTimeSpan visualizers.
Browse files Browse the repository at this point in the history
Pulled a couple of repeated LOC into SystemTimeToVisualizerFormattedString.
Updated to C++17 to use optional.
  • Loading branch information
David-FromVS authored and David-FromVS committed Jan 1, 2021
1 parent 851eac2 commit 70a87aa
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 44 deletions.
3 changes: 3 additions & 0 deletions CppCustomVisualizer/DavesCustomVisualizer.sln
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vsix", "vsix\vsix.vcxproj", "{0E22D156-940B-431D-945D-51B7DFA08AEF}"
ProjectSection(ProjectDependencies) = postProject
{B78603F6-45FD-4824-95ED-294012F08895} = {B78603F6-45FD-4824-95ED-294012F08895}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DavesCustomVisualizer", "dll\DavesCustomVisualizer.vcxproj", "{B78603F6-45FD-4824-95ED-294012F08895}"
EndProject
Expand Down
16 changes: 8 additions & 8 deletions CppCustomVisualizer/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Dave's Visual Studio Debugger Visualizer
This is an enhanced version of the CppCustomVisualizer in the [Microsoft Concord Extensibility Sample](https://github.com/Microsoft/ConcordExtensibilitySamples/wiki/Cpp-Custom-Visualizer-Sample). It currently supports the following Windows types:
This is an enhanced version of the CppCustomVisualizer in the [Microsoft Concord Extensibility Sample](https://github.com/Microsoft/ConcordExtensibilitySamples/wiki/Cpp-Custom-Visualizer-Sample). It currently supports the following Windows SDK and ATL class types:

#### FILETIME
Displays both UTC & local time in the current locale format.

#### SYSTEMTIME
Displays the literal time in the current locale format.
#### FILETIME, SYSTEMTIME, COleDateTime, CTime
Displays the time value interpreted as both UTC and local time, shown in your current locale format.

#### PROPERTYKEY
Displays the key's canonical and display names.

Variables of these types are normally displayed in the debugger in raw number form, but as you can see in the following example, with this extension they're displayed in more useful forms:
#### CTimeSpan
Displays the time value as Days, Hours, Minutes, and Seconds.

Variables of the above types are normally displayed in the debugger in raw number form, but as you can see in the following example, with this extension they're displayed in more useful forms:

![Demonstration animation](demo.gif)

Expand All @@ -25,7 +25,7 @@ Natvis documentation can be found on [docs.microsoft.com](https://docs.microsoft
### dll folder

#### _EntryPoint.cpp
Defined new GUIDs for the 3 type visualizers & calls the appropriate converter when the matching GUID is passed (*from the debugger*).
Defined new GUIDs for the type visualizers & calls the appropriate converter when the matching GUID is passed (*from the debugger*).

#### FileAndSystemTimeViz.cpp/.h
Converter for FILETIME & SYSTEMTIME -> String
Expand Down
5 changes: 5 additions & 0 deletions CppCustomVisualizer/TargetApp/TargetApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ int wmain(int argc, WCHAR* argv[])
// Another in winter time
COleDateTime dtWinter(dt.GetYear(), 12, 25, 4, 5, 6);

CTimeSpan tspan( 1, 2, 3, 4 );
tspan.GetDays();

CString str = dt.Format();

FILETIME ft;
Expand All @@ -52,6 +55,8 @@ int wmain(int argc, WCHAR* argv[])

SystemTimeToFileTime( &st, &ft );

CTime tim( ft );

// Now get the local time
SYSTEMTIME lst;
SystemTimeToTzSpecificLocalTime( nullptr, &st, &lst );
Expand Down
5 changes: 3 additions & 2 deletions CppCustomVisualizer/dll/CppCustomVisualizer.vsdconfigxml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ For more information about this file, see https://github.com/Microsoft/ConcordEx
<VisualizerId RequiredValue="1AC4A977-2954-4316-8CE6-A6251EEBA144"/>
<!--PROPERTYKEY-->
<VisualizerId RequiredValue="47D01893-3FA1-4326-9ED2-5236246CF231"/>
<!--time_t Ineffective, no unique struct definition
<!--CTimeSpan-->
<VisualizerId RequiredValue="C7B69925-4654-434D-A657-631AAB40BB82"/>
-->
<!--CTime-->
<VisualizerId RequiredValue="6873613E-3521-4D77-B530-70477A6AEF51"/>
</Filter>
<Interface Name="IDkmCustomVisualizer"/>
</InterfaceGroup>
Expand Down
10 changes: 6 additions & 4 deletions CppCustomVisualizer/dll/DavesCustomVisualizer.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ For information about natvis files see: https://docs.microsoft.com/en-us/visuals
<Type Name="_tagpropertykey">
<CustomVisualizer VisualizerId="47D01893-3FA1-4326-9ED2-5236246CF231"/>
</Type>
<!--
Ineffective, no unique struct definition
<Type Name="__time64_t">

<Type Name="ATL::CTimeSpan">
<CustomVisualizer VisualizerId="C7B69925-4654-434D-A657-631AAB40BB82"/>
</Type>
-->
<Type Name="ATL::CTime">
<CustomVisualizer VisualizerId="6873613E-3521-4D77-B530-70477A6AEF51"/>
</Type>

<Type Name="ATL::COleDateTime">
<!--<CustomVisualizer Condition="m_status == DateTimeStatus::valid" VisualizerId="C27383FF-1889-4959-A0E4-99DB41295CB3"/>-->
<CustomVisualizer VisualizerId="C27383FF-1889-4959-A0E4-99DB41295CB3"/>
Expand Down
8 changes: 8 additions & 0 deletions CppCustomVisualizer/dll/DavesCustomVisualizer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<CharacterSet>Unicode</CharacterSet>
<NugetPackagesDirectory>$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\packages\))</NugetPackagesDirectory>
<ProjectName>DavesCustomVisualizer</ProjectName>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="packages.version.props" />
<Import Project="..\Cpp.props" />
Expand Down Expand Up @@ -78,6 +79,9 @@
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgEnabled>false</VcpkgEnabled>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
Expand All @@ -86,6 +90,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand All @@ -111,6 +116,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand All @@ -134,6 +140,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand All @@ -159,6 +166,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand Down
17 changes: 16 additions & 1 deletion CppCustomVisualizer/dll/FileAndSystemTimeViz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include "stdafx.h"
#include <optional>
using std::optional;
#include "FileAndSystemTimeViz.h"

CString FormatSystemTime( const SYSTEMTIME& st )
static CString FormatSystemTime( const SYSTEMTIME& st )
{
TCHAR szDate[50];

Expand Down Expand Up @@ -113,3 +115,16 @@ CString FileTimeToText( const FILETIME& ftUtc, UINT nBase )
}
return text;
}

optional<CString> SystemTimeToVisualizerFormattedString( const SYSTEMTIME& st, UINT Radix )
{
optional<CString> sRet;

FILETIME ft;
if ( SystemTimeToFileTime( &st, &ft ) )
{
sRet = FileTimeToText( ft, Radix );
}

return sRet;
}
5 changes: 4 additions & 1 deletion CppCustomVisualizer/dll/FileAndSystemTimeViz.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#pragma once

extern CString FormatSystemTime( const SYSTEMTIME& st );
#include <optional>

//extern CString FormatSystemTime( const SYSTEMTIME& st );
extern CString FileTimeToText( const FILETIME& ftUtc, UINT nBase );
std::optional<CString> SystemTimeToVisualizerFormattedString( const SYSTEMTIME& st, UINT Radix );
68 changes: 42 additions & 26 deletions CppCustomVisualizer/dll/_EntryPoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ DEFINE_GUID( SYSTEMTIME_VIZ_ID, 0x1ac4a977, 0x2954, 0x4316, 0x8c, 0xe6, 0xa6, 0x
DEFINE_GUID( PROPKEY_VIZ_ID, 0x47d01893, 0x3fa1, 0x4326, 0x9e, 0xd2, 0x52, 0x36, 0x24, 0x6c, 0xf2, 0x31 );

// {C7B69925-4654-434D-A657-631AAB40BB82}
//DEFINE_GUID( TIME_T_VIZ_ID, 0xc7b69925, 0x4654, 0x434d, 0xa6, 0x57, 0x63, 0x1a, 0xab, 0x40, 0xbb, 0x82 );
DEFINE_GUID( CTimeSpan_VIZ_ID, 0xc7b69925, 0x4654, 0x434d, 0xa6, 0x57, 0x63, 0x1a, 0xab, 0x40, 0xbb, 0x82 );

// {6873613E-3521-4D77-B530-70477A6AEF51}
DEFINE_GUID( CTime_VIZ_ID, 0x6873613e, 0x3521, 0x4d77, 0xb5, 0x30, 0x70, 0x47, 0x7a, 0x6a, 0xef, 0x51 );

// {C27383FF-1889-4959-A0E4-99DB41295CB3}
DEFINE_GUID( COleDateTime_VIZ_ID,
Expand Down Expand Up @@ -86,17 +89,10 @@ HRESULT STDMETHODCALLTYPE CCppCustomVisualizerService::EvaluateVisualizedExpress
}

// Convert to FILETIME (UTC) to pass to the string conversion that shows both UTC & local
FILETIME ft;
if ( SystemTimeToFileTime( &value, &ft ) )
{
strValue = FileTimeToText( ft, pRootVisualizedExpression->InspectionContext()->Radix() );
}
auto sv = SystemTimeToVisualizerFormattedString( value, pRootVisualizedExpression->InspectionContext()->Radix() );

// An empty returned string indicates an invalid SYSTEMTIME
if ( strValue.IsEmpty() )
{
strValue = _T( "Invalid" );
}
strValue = sv.has_value() ? *sv : _T( "Invalid" );
}
else if ( vizId == PROPKEY_VIZ_ID )
{
Expand All @@ -112,31 +108,51 @@ HRESULT STDMETHODCALLTYPE CCppCustomVisualizerService::EvaluateVisualizedExpress
// Format as a string
strValue = GetKeyName( value );
}
#if 0 //Ineffective, no unique struct definition
else if ( vizId == TIME_T_VIZ_ID)
else if ( vizId == CTimeSpan_VIZ_ID)
{
// Read the time_t value from the target process
time_t value;
// Read the value from the target process
CTimeSpan value;
hr = pTargetProcess->ReadMemory( pPointerValueHome->Address(), DkmReadMemoryFlags::None, &value, sizeof( value ), nullptr );
if ( FAILED( hr ) )
{
// If the bytes of the value cannot be read from the target process, just fall back to the default visualization
return E_NOTIMPL;
}

// Format as a string
strValue = value.Format( _T("%Dd %Hh %Mm %Ss") );
}
else if ( vizId == CTime_VIZ_ID )
{
// Read the value from the target process
CTime value;
hr = pTargetProcess->ReadMemory( pPointerValueHome->Address(), DkmReadMemoryFlags::None, &value, sizeof( value ), nullptr );
if ( FAILED( hr ) )
{
// If the bytes of the value cannot be read from the target process, just fall back to the default visualization
return E_NOTIMPL;
}

// Convert -> SYSTEMTIME -> FILETIME in order to use the FILETIME string output function
SYSTEMTIME st;
if ( value.GetAsSystemTime( st ) )
{
auto ostrVal = SystemTimeToVisualizerFormattedString( st, pRootVisualizedExpression->InspectionContext()->Radix() );

if ( ostrVal.has_value() )
{
strValue = *ostrVal;
}
}

// An empty returned string indicates an invalid SYSTEMTIME
if ( strValue.IsEmpty() )
{
tm tmm;
gmtime_s( &tmm, &value );
char buffer[100];
asctime_s( buffer, &tmm );
strValue = buffer;
strValue = _T("Invalid");
}
}
#endif
else if ( vizId == COleDateTime_VIZ_ID )
{
/*ATL::*/COleDateTime value;
COleDateTime value;

hr = pTargetProcess->ReadMemory( pPointerValueHome->Address(), DkmReadMemoryFlags::None, &value, sizeof( value ), nullptr );
if ( FAILED( hr ) )
Expand All @@ -149,11 +165,11 @@ HRESULT STDMETHODCALLTYPE CCppCustomVisualizerService::EvaluateVisualizedExpress
SYSTEMTIME st;
if ( value.GetAsSystemTime( st ) )
{
// Convert to FILETIME (UTC) to pass to the string conversion that shows both UTC & local
FILETIME ft;
if ( SystemTimeToFileTime( &st, &ft ) )
auto ostrVal = SystemTimeToVisualizerFormattedString( st, pRootVisualizedExpression->InspectionContext()->Radix() );

if ( ostrVal.has_value() )
{
strValue = FileTimeToText( ft, pRootVisualizedExpression->InspectionContext()->Radix() );
strValue = *ostrVal;
}
}

Expand Down
2 changes: 1 addition & 1 deletion CppCustomVisualizer/vsix/source.extension.vsixmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Description xml:space="preserve">Win32 Debug Visualizers</Description>
<MoreInfo>https://github.com/Dave-Lowndes/DavesVisualStudioVisualizers/tree/master/CppCustomVisualizer</MoreInfo>
<ReleaseNotes>https://github.com/Dave-Lowndes/DavesVisualStudioVisualizers/tree/master/CppCustomVisualizer</ReleaseNotes>
<Tags>FILETIME;SYSTEMTIME;PROPERTYKEY;COleDateTime</Tags>
<Tags>FILETIME;SYSTEMTIME;PROPERTYKEY;COleDateTime,CTime,CTimeSpan</Tags>
<Version>2.0</Version>
</Metadata>
<Installation>
Expand Down
5 changes: 4 additions & 1 deletion CppCustomVisualizer/vsix/vsix.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,17 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgEnabled>false</VcpkgEnabled>
</PropertyGroup>
<ItemGroup>
<None Include="Build-x64.targets" />
<None Include="source.extension.vsixmanifest">
<SubType>Designer</SubType>
</None>
<None Include="VSIXSourceItems.props" />
</ItemGroup>
<Import Project="VSIXSourceItems.props"/>
<Import Project="VSIXSourceItems.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
Expand Down

0 comments on commit 70a87aa

Please sign in to comment.