<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Asim Goheer's Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/asim_goheer/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/asim_goheer/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 04:09:26 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Creating a log file in Windows Runtime using C++</title>
      <link>https://docs.microsoft.com/archive/blogs/asim_goheer/creating-a-log-file-in-windows-runtime-using-c</link>
      <pubDate>Sat, 01 Nov 2014 15:26:00 GMT</pubDate>
      <dc:creator><![CDATA[Asim Goheer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/asim_goheer/2014/11/01/creating-a-log-file-in-windows-runtime-using-c/</guid>
      <description><![CDATA[If you have a native C++ project running on Windows Runtime AND you want to do some logging then you...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: verdana,geneva; font-size: small;">If you have a native C++ project running on Windows Runtime AND you want to do some logging then you are in for a surprise. You cannot simply open a file "C:\log.txt" and dump all your logs there. You have to use Windows Runtime APIs to create files and write to them. Since Windows Runtime APIs are mostly Async you will jump through different hoops to get there.</span></p>
<p><span style="font-family: verdana,geneva; font-size: small;">This class will allow you to create a temp file and it will allow you write formatted output to the file. You can do things like ".Write( L"param %d", parameter1 );" </span></p>
<p><span style="font-family: verdana,geneva; font-size: small;">It's very easy to use this class, simply create an instance and call Register in the constructor of your App/Class. Then simply call Write/WriteLine to write to the log file. When you are done call UnRegister to close the file. Register/UnRegister functions are there to provide your class ref counting. This will be helpful when you have one global instance of this Logger but multiple classes are using it. In this scenario you only want to close &amp; flush the file when all classes using this logger are gone. So make sure to call Register/UnRegister in Constructor/Destructor respectively.</span></p>
<pre class="scroll"><code class="cplusplus">DebugLogger logger;<br />logger.Register();<br />logger.Write( L"param %d", 123 );<br />logger.UnRegister();</code></pre>
<p><span style="font-size: small; font-family: verdana,geneva;">Full Source code:<br /></span></p>
<pre class="scroll" style="background: #012456;"><code class="cplusplus"><span style="color: #ffffff;">#pragma once<br />/******************************************************************************<br />*<br />* Author: Asim Goheer<br />*<br />* DebugLogger will allow you to write logs to local folder in <br />* Windows Runtime C++ projects.<br />*<br />* This class will allow you to log everything to isolated storage(or local folder). Once all the <br />* logging is done it will do proper clean-up and release the file.<br />* <br />******************************************************************************/<br /><br /><br />#include &lt;wrl/async.h&gt;<br />#include "HStringOwner.h"<br />#include "CSOwner.h"<br />#include &lt;time.h&gt;<br /><br />class DebugLogger<br />{<br />public:<br />&nbsp;&nbsp; DebugLogger() : m_csNewLine( L"\r\n" )<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeCriticalSectionEx( &amp;m_critSec, 0, 0 );<br />&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp; virtual ~DebugLogger()<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DeleteCriticalSection( &amp;m_critSec );<br />&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp; void Register()<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CRITICAL_SECTION_OWNER( m_critSec );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( m_registerCount == 0 )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Init();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_registerCount++;<br />&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp; void UnRegister()<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( !m_pDataWriter )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Foundation::IAsyncOperation&lt; UINT32 &gt; &gt; pAsyncAction;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_pDataWriter-&gt;StoreAsync( &amp;pAsyncAction );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pAsyncAction-&gt;put_Completed( Microsoft::WRL::Callback&lt; ABI::Windows::Foundation::IAsyncOperationCompletedHandler&lt; UINT32 &gt; &gt;(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ this ] ( ABI::Windows::Foundation::IAsyncOperation&lt; UINT32 &gt;* pHandler, AsyncStatus status )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( !pHandler || status != AsyncStatus::Completed )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Foundation::IAsyncOperation&lt; bool &gt; &gt; pAsyncAction;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_pIIStream-&gt;FlushAsync( &amp;pAsyncAction );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pAsyncAction-&gt;put_Completed( Microsoft::WRL::Callback&lt; ABI::Windows::Foundation::IAsyncOperationCompletedHandler&lt; bool &gt; &gt;(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ this ] ( ABI::Windows::Foundation::IAsyncOperation&lt; bool &gt;* pHandler, AsyncStatus status )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( !pHandler || status != AsyncStatus::Completed )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CRITICAL_SECTION_OWNER( m_critSec );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_registerCount--;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( m_registerCount == 0 )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // close the file<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Foundation::IClosable &gt; pICloseable;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HRESULT hr = m_pDataWriter.As&lt; ABI::Windows::Foundation::IClosable &gt;( &amp;pICloseable );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( SUCCEEDED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pICloseable-&gt;Close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // close the file<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Foundation::IClosable &gt; pICloseable;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HRESULT hr = m_pIIStream.As&lt; ABI::Windows::Foundation::IClosable &gt;( &amp;pICloseable );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( SUCCEEDED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pICloseable-&gt;Close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // close the file<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Foundation::IClosable &gt; pICloseable;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HRESULT hr = m_randomAccessStream.As&lt; ABI::Windows::Foundation::IClosable &gt;( &amp;pICloseable );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( SUCCEEDED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pICloseable-&gt;Close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } ).Get() );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } ).Get() );<br />&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp; void WriteLine( wchar_t* wzString )<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( !m_pDataWriter )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CRITICAL_SECTION_OWNER( m_critSec );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HStringOwner csString( wzString );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UINT32 length = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HRESULT hr = m_pDataWriter-&gt;WriteString( csString, &amp;length );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; length = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hr = m_pDataWriter-&gt;WriteString( m_csNewLine, &amp;length );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp; void Write( wchar_t* fmt, ... )<br />&nbsp;&nbsp; {<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wchar_t szBuf[ 512 ];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; szBuf[ 0 ] = '\0';<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nSize = 0;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; va_list args;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; va_start( args, fmt );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nSize = _vsnwprintf_s( szBuf, _countof( szBuf ), _TRUNCATE, fmt, args ); // C4996<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; va_end( args );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriteLine( szBuf );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch( ... )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriteLine( L"Exception" );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp; }<br /><br />private:<br />&nbsp;&nbsp; void Init()<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CRITICAL_SECTION_OWNER( m_critSec );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( initDone )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; initDone = true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_logFileCreatedEvent.Attach( CreateEventEx( nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, WRITE_OWNER | EVENT_ALL_ACCESS ) );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( SUCCEEDED( CreateLogFile() ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WaitForSingleObjectEx( m_logFileCreatedEvent.Get(), INFINITE, FALSE );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp; void CreateLogFileError( HRESULT hr )<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetEvent( m_logFileCreatedEvent.Get() );<br />&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp; HRESULT CreateLogFile()<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Storage::IApplicationDataStatics &gt; applicationDataStatics;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HRESULT hr = Windows::Foundation::GetActivationFactory( Microsoft::WRL::Wrappers::HStringReference( RuntimeClass_Windows_Storage_ApplicationData ).Get(), &amp;applicationDataStatics );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return hr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Storage::IApplicationData &gt; applicationData;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hr = applicationDataStatics-&gt;get_Current( &amp;applicationData );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return hr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Storage::IStorageFolder &gt; storageFolder;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hr = applicationData-&gt;get_LocalFolder( &amp;storageFolder );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return hr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HStringOwner logFileName( L"log.txt" );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Foundation::IAsyncOperation&lt; ABI::Windows::Storage::StorageFile* &gt; &gt; pAsyncAction;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hr = storageFolder-&gt;CreateFileAsync( logFileName,&nbsp; ABI::Windows::Storage::CreationCollisionOption::CreationCollisionOption_ReplaceExisting, &amp;pAsyncAction );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return hr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pAsyncAction-&gt;put_Completed( Microsoft::WRL::Callback&lt; ABI::Windows::Foundation::IAsyncOperationCompletedHandler&lt; ABI::Windows::Storage::StorageFile* &gt; &gt;(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ this ] ( ABI::Windows::Foundation::IAsyncOperation&lt; ABI::Windows::Storage::StorageFile* &gt;* pHandler, AsyncStatus status )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( pHandler == nullptr || status != AsyncStatus::Completed )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CreateLogFileError( E_ABORT );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ABI::Windows::Storage::IStorageFile* pStorageFile = nullptr;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HRESULT hr = pHandler-&gt;GetResults( &amp;pStorageFile );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) || !pStorageFile )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CreateLogFileError( hr );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Foundation::IAsyncOperation&lt; ABI::Windows::Storage::Streams::IRandomAccessStream* &gt; &gt; pAsyncAction;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hr = pStorageFile-&gt;OpenAsync(&nbsp; ABI::Windows::Storage::FileAccessMode::FileAccessMode_ReadWrite, &amp;pAsyncAction );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CreateLogFileError( hr );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pAsyncAction-&gt;put_Completed( Microsoft::WRL::Callback&lt; ABI::Windows::Foundation::IAsyncOperationCompletedHandler&lt; ABI::Windows::Storage::Streams::IRandomAccessStream* &gt; &gt;(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ this ] ( ABI::Windows::Foundation::IAsyncOperation&lt; ABI::Windows::Storage::Streams::IRandomAccessStream* &gt;* pHandler, AsyncStatus status )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( pHandler == nullptr || status != AsyncStatus::Completed )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CreateLogFileError( E_ABORT );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HRESULT hr = pHandler-&gt;GetResults( &amp;m_randomAccessStream );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) || !m_randomAccessStream )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CreateLogFileError( hr );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hr = m_randomAccessStream-&gt;GetOutputStreamAt( 0, &amp;m_pIIStream );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) || !m_pIIStream )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CreateLogFileError( hr );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CreateDataWriter( m_pIIStream );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wchar_t buffer[ 256 ];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetCurrentDateTime( buffer, sizeof( buffer ) / sizeof( wchar_t ) );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write( L"Log file created %s", buffer );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } ).Get() );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } ).Get() );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return S_OK;<br />&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp; void CreateDataWriter( Microsoft::WRL::ComPtr&lt; ABI::Windows::Storage::Streams::IOutputStream &gt;&amp; pStream )<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Storage::Streams::IDataWriter &gt; dataWriter;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Storage::Streams::IDataWriterFactory &gt; data_writer_factory;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HRESULT hr = Windows::Foundation::GetActivationFactory( Microsoft::WRL::Wrappers::HStringReference( RuntimeClass_Windows_Storage_Streams_DataWriter ).Get(), &amp;data_writer_factory );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CreateLogFileError( hr );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hr = data_writer_factory-&gt;CreateDataWriter( *pStream.GetAddressOf(), &amp;m_pDataWriter );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( FAILED( hr ) )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CreateLogFileError( hr );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetEvent( m_logFileCreatedEvent.Get() );<br />&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp; void GetCurrentDateTime( wchar_t* wzBuffer, int wcBufferLen )<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time_t now = time( 0 );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct tm tstruct;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; localtime_s( &amp;tstruct, &amp;now );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wcsftime( wzBuffer, wcBufferLen, L"%Y-%m-%d.%X", &amp;tstruct );<br />&nbsp;&nbsp; }<br /><br /><br />private:<br />&nbsp;&nbsp; CRITICAL_SECTION&nbsp; m_critSec;<br />&nbsp;&nbsp; HStringOwner m_csNewLine;<br /><br />&nbsp;&nbsp; Microsoft::WRL::Wrappers::Event m_logFileCreatedEvent;<br />&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Storage::Streams::IDataWriter &gt; m_pDataWriter;<br />&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Storage::Streams::IRandomAccessStream &gt; m_randomAccessStream;<br />&nbsp;&nbsp; Microsoft::WRL::ComPtr&lt; ABI::Windows::Storage::Streams::IOutputStream &gt; m_pIIStream;<br /><br />&nbsp;&nbsp; int m_registerCount { 0 };<br />&nbsp;&nbsp; bool initDone { false };<br />};<br /><br /></span><br /> </code></pre>]]></content:encoded>
    </item>
    <item>
      <title>Best method for Critical Section management in C++</title>
      <link>https://docs.microsoft.com/archive/blogs/asim_goheer/best-method-for-critical-section-management-in-c</link>
      <pubDate>Sat, 01 Nov 2014 13:57:00 GMT</pubDate>
      <dc:creator><![CDATA[Asim Goheer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/asim_goheer/2014/11/01/best-method-for-critical-section-management-in-c/</guid>
      <description><![CDATA[When it comes down to using critical sections in your C++ code you have pretty much standard...]]></description>
      <content:encoded><![CDATA[<p>When it comes down to using critical sections in your C++ code you have pretty much standard options. Simply call "EnterCriticalSection" at the start of your function and call "LeaveCriticalSection" at the end of your function. No doubt things will work fine, but this approach is not going to be very scalable. Look at the following example:</p>
<pre class="scroll" style="background: #012456;"><code class="cplusplus"><span style="color: #ffffff;">void DummyFunction()</span><br /><span style="color: #ffffff;">{</span><br /><span style="color: #ffffff;"> EnterCriticalSection( &amp;m_cs );</span><br /> <br /><span style="color: #ffffff;"> if( m_count == 0 )</span><br /><span style="color: #ffffff;"> {</span><br /><span style="color: #ffffff;"> // since we are returning early leave the critical section</span><br /><span style="color: #ffffff;"> LeaveCriticalSection( &amp;m_cs );</span><br /><span style="color: #ffffff;"> return;</span><br /><span style="color: #ffffff;"> }</span><br /> <br /><span style="color: #ffffff;"> // do some dummy work here</span><br /><span style="color: #ffffff;"> m_count = m_count + 1;</span><br /><span style="color: #ffffff;"> CallingSomeDummyFunction();</span><br /> <br /><span style="color: #ffffff;"> LeaveCriticalSection( &amp;m_cs );</span><br /><span style="color: #ffffff;">}</span><br /></code></pre>
<p>As you can see this solution is not very scalable, as every time you have to return early you will have to call "LeaveCriticalSection" otherwise you will deadlock. A very bad workaround that some developers use is to use "goto" statements. Look at the following example:</p>
<pre class="scroll" style="background: #012456;"><span style="color: #ffffff;"><code class="cplusplus">void DummyFunction()<br />{<br /> EnterCriticalSection( &amp;m_cs );<br /> <br /> if( m_count == 0 )<br /> {<br /> goto done:<br /> }<br /> <br /> // do some dummy work here<br /> m_count = m_count + 1;<br /> CallingSomeDummyFunction();<br /> <br />done:<br /> LeaveCriticalSection( &amp;m_cs );<br />}</code></span></pre>
<p>This will simplify things because now you do not have to call "LeaveCriticalSection" every time you want to return early, but on the other hand you will be stuck with jumps to prehistoric-goto statements. Also this will make your code hard to follow.</p>
<p>Modern day solution to this problem will be to use a class that will manage the ownership of critical section (full source code of CriticalSectionOwner below).</p>
<pre class="scroll" style="background: #012456;"><span style="color: #ffffff;"><code class="cplusplus">void DummyFunction()<br />{<br /> CriticalSectionOwner csOwner( m_cs );<br /> <br /> if( m_count == 0 )<br /> return;<br /> <br /> // do some dummy work here<br /> m_count = m_count + 1;<br /> CallingSomeDummyFunction();<br />}</code></span></pre>
<p>If you use "CriticalSectionOwner" wrapper class then you will not have to worry about cleanup-when-returning-early, cleanup-when-exceptions-happen, returning-values-from-your function. You can even write a small macro around this class so that you do not have to declare a variable every time. For example:</p>
<pre class="scroll" style="background: #012456;"><span style="color: #ffffff;"><code class="cplusplus">bool DummyFunction()<br />{<br /> <span style="color: #ffffff;"><code class="cplusplus">CRITICAL_SECTION_OWNER</code></span>( m_cs );<br /> <br /> if( m_count == 0 )<br /> return false;<br /> <br /> // do some dummy work here<br /> m_count = m_count + 1;<br /> CallingSomeDummyFunction();<br /> return true;<br />}</code></span></pre>
<p>This will keep things simple and neat.</p>
<p>&nbsp;</p>
<p>Full Source Code of CriticalSectionOwner:</p>
<pre class="scroll" style="background: #012456;"><span style="color: #ffffff;"><code class="cplusplus">#pragma once<br /> /******************************************************************************<br /> *<br /> * Author: Asim Goheer<br /> *<br /> * CriticalSectionOwner is a very lightweight helper class to make critical<br /> * section management easier. <br /> *<br /> * This helper will guarantee proper cleanup, becase in case of an exception<br /> * it's destructor will run thus releasing critical section.<br /> * <br /> * This helper will also allow you to return early from a function. Because<br /> * when you return early from a function the destructor will automatically<br /> * release critical section.<br /> *<br /> ******************************************************************************/<br /> <br /> class CriticalSectionOwner<br /> {<br /> public:<br /> // constructor<br /> CriticalSectionOwner( CRITICAL_SECTION&amp; cs ) : m_cs( cs )<br /> {<br /> EnterCriticalSection( &amp;m_cs );<br /> }<br /> <br /> // destructor<br /> ~CriticalSectionOwner()<br /> {<br /> LeaveCriticalSection( &amp;m_cs );<br /> }<br /> <br /> private:<br /> // Disable copy constructor<br /> CriticalSectionOwner( const CriticalSectionOwner&amp; ) = delete;<br /> <br /> private:<br /> CRITICAL_SECTION&amp; m_cs;<br /> };<br /> <br /> // Define a macro that we can use<br /> #define CRITICAL_SECTION_OWNER( x ) CriticalSectionOwner csOwner( x );<br /> </code></span></pre>]]></content:encoded>
    </item>
    <item>
      <title>C++ Converting ComPtr&lt;IRandomAccessStream&gt; to ComPtr&lt;IClosable&gt;</title>
      <link>https://docs.microsoft.com/archive/blogs/asim_goheer/c-converting-comptrirandomaccessstream-to-comptriclosable</link>
      <pubDate>Sat, 01 Nov 2014 05:08:00 GMT</pubDate>
      <dc:creator><![CDATA[Asim Goheer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/asim_goheer/2014/11/01/c-converting-comptrirandomaccessstream-to-comptriclosable/</guid>
      <description><![CDATA[When using WRL, sometimes if you have a pointer to derived interface such as IRandomAccessStream...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: verdana,geneva; font-size: small;">When using WRL, sometimes if you have a pointer to derived interface such as IRandomAccessStream (which derives from IClosable), and you would want to convert it to IClosable (so that you can call "Close" on the stream). To do that you will have to use ComPtr.As call.<br /></span></p>
<p>Example:&nbsp;</p>
<pre class="scroll" style="background: #012456;"><span style="color: #ffffff;"><code class="cplusplus"> WRL::ComPtr&lt; Streams::IRandomAccessStream &gt; randomAccessStream;<br /> // set randomAccessStream to something here.<br /><br /> <span style="color: #ffffff;"><code class="cplusplus">WRL::</code></span>ComPtr&lt; IClosable &gt; pICloseable;<br /> HRESULT hr = randomAccessStream.As&lt; IClosable &gt;( &amp;pICloseable );<br /> if( SUCCEEDED( hr ) )<br /> pICloseable-&gt;Close(); // Call Close on Stream</code></span></pre>]]></content:encoded>
    </item>
    <item>
      <title>Calling Windows Runtime Async functions from C++ using WRL</title>
      <link>https://docs.microsoft.com/archive/blogs/asim_goheer/calling-windows-runtime-async-functions-from-c-using-wrl</link>
      <pubDate>Sat, 01 Nov 2014 04:37:00 GMT</pubDate>
      <dc:creator><![CDATA[Asim Goheer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/asim_goheer/2014/11/01/calling-windows-runtime-async-functions-from-c-using-wrl/</guid>
      <description><![CDATA["await" This 5 letter word might look trivial to you if you are a C# developer, but once you leave...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: small; font-family: verdana,geneva;">"await" This 5 letter word might look trivial to you if you are a C# developer, but once you leave C# domain and enter the cruel world of C++/CX you will start to like it. But if you move to pure C++ from C++/CX then you will start to love it. Reason for that is simple, await makes your life easier by waiting for Async functions to return. In C++/CX you can use create_task() &amp; .then() to do the same thing.</span></p>
<p><span style="font-size: small; font-family: verdana,geneva;">If you are just using pure C++ (without /CX) you will have to do lot more work to accomplish the same thing.</span> Here is how you will do it:</p>
<p>&nbsp;</p>
<pre class="scroll" style="background: #012456;"><span style="color: #ffffff;"><code class="cplusplus"> WRL::ComPtr&lt; IAsyncOperation&lt; Streams::IRandomAccessStream* &gt; &gt; pAsyncAction;<br /> IStorageFile* pStorageFile = nullptr; //we are assuming storageFolder is initialized in the next line before calling OpenAsync<br /><br /> HRESULT hr = pStorageFile-&gt;OpenAsync( FileAccessMode::FileAccessMode_ReadWrite, &amp;pAsyncAction );<br /> if( FAILED( hr ) )<br /> {<br /> // report error<br /> return E_FAIL;<br /> }<br /> <br /> pAsyncAction-&gt;put_Completed( Microsoft::WRL::Callback&lt; IAsyncOperationCompletedHandler&lt; Streams::IRandomAccessStream* &gt; &gt;(<br /> [ this ] ( IAsyncOperation&lt; Streams::IRandomAccessStream* &gt;* pHandler, AsyncStatus status )<br /> {<br /> // check status and use the stream here<br /> return S_OK;<br /> } ).Get() );<br /> <br /> return S_OK;<br /> <br /> } ).Get() );</code></span></pre>
<p><br /><br /><br /></p>]]></content:encoded>
    </item>
    <item>
      <title>HSTRING wrapper for C++</title>
      <link>https://docs.microsoft.com/archive/blogs/asim_goheer/hstring-wrapper-for-c</link>
      <pubDate>Sat, 01 Nov 2014 03:51:00 GMT</pubDate>
      <dc:creator><![CDATA[Asim Goheer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/asim_goheer/2014/11/01/hstring-wrapper-for-c/</guid>
      <description><![CDATA[If you are developing apps for Windows Store or Windows Phone in C++, chances are that one of the...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: verdana,geneva; font-size: small;">If you are developing apps for Windows Store or Windows Phone in C++, chances are that one of the biggest annoyance you will see are the <a title="https://msdn.microsoft.com/en-us/library/br205775%28v=vs.85%29.aspx" href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/HSTRINGS" target="_blank">HSTRING</a>(specifically creating and managing them.) If you are using C++/CX you can get away by using "Platform::String", but if you cannot use CX extension your only option is to use HSTRING.<br /></span></p>
<p>&nbsp;</p>
<p><span style="font-family: verdana,geneva; font-size: small;">C++ developers normally&nbsp;keep their strings in "<span style="color: #0000ff;">wchar_t*</span>" format, however Windows Runtime APIs require them in HSTRING format. APIs exists to convert between them, but you have to make sure that you call them properly, otherwise memory leaks will happen. </span></p>
<p>&nbsp;</p>
<p><span style="font-family: verdana,geneva; font-size: small;">This class will management of HSTRINGs easier. You simply create a HStringOwner object on the stack. Once this object goes out of scope, it will be destroyed.</span></p>
<p><span style="font-family: verdana,geneva; font-size: small;">Benefits:</span></p>
<ol>
<li><span style="font-family: verdana,geneva; font-size: small;">Easy creation of <a title="https://msdn.microsoft.com/en-us/library/br205775%28v=vs.85%29.aspx" href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/HSTRING">HSTRING</a></span></li>
<li><span style="font-family: verdana,geneva; font-size: small;">Lifetime management of HSTRING</span></li>
<li><span style="font-family: verdana,geneva; font-size: small;">Proper cleanup of HSTRING in case of exception</span></li>
<li><span style="font-family: verdana,geneva; font-size: small;">Allows you to return early from your function without running a block of code specifically for cleanup.</span></li>
</ol>
<p>&nbsp;</p>
<pre class="scroll" style="background: #012456;"><code class="cplusplus"><span style="color: #ffffff;">#pragma once</span><br /><span style="color: #ffffff;"> /******************************************************************************</span><br /><span style="color: #ffffff;"> *<br /> * Author : Asim Goheer<br /> *<br /></span><span style="color: #ffffff;"> * HStringOwner is a very lightweight helper class to make HSTRING</span><br /><span style="color: #ffffff;"> * management easier. </span><br /><span style="color: #ffffff;"> *</span><br /><span style="color: #ffffff;"> * This helper will guarantee proper cleanup, becase in case of an exception</span><br /><span style="color: #ffffff;"> * it's destructor will run thus releasing the string</span><br /><span style="color: #ffffff;"> * </span><br /><span style="color: #ffffff;"> * This helper will also allow you to return early from a function. Because</span><br /><span style="color: #ffffff;"> * when you return early from a function the destructor will automatically</span><br /><span style="color: #ffffff;"> * release the string</span><br /><span style="color: #ffffff;"> *</span><br /><span style="color: #ffffff;"> ******************************************************************************/</span><br /> <br /> <br /><span style="color: #ffffff;"> class HStringOwner</span><br /><span style="color: #ffffff;"> {</span><br /><span style="color: #ffffff;"> public:</span><br /><span style="color: #ffffff;"> HStringOwner( wchar_t* wzSource )</span><br /><span style="color: #ffffff;"> {</span><br /><span style="color: #ffffff;"> HRESULT hr = WindowsCreateString( wzSource, wcslen( wzSource ), &amp;m_hString );</span><br /><span style="color: #ffffff;"> if( FAILED( hr ) )</span><br /><span style="color: #ffffff;"> {</span><br /><span style="color: #ffffff;"> // throw exception here</span><br /><span style="color: #ffffff;"> }</span><br /><span style="color: #ffffff;"> }</span><br /> <br /><span style="color: #ffffff;"> virtual ~HStringOwner()</span><br /><span style="color: #ffffff;"> {</span><br /><span style="color: #ffffff;"> WindowsDeleteString( m_hString );</span><br /><span style="color: #ffffff;"> }</span><br /> <br /><span style="color: #ffffff;"> operator HSTRING () const</span><br /><span style="color: #ffffff;"> {</span><br /><span style="color: #ffffff;"> return m_hString;</span><br /><span style="color: #ffffff;"> }</span><br /> <br /><span style="color: #ffffff;"> private:</span><br /><span style="color: #ffffff;"> HStringOwner( const HStringOwner&amp; );</span><br /> <br /><span style="color: #ffffff;"> HSTRING m_hString;</span><br /><span style="color: #ffffff;"> };</span><br /> </code></pre>]]></content:encoded>
    </item>
  </channel>
</rss>