Mesoscopic Programming

プログラミング専門

子ウィンドウをポップアップウィンドウに変更するには?

やっと分かったぞ!
せっかく調べたのでその方法を公開します。
ポップアップウィンドウを作るとき、
CreateWindow関数だと超簡単に親ウィンドウ(=オーナーウィンドウ)を設定できるけど、
子ウィンドウからポップアップウィンドウに変更するとなると
そう簡単には行かないのだった(分かってしまえば簡単だけど)。

// hWnd    子ウィンドウまたはポップアップウィンドウハンドル
// hParent 親ウィンドウハンドル

//-----------------------------------------------------------------------------
// 子ウィンドウをポップアップウィンドウに変更する

// 親ウィンドウをクリアする
::SetParent( hWnd, nullptr );

// ウィンドウスタイルを設定する
::SetWindowLongPtrW( hWnd, GWL_STYLE, static_cast< LONG_PTR >( WS_POPUP ) );

// オーナーウィンドウを設定する
::SetWindowLongPtrW( hWnd, GWLP_HWNDPARENT, reinterpret_cast< LONG_PTR >( hParent ) );

//-----------------------------------------------------------------------------
// ポップアップウィンドウを子ウィンドウに変更する

// ウィンドウスタイルを設定する
::SetWindowLongPtrW( hWnd, GWL_STYLE, static_cast< LONG_PTR >( WS_CHILD ) ) );

// 親ウィンドウを設定する
::SetParent( hWnd, hParent );
解説

要はSetWindowLong関数の部分ですにゃ。
※64ビットのユニコード用なのでSetWindowLongPtrW関数を使っているけども。
これがなかなか見つからなかった。
だってSetParent関数だと思うじゃん、普通。
ところがSetParent関数だと、ウィンドウが消えちゃうじゃん!
これが違うかったんだにゃ。
これで2日ほど悩んだっぺした。
分かってスッキリしたべ。
以上です。

VusualStudio 2015 のテキストエディタのここが嫌いだ!

誰が設計してるんだか。
このテキストエディタは。
昔のVisualStudioはこんなじゃなかったのに。
せめてオプションで機能を禁止できるようにして欲しいものだ。
この余計な機能を。
Googleで調べても禁止する方法が分からなかった。
検索ボックスに文字を入力してる途中で勝手にジャンプしてしまう余計な機能のことだ。
作業者の視線はいま検索ボックスにあるのだから、
テキストのカーソル位置は以前の場所にあると思い込んでいるのに、
検索を途中でやめて文字を入力すると、
まったくでたらめな場所に文字が入力されてしまうのだ。
こんな馬鹿な機能を考えたのはいったいどこのどいつだ。
責任者を呼んで来い!
こんなにも余計な機能なのに、
オプションで禁止できないってどういうことだ。
ほかにもたくさん余計な機能があるけど、
大体はオプションで機能を禁止できるのに。
本当に腹が立つ。
作業効率が悪くなってしょうがない。
それになんといっても重過ぎる。
インテリセンスのせいであることは分かっているが、
インテリセンスを完全に切るのは忍びない。
もっと軽いテキストエディタの統合環境が欲しい。
オプションでもっと軽いテキストエディタが選べるといいのに。
文句を言ったらスッキリした。
VisualStudio 2020くらいで改良されることを期待しよう!

プロセス関係の関数を作った

プロセス関係の関数を作ったので置いておきます。
マルチプロセスのプログラムをデバッグしていると、
自分以外のプロセスを殺したくなりますよね。
いちいち手作業で殺すのはめんどくさいので、
自動で殺すためのお助け関数を作りました。
これでプロセス識別子からハンドルをゲットして、
ターミネートしてやれば自動で殺せますよね。

親プロセス識別子取得関数
    //-------------------------------------------------------------------------
    /// 親プロセス識別子取得関数
    ///
    /// 親プロセス識別子取得関数です。
    ///
    /// @param[in] value プロセス識別子
    /// @return    プロセス識別子
    /// @attention なし
    ///
    DWORD GetParentProcess( DWORD value ) {
        // 実行結果を初期化する
        DWORD result = 0;

        // プロセススナップショットを作成する
        HANDLE snap = ::CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
        if ( nullptr != snap ) {
            // 最初のプロセス情報を取得する
            PROCESSENTRY32 pe;
            pe.dwSize = sizeof( PROCESSENTRY32 );
            BOOL result2 = ::Process32First( snap, &pe );

            // プロセス情報を巡回する
            while ( TRUE == result2 ) {
                // プロセス識別子を調べる
                if ( value == pe.th32ProcessID ) {
                    // 親プロセス識別子を取得する
                    result = pe.th32ParentProcessID;
                    break;
                }

                // 次のプロセス情報を取得する
                pe.dwSize = sizeof( PROCESSENTRY32 );
                result2 = ::Process32Next( snap, &pe );
            }
        }

        // 実行結果を返す
        return result;
    }
解説

自分を起動したプロセスが誰なのかを知りたいです。
他のプロセスのためのプロセスならば、
親が特定のプロセスでなければ意味がありませんから。

プロセス実行ファイルパス取得関数
    //-------------------------------------------------------------------------
    /// プロセス実行ファイルパス取得関数
    ///
    /// プロセス実行ファイルパス取得関数です。
    ///
    /// @param[in]  id     プロセス識別子
    /// @param[out] buffer 文字列バッファ
    /// @param[out] size   バッファサイズ
    /// @return     文字列ポインタ
    /// @attention  なし
    ///
    char const* GetProcessExeFilePath( DWORD id, char* buffer, size_t size ) {
        // 実行結果を初期化する
        char const* result = nullptr;

        // モジュールスナップショットを作成する
        HANDLE snap = ::CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, id );
        if ( nullptr != snap ) {
            // 最初のモジュール情報を取得する
            MODULEENTRY32 me;
            me.dwSize = sizeof( MODULEENTRY32 );
            BOOL result2 = ::Module32First( snap, &me );

            // モジュール情報を巡回する
            while ( TRUE == result2 ) {
                // プロセス識別子を調べる
                if ( id == me.th32ProcessID ) {
                    // プロセス実行ファイルパスを取得する
                    ::strcpy_s( buffer, size, me.szExePath );

                    // 文字列ポインタを設定する
                    result = buffer;
                    break;
                }

                // 次のプロセス情報を取得する
                me.dwSize = sizeof( MODULEENTRY32 );
                BOOL result2 = ::Module32Next( snap, &me );
            }
        }

        // 実行結果を返す
        return result;
    }
解説

親プロセスの識別子が分かったなら、
その実行ファイルパスから
目的とするプロセスかどうか
判断できますよね。

プロセス検索関数
    //-------------------------------------------------------------------------
    /// プロセス検索関数
    ///
    /// プロセス検索関数です。
    ///
    /// @param[in] value プロセス実行ファイルパス
    /// @return    プロセス識別子
    /// @attention なし
    ///
    //-------------------------------------------------------------------------
    // プロセス検索関数
    DWORD SearchProcess( char const* value ) {
        // 実行結果を初期化する
        DWORD result = 0;

        // プロセススナップショットを作成する
        HANDLE snap_process = ::CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
        if ( nullptr != snap_process ) {
            // 最初のプロセス情報を取得する
            PROCESSENTRY32 pe;
            pe.dwSize = sizeof( PROCESSENTRY32 );
            BOOL result2 = ::Process32First( snap_process, &pe );

            // プロセス情報を巡回する
            while ( TRUE == result2 ) {
                // モジュールスナップショットを作成する
                HANDLE snap_module = ::CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pe.th32ProcessID );
                if ( nullptr != snap_module ) {
                    // 最初のモジュール情報を取得する
                    MODULEENTRY32 me;
                    me.dwSize = sizeof( MODULEENTRY32 );
                    BOOL result2 = ::Module32First( snap_module, &me );

                    // モジュール情報を巡回する
                    while ( TRUE == result2 ) {
                        // プロセス実行ファイルパスを調べる
                        if ( 0 == ::_strcmpi( value, me.szExePath ) ) {
                            // プロセス識別子を取得する
                            result = pe.th32ProcessID;
                            break;
                        }

                        // 次のプロセス情報を取得する
                        me.dwSize = sizeof( MODULEENTRY32 );
                        BOOL result2 = ::Module32Next( snap_module, &me );
                    }

                    // 実行結果を調べる
                    if ( 0 != result ) {
                        // ブレークする
                        break;
                    }
                }

                // 次のプロセス情報を取得する
                pe.dwSize = sizeof( PROCESSENTRY32 );
                result2 = ::Process32Next( snap_process, &pe );
            }
        }

        // 実行結果を返す
        return result;
    }
解説

いろんなプロセスを殺したいときってありますよね。
ファイル名だけだと同じ名前の他人だったりするから、
ちゃんとフルパスで探してあげてね。
あと
必要なヘッダはこんな感じです。

#include <windows.h>
#include <string.h>
#include <tlhelp32.h>

もし足りなかったらぼめんなさい。

以上です。

C++/CLIにはまる

いままでWin32だけで済まそうとがんばって来ましたが、.NETの便利な関数というか.NETにしかない関数を使いたくて、ついにCLIに手を出しました。
でもやっぱりC#には手を出したくない。仕事以外では。
なぜならば神であるビャーネ・ストラウストラップ先生に申し訳ないからだ。
ま、両方やればいいじゃんと言う話もあるが。

しかし結局CLIを勉強しようとすると、C#の勉強にもなってしまうのだ。
なぜならば.NET APIを検索すると、ほとんどC#関係の記事しか引っかからないからだ。

VS2015を使えば、C++11とCLIを同時に使えるので非常に便利で楽しい。
しかも#pragma managedを使えば、CLRプロジェクトでも、ほぼすべてネイティブコードで書くことだってできるんだ。意味ないけど。

最近やっと、マネージコードとネイティブコードの混在方法が分かってきた。
マネージコードでDLL作ると、ヘッダファイルを書く必要がないってのも分かった。
いまオリジナルの構成ファイル処理モジュールを作っている。
.NETに備え付けの構成ファイルAPIだと細かいことが自由にできないからだ。
そんなわけでXMLも勉強してしまった。
実におもしろい。

レジストリのクラス

ずっと昔ながらのプロファイルばかり使っていましたが、
意を決してレジストリを使うことにしました。
そこで、レジストリのクラスを作りました。

TRegistry.h
//----------------------------------------------------------------------------
/// @file    TRegistry.h
/// @brief   レジストリクラスヘッダ
/// @details レジストリクラスです。
/// @version 0.1.0
/// @date    2015/05/10
/// @author  Copyright (C) 2015 hidakas1961 All rights reserved.
//----------------------------------------------------------------------------

#pragma once

#include <Common.h>
#include <TLogOut.h>

// 共通ライブラリ名前空間
namespace Common
{
    //------------------------------------------------------------------------
    /// @brief   レジストリクラス
    /// @details レジストリクラスです。
    //------------------------------------------------------------------------
    class TRegistry
    {
        //--------------------------------------------------------------------
        // 動的変数
        //--------------------------------------------------------------------

    private :

        HKEY         m_hopenkey; ///< オープンキーハンドル
        const char * m_headkey;  ///< 先頭キー文字列
        const char * m_subkey;   ///< サブキー文字列

        //--------------------------------------------------------------------
        // 構築子と解体子
        //--------------------------------------------------------------------

    public :

        /// @brief   デフォルト構築子
        /// @param   [in] subkey   サブキー文字列
        /// @param   [in] headkey  先頭キー文字列
        /// @param   [in] hopenkey オープンキーハンドル
        /// @details レジストリクラスを構築します。
        explicit TRegistry( const char * subkey, const char * headkey = "Software", HKEY hopenkey = HKEY_CURRENT_USER );

        /// @brief 解体子
        inline virtual ~TRegistry() {}

        //--------------------------------------------------------------------
        // 動的関数
        //--------------------------------------------------------------------

    private :

        /// @brief   レジストリキーオープン関数
        /// @param   [in] tailkey 最後尾キー文字列
        /// @return  レジストリキーハンドル
        /// @details レジストリキーをオープンします。
        HKEY OpenKey( const char * tailkey = 0 ) const;

    public :

        /// @brief   任意型データ保存関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] data    任意データ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @retval  true  成功
        /// @retval  false 失敗
        /// @details 任意の型のデータを保存します。
        template< class T > bool WriteData( const char * entry, const T & data, const char * tailkey = 0 ) const
        {
            bool  result = false;
            DWORD size   = sizeof( data );
            DWORD type   = REG_BINARY;

            Log().Begin( __func__ );
            Log().LineDataText( "entry  ", entry );
            Log().LineDataText( "class T", typeid( data ).name() );
            Log().LineData    ( "data   ", data );
            Log().LineDataText( "tailkey", tailkey );
            Log().LineDataText( "type   ", "REG_BINARY" );
            Log().LineData    ( "size   ", size );

            // レジストリキーをオープンします。
            HKEY hkey = OpenKey( tailkey );

            if ( hkey )
            {
                // エントリデータを保存します。
                result = RegSetValueEx( hkey, entry, 0, type, reinterpret_cast< const BYTE * >( & data ), size ) == ERROR_SUCCESS;

                // レジストリキーをクローズします。
                RegCloseKey( hkey );
            }

            Log().LineData( "result ", result );
            Log().End( __func__ );

            return result;
        }

        /// @brief   任意型データ取得関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] data    デフォルトデータ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @return  任意型データ
        /// @details 任意の型のデータを取得します。
        template< class T > T ReadData( const char * entry, const T & data, const char * tailkey = 0 ) const
        {
            bool  result = false;
            T     buffer = data;
            DWORD size   = sizeof( T );
            DWORD recv   = 0;
            DWORD type   = REG_BINARY;

            Log().Begin( __func__ );
            Log().LineDataText( "entry  ", entry );
            Log().LineDataText( "class T", typeid( data ).name() );
            Log().LineData    ( "data   ", data );
            Log().LineDataText( "tailkey", tailkey );
            Log().LineDataText( "type   ", "REG_BINARY" );
            Log().LineData    ( "size   ", size );

            // レジストリキーをオープンします。
            HKEY hkey = OpenKey( tailkey );

            if ( hkey )
            {
                // エントリデータを取得します。
                if ( RegQueryValueEx( hkey, entry, 0, & type, reinterpret_cast< BYTE * >( & buffer ), & size ) == ERROR_SUCCESS )
                {
                    result = true;
                    recv   = size;
                }

                // レジストリキーをクローズします。
                RegCloseKey( hkey );
            }

            Log().LineData( "result ", result );
            Log().LineData( "recv   ", recv );
            Log().LineData( "buffer ", buffer );
            Log().End( __func__ );

            return buffer;
        }

        /// @brief   バイナリデータ保存関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] buffer  バッファポインタ
        /// @param   [in] size    バッファサイズ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @retval  true  成功
        /// @retval  false 失敗
        /// @details バイナリデータを保存します。
        bool WriteBinary( const char * entry, const void * buffer, DWORD size, const char * tailkey = 0 ) const;

        /// @brief   文字列保存関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] text    文字列
        /// @param   [in] tailkey 最後尾キー文字列
        /// @retval  true  成功
        /// @retval  false 失敗
        /// @details 文字列を保存します。
        bool WriteText( const char * entry, const char * text, const char * tailkey = 0 ) const;

        /// @brief   整数型データ保存関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] data    整数型データ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @retval  true  成功
        /// @retval  false 失敗
        /// @details 整数型のデータを保存します。
        bool WriteInt( const char * entry, DWORD data, const char * tailkey = 0 ) const;

        /// @brief   バイナリデータ取得関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] buffer  バッファポインタ
        /// @param   [in] size    バッファサイズ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @return  取得データバイトサイズ
        /// @details バイナリデータを取得します。
        DWORD ReadBinary( const char * entry, void * buffer, DWORD size, const char * tailkey = 0 ) const;

        /// @brief   文字列取得関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] buffer  文字列バッファポインタ
        /// @param   [in] size    バッファサイズ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @return  取得文字列バイトサイズ
        /// @details 文字列を取得します。
        DWORD ReadText( const char * entry, char * buffer, DWORD size, const char * tailkey = 0 ) const;

        /// @brief   整数型データ取得関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] data    デフォルトデータ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @return  整数型データ
        /// @details 整数型のデータを取得します。
        DWORD ReadInt( const char * entry, DWORD data, const char * tailkey = 0 ) const;
    };
}   // Window
TRegistry.cpp
//----------------------------------------------------------------------------
/// @file    TRegistry.cpp
/// @brief   レジストリクラス
/// @details レジストリクラスです。
//----------------------------------------------------------------------------

#include <TRegistry.h>

//----------------------------------------------------------------------------
// 名前空間使用宣言
//----------------------------------------------------------------------------

using namespace Common;

//----------------------------------------------------------------------------
// 構築子と解体子
//----------------------------------------------------------------------------
// デフォルト構築子
TRegistry::TRegistry( const char * subkey, const char * headkey, HKEY hopenkey )
    : m_subkey  ( subkey )
    , m_headkey ( headkey )
    , m_hopenkey( hopenkey )
{
    Log().Begin( __func__ );
    Log().LineDataText( "subkey  ", subkey );
    Log().LineDataText( "headkey ", headkey );
    Log().LineData    ( "hopenkey", hopenkey );
    Log().End( __func__ );
}

//----------------------------------------------------------------------------
// 動的関数
//----------------------------------------------------------------------------

// レジストリキーオープン関数
HKEY TRegistry::OpenKey( const char * tailkey ) const
{
    // サブキー文字列を作成します。
    string subkey;

    if ( m_headkey )
    {
        subkey.append( m_headkey );
        subkey.append( "\\" );
    }

    subkey.append( m_subkey );

    if ( tailkey )
    {
        subkey.append( "\\" );
        subkey.append( tailkey );
    }

    // レジストリキーをオープンします。
    HKEY hkey;

    if ( RegCreateKeyEx( m_hopenkey, subkey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, & hkey, NULL ) == ERROR_SUCCESS )
    {
        return hkey;
    }

    return 0;
}

// バイナリデータ保存関数
bool TRegistry::WriteBinary( const char * entry, const void * buffer, DWORD size, const char * tailkey ) const
{
    bool  result = false;
    DWORD type   = REG_BINARY;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineData    ( "buffer ", buffer );
    Log().LineData    ( "size   ", size );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_BINARY" );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを保存します。
        result = RegSetValueEx( hkey, entry, 0, type, reinterpret_cast< const BYTE * >( buffer ), size ) == ERROR_SUCCESS;

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().End( __func__ );

    return result;
}

// 文字列保存関数
bool TRegistry::WriteText( const char * entry, const char * text, const char * tailkey ) const
{
    bool  result = false;
    DWORD size   = strlen( text ) + 1;
    DWORD type   = REG_SZ;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineDataText( "text   ", text );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_SZ" );
    Log().LineData    ( "size   ", size );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを保存します。
        result = RegSetValueEx( hkey, entry, 0, type, reinterpret_cast< const BYTE * >( text ), size ) == ERROR_SUCCESS;

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().End( __func__ );

    return result;
}

// 整数型データ保存関数
bool TRegistry::WriteInt( const char * entry, DWORD data, const char * tailkey ) const
{
    bool  result = false;
    DWORD size   = sizeof( DWORD );
    DWORD type   = REG_DWORD;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineData    ( "data   ", data );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_DWORD" );
    Log().LineData    ( "size   ", size );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを保存します。
        result = RegSetValueEx( hkey, entry, 0, type, reinterpret_cast< const BYTE * >( & data ), size ) == ERROR_SUCCESS;

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().End( __func__ );

    return result;
}

// バイナリデータ取得関数
DWORD TRegistry::ReadBinary( const char * entry, void * buffer, DWORD size, const char * tailkey ) const
{
    bool  result = false;
    DWORD recv   = 0;
    DWORD type   = REG_BINARY;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineData    ( "buffer ", buffer );
    Log().LineData    ( "size   ", size );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_BINARY" );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを取得します。
        if ( RegQueryValueEx( hkey, entry, 0, & type, reinterpret_cast< BYTE * >( buffer ), & size ) == ERROR_SUCCESS )
        {
            result = true;
            recv   = size;
        }

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().LineData( "recv   ", recv );
    Log().End( __func__ );

    return recv;
}

// 文字列取得関数
DWORD TRegistry::ReadText( const char * entry, char * buffer, DWORD size, const char * tailkey ) const
{
    bool  result = false;
    DWORD recv   = 0;
    DWORD type   = REG_SZ;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineData    ( "buffer ", buffer );
    Log().LineData    ( "size   ", size );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_SZ" );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを取得します。
        if ( RegQueryValueEx( hkey, entry, 0, & type, reinterpret_cast< BYTE * >( buffer ), & size ) == ERROR_SUCCESS )
        {
            result = true;
            recv   = size;
        }

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().LineData( "recv   ", recv );

    if ( recv )
    {
        Log().LineDataText( "buffer ", buffer );
    }

    Log().End( __func__ );

    return recv;
}

// 整数型データ取得関数
DWORD TRegistry::ReadInt( const char * entry, DWORD data, const char * tailkey ) const
{
    bool  result = false;
    DWORD buffer = data;
    DWORD size   = sizeof( DWORD );
    DWORD recv   = 0;
    DWORD type   = REG_DWORD;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineData    ( "data   ", data );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_DWORD" );
    Log().LineData    ( "size   ", size );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを取得します。
        if ( RegQueryValueEx( hkey, entry, 0, & type, reinterpret_cast< BYTE * >( & buffer ), & size ) == ERROR_SUCCESS )
        {
            result = true;
            recv   = size;
        }

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().LineData( "recv   ", recv );
    Log().LineData( "buffer ", buffer );
    Log().End( __func__ );

    return buffer;
}
解説

整数と文字列以外の任意の型にはテンプレートでバイナリーデータとして対応しているので、
どんなクラスや構造体もそのまま保存と取得ができるようになっています。
またログ出力クラスもだいぶ改良しましたので、
サンプルプログラムは、サイドバーのリンクから倉庫置き場に行って適当に見つけてください。
以上です。

ソースコード置き場へのリンク

最近なぜかしら@PAGESが繋がらなくなったので、ソース置き場をSiteMixに代えました。
ついでにVisual Web Developer 2010 Expressでサイトの構成をいろいろいじってる最中なもんで、
リンク先が頻繁に変更になってます。
記事ごとにリンクを直すのも大変なんで、ここに一括してリンクを貼っておきます。

しつこいぐらいにログを出すテスト

一人でプログラムを作っているときにはそれほど必要に感じませんけど、
プロジェクトチームでプログラムを作っていると、
何が原因でプログラムが動かないのか気になりますよね。
そんなとき役に立つのが、やっぱログですよね。
そこで、しつこいぐらいにログを出すシステムを作りました。

まずはログ出力用のストリームクラスです。

TLogStream.h
//----------------------------------------------------------------------------
/// @file    TLogStream.h
/// @brief   ログ出力ストリームクラスヘッダ
/// @details ログ出力ストリームクラスです。
/// @version 0.1.1
/// @date    2015/05/03
/// @author  Copyright (C) 2015 hidakas1961 All rights reserved.
//----------------------------------------------------------------------------

#pragma once

#include <TDebugStream.h>
#include <fstream>
#include <stdio.h>
#include <stdarg.h>

// 共通ライブラリ名前空間
namespace Common
{
    //------------------------------------------------------------------------
    // 名前空間使用宣言
    //------------------------------------------------------------------------

    using namespace std;

    //------------------------------------------------------------------------
    // クラス宣言
    //------------------------------------------------------------------------

    class TLogStream;

    //------------------------------------------------------------------------
    // グローバル関数
    //------------------------------------------------------------------------

    /// @brief   ログストリーム作成関数
    /// @param   [in] filename ファイル名
    /// @param   [in] plog     ログ出力ストリームポインタ
    /// @param   [in] tabsize  タブサイズ
    /// @param   [in] header   ヘッダー文字列
    /// @param   [in] line     行番号
    /// @param   [in] date     日付出力フラグ
    /// @param   [in] time     時刻出力フラグ
    /// @return  ログストリームクラスオブジェクト
    /// @details ログストリームを作成します。
    TLogStream & CreateLog( const char * filename = 0, ostream * plog = 0, int tabsize = 4, const char * header = 0, long line = 0, bool date = false, bool time = false );

    /// @brief   ログオブジェクト取得関数
    /// @return  ログストリームクラスオブジェクト
    /// @details ログストリームクラスオブジェクトを取得します。
    TLogStream & LogOut();

    //------------------------------------------------------------------------
    /// @brief   ログ出力ストリームクラス
    /// @details ログ出力ストリームクラスです。
    //------------------------------------------------------------------------
    class TLogStream
    {
        //--------------------------------------------------------------------
        // 動的変数
        //--------------------------------------------------------------------

    private :

        ofstream     * m_pfile;   ///< ファイル出力ストリームポインタ
        ostream      * m_plog;    ///< ログ出力ストリームポインタ
        int            m_tabsize; ///< タブサイズ
        const char   * m_header;  ///< ヘッダー文字列
        int            m_block;   ///< ブロック数
        TDebugStream * m_pdebug;  ///< デバッグ出力ストリームポインタ
        long           m_line;    ///< 行番号
        bool           m_date;    ///< 日付出力フラグ
        bool           m_time;    ///< 時刻出力フラグ

        //--------------------------------------------------------------------
        // 構築子と解体子
        //--------------------------------------------------------------------

    public :

        /// @brief デフォルト構築子
        /// @param [in] filename ファイル名
        /// @param [in] plog     ログ出力ストリームポインタ
        /// @param [in] tabsize  タブサイズ
        /// @param [in] header   ヘッダー文字列
        /// @param [in] line     行番号
        /// @param [in] date     日付出力フラグ
        /// @param [in] time     時刻出力フラグ
        explicit TLogStream( const char * filename = 0, ostream * plog = 0, int tabsize = 4, const char * header = 0, long line = 0, bool date = false, bool time = false );

        /// @brief 解体子
        virtual ~TLogStream();

        //--------------------------------------------------------------------
        // 演算子オーバーロード関数
        //--------------------------------------------------------------------

    public :

        /// @brief   左シフト演算子オーバーロード関数
        /// @param   [in] param 引数
        /// @return  ログ出力ストリーム参照アドレス
        /// @details 引数を出力します。
        template< class T > TLogStream & operator <<( T param ) { * m_plog << param; return * this; }

        //--------------------------------------------------------------------
        // 動的関数
        //--------------------------------------------------------------------

    public :

        /// @brief   ヘッダー出力関数
        /// @param   [in] block ブロック数
        /// @return  ログ出力ストリーム参照アドレス
        /// @details ヘッダー文字列とブロックインデントを出力します。
        inline virtual TLogStream & Header( int block = -1 )
        {
            // ヘッダー文字列を出力します。
            if ( m_header ) * m_plog << m_header << ":";

            // 行番号を出力します。
            if ( m_line > 0 )
            {
                WriteFormat( "%06ld:", m_line++ );
            }

            // 日付を出力します。
            if ( m_date )
            {
                char date[ 256 ];

                GetDateFormat( LOCALE_SYSTEM_DEFAULT, LOCALE_NOUSEROVERRIDE, 0, 0, date, ArrayCount( date ) );

                WriteFormat( "%s:", date );
            }

            // 時刻を出力します。
            if ( m_time )
            {
                char time[ 256 ];

                GetTimeFormat( LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT, 0, "HH':'mm':'ss", time, ArrayCount( time ) );

                WriteFormat( "%s:", time );
            }

            // ブロックインデントを出力します。
            return Indent( block );
        }

        /// @brief   ブロックインデント出力関数
        /// @param   [in] block ブロック数
        /// @return  ログ出力ストリーム参照アドレス
        /// @details ブロックインデントを出力します。
        inline virtual TLogStream & Indent( int block = -1 )
        {
            // ブロック数を調べます。
            if ( block < 0 )
            {
                // 現在のブロック数を適用します。
                block = m_block;
            }

            // ブロック数を巡回します。
            for ( int n = 0; n < block; n++ )
            {
                // タブサイズを巡回します。
                for ( int m = 0; m < m_tabsize; m++ )
                {
                    // 空白を出力します。
                    * m_plog << " ";
                }
            }

            return * this;
        }

        /// @brief   改行出力関数
        /// @return  ログ出力ストリーム参照アドレス
        /// @details 改行を出力します。
        inline virtual TLogStream & NewLine()
        {
            // 改行を出力します。
            * m_plog << endl;

            return * this;
        }

        /// @brief   ブロック開始行出力関数
        /// @param   [in] name ブロック名
        /// @return  ログ出力ストリーム参照アドレス
        /// @details ブロック開始行を出力します。
        inline virtual TLogStream & Begin( const char * name )
        {
            // ヘッダーを出力してブロックカウンタをインクリメントしてブロック開始文字とブロック名を出力します。
            Header( m_block++ ) << "{ // " << name;

            // 改行します。
            return NewLine();
        }

        /// @brief   ブロック終了行出力関数
        /// @param   [in] name ブロック名
        /// @return  ログ出力ストリーム参照アドレス
        /// @details ブロック終了行を出力します。
        inline virtual TLogStream & End( const char * name )
        {
            // ブロックカウンタをデクリメントしてヘッダーとブロック終了文字とブロック名を出力します。
            Header( --m_block ) << "} // " << name;

            // 改行します。
            return NewLine();
        }

        /// @brief   文字列出力関数
        /// @param   [in] text 文字列
        /// @return  ログ出力ストリーム参照アドレス
        /// @details 文字列を出力します。
        inline TLogStream & Write( const char * text )
        {
            // 文字列を出力します。
            if ( text ) * m_plog << "\"" << text << "\"";
            else        * m_plog << "(null)";

            return * this;
        }

        /// @brief   文字列出力関数
        /// @param   [in] text 文字列
        /// @return  ログ出力ストリーム参照アドレス
        /// @details 文字列を出力します。
        inline TLogStream & Write( char * text ) { return Write( const_cast< const char * >( text ) ); }

        /// @brief   文字列出力関数
        /// @param   [in] wtext 文字列
        /// @return  ログ出力ストリーム参照アドレス
        /// @details 文字列を出力します。
        inline TLogStream & Write( const wchar_t * wtext )
        {
            // ワイド文字列をマルチバイト文字列に変換します。
            char text[ 1024 ] = { 0 };

            if ( ! WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, wtext, -1, text, 1024, 0, 0 ) )
            {
                // throw( this );
            }

            // 文字列を出力します。
            return Write( text );
        }

        /// @brief   文字列出力関数
        /// @param   [in] wtext 文字列
        /// @return  ログ出力ストリーム参照アドレス
        /// @details 文字列を出力します。
        inline TLogStream & Write( wchar_t * wtext ) { return Write( const_cast< const wchar_t * >( wtext ) ); }

        /// @brief   文字列出力関数
        /// @param   [in] text 文字列
        /// @return  ログ出力ストリーム参照アドレス
        /// @details 文字列を出力します。
        inline TLogStream & Write( string text ) { return Write( text.c_str() ); }

        /// @brief   出力関数
        /// @param   [in] param 引数
        /// @return  ログ出力ストリーム参照アドレス
        /// @details 引数を出力します。
        template< class T > inline TLogStream & Write( T param )
        {
            // 引数を出力します。
            * m_plog << param;

            return * this;
        }

        /// @brief   ヘッダー付き行出力関数
        /// @param   [in] param 引数
        /// @return  ログ出力ストリーム参照アドレス
        /// @details ヘッダー付きで引数を行出力します。
        template< class T > inline TLogStream & Line( T param )
        {
            // ヘッダーを出力します。
            Header();

            // 引数を出力します。
            Write( param );

            // 改行します。
            return NewLine();
        }

        /// @brief   データ出力関数
        /// @param   [in] name  データ名
        /// @param   [in] value 値
        /// @param   [in] lf    改行フラグ
        /// @return  ログ出力ストリーム参照アドレス
        /// @details データ名と値を出力します。
        template< class T > TLogStream & Data( const char * name, T value, bool lf = true )
        {
            // ヘッダーとデータ名を出力します。
            Header() << name << " = ";

            // 値を出力します。
            Write( value );

            // 改行します。
            if ( lf ) NewLine();

            return * this;
        }

        /// @brief   16進データ出力関数
        /// @param   [in] name  データ名
        /// @param   [in] value 値
        /// @param   [in] lf    改行フラグ
        /// @return  ログ出力ストリーム参照アドレス
        /// @details データ名と値を16進数形式で出力します。
        template< class T > TLogStream & Hex( const char * name, T value, bool lf = true )
        {
            // 16進数文字列を作成します。
            char buffer[ 256 ];

            sprintf_s( buffer, ArrayCount( buffer ), "0x%08X", value );

            // ヘッダーとデータ名と値を出力します。
            Header() << name << " = " << buffer;

            // 改行します。
            if ( lf ) NewLine();

            return * this;
        }

        /// @brief   書式付き文字列出力関数
        /// @param   [in] format 書式文字列
        /// @param   [in] args   可変引数
        /// @return  ログ出力ストリーム参照アドレス
        /// @details 書式付き文字列を出力します。
        inline virtual TLogStream & WriteFormatArgs( const char * format, va_list args )
        {
            // 展開後の文字列サイズを取得します。
            size_t size = _vscprintf( format, args ) + 1;

            // 書式付き文字列をバッファーに展開します。
            char * buffer = new char[ size ];

            vsprintf_s( buffer, size, format, args );

            // 展開された文字列を出力します。
            * m_plog << buffer;

            // 文字列バッファーを削除します。
            delete[] buffer;

            return * this;
        }

        /// @brief   書式付き文字列出力関数
        /// @param   [in] format 書式文字列
        /// @param   [in] ...    可変引数
        /// @return  ログ出力ストリーム参照アドレス
        /// @details 書式付き文字列を出力します。
        inline virtual TLogStream & WriteFormat( const char * format, ... )
        {
            // 書式付き文字列を出力します。
            va_list args;

            va_start( args, format );

            return WriteFormatArgs( format, args );
        }

        /// @brief   書式付き文字列行出力関数
        /// @param   [in] format 書式文字列
        /// @param   [in] ...    可変引数
        /// @return  ログ出力ストリーム参照アドレス
        /// @details 書式付き文字列を行出力します。
        inline virtual TLogStream & WriteFormatLine( const char * format, ... )
        {
            // ヘッダーを出力します。
            Header();

            // 書式付き文字列を出力します。
            va_list args;

            va_start( args, format );

            WriteFormatArgs( format, args );

            // 改行します。
            return NewLine();
        }
    };

}   // Common
TLogStream.cpp
//----------------------------------------------------------------------------
/// @file    TLogStream.cpp
/// @brief   ログ出力ストリームクラス
/// @details ログ出力ストリームクラスです。
//----------------------------------------------------------------------------

#include <TLogStream.h>

//----------------------------------------------------------------------------
// 名前空間使用宣言
//----------------------------------------------------------------------------

using namespace std;
using namespace Common;

//----------------------------------------------------------------------------
// ローカル変数
//----------------------------------------------------------------------------

/// @brief   静的初期化構造体
/// @details 静的な初期化終了処理を行います。
static struct TInit
{
    TLogStream * m_plog; ///< ログストリームポインタ

    /// 構築子
    TInit() : m_plog( 0 ) {}

    /// 解体子
    ~TInit()
    {
        // ログストリームを削除します。
        if ( m_plog )
        {
            s_init.m_plog->Line( "ログストリームオブジェクトを削除しました。" );

            delete m_plog;
        }
    }
} s_init; ///< 静的初期化構造体オブジェクト

//----------------------------------------------------------------------------
// グローバル関数
//----------------------------------------------------------------------------

// ログストリーム作成関数
TLogStream & Common::CreateLog( const char * filename, ostream * plog, int tabsize, const char * header, long line, bool date, bool time )
{
    // ログストリームポインタを調べます。
    if ( s_init.m_plog )
    {
        // ログストリームを削除します。
        s_init.m_plog->Line( "ログストリームオブジェクトを削除しました。" );

        delete s_init.m_plog;
    }

    // ログストリームオブジェクトを作成します。
    s_init.m_plog = new TLogStream( filename, plog, tabsize, header, line, date, time );
    s_init.m_plog->Line( "ログストリームオブジェクトを作成しました。" );

    // ログストリームオブジェクトを返します。
    return * s_init.m_plog;
}

// ログオブジェクト取得関数
TLogStream & Common::LogOut()
{
    // ログストリームポインタを調べます。
    if ( ! s_init.m_plog )
    {
        // ログストリームオブジェクトを作成します。
        s_init.m_plog = new TLogStream();
        s_init.m_plog->Line( "ログストリームオブジェクトを作成しました。" );
    }

    // ログストリームオブジェクトを返します。
    return * s_init.m_plog;
}

//----------------------------------------------------------------------------
// ログ出力ストリームクラス
//----------------------------------------------------------------------------
// 構築子と解体子
//----------------------------------------------------------------------------
// デフォルト構築子
TLogStream::TLogStream( const char * filename, ostream * plog, int tabsize, const char * header, long line, bool date, bool time )
    : m_pfile  ( 0 )
    , m_plog   ( 0 )
    , m_tabsize( tabsize )
    , m_header ( header )
    , m_block  ( 0 )
    , m_pdebug ( 0 )
    , m_line   ( line )
    , m_date   ( date )
    , m_time   ( time )
{
    // ファイル名を調べます。
    if ( filename )
    {
        // ファイル出力ストリームを作成します。
        m_plog = m_pfile = new ofstream( filename );
    }
    // ログ出力ストリームポインタを調べます。
    else if ( m_plog )
    {
        // ログ出力ストリームポインタを設定します。
        m_plog = plog;
    }
    else
    {
        // デバッグ出力ストリームを作成してログ出力ストリームポインタに設定します。
        m_plog = m_pdebug = new TDebugStream();
    }
}

/// @brief 解体子
TLogStream::~TLogStream()
{
    // デバッグ出力ストリームを削除します。
    if ( m_pdebug ) delete m_pdebug;

    // ファイル出力ストリームを削除します。
    if ( m_pfile )
    {
        m_pfile->close();

        delete m_pfile;
    }
}

解説

クラス構築時のオプションで、ヘッダー文字列や行番号や日付や時刻を表示できるようになってます。
デフォルトではウザいので出さないようにしています。
あとファイル名を指定すればファイルに出力しますが、
デフォルトではデバッグコンソールに出力します。

次にこれを使ったサンプルプログラムをご紹介します。

ウィンドウサンプルプログラムヘッダ(main.h)

//----------------------------------------------------------------------------
/// @file    main.h
/// @brief   ウィンドウサンプルプログラムヘッダ
/// @details ウィンドウサンプルプログラムです。
//----------------------------------------------------------------------------
/// @mainpage ウィンドウサンプルプログラム
///
/// @section 概要
///          ウィンドウアプリケーションのサンプルプログラムです。
///
/// @section 履歴
/// -        2015/05/01 開発を開始しました。
/// -        2015/05/03 ログ出力を改良しました。
///
/// @version 0.1.1
/// @date    2015/05/03
/// @author  Copyright (C) 2015 hidakas1961 All rights reserved.
//----------------------------------------------------------------------------

#pragma once

#include <windows.h>

//----------------------------------------------------------------------------
// グローバル関数
//----------------------------------------------------------------------------

/// @brief ウィンドウズメイン関数
/// @param [in] hInstance     現在のインスタンスのハンドル\n
///                           アプリケーションの現在のインスタンスのハンドルが入ります。
/// @param [in] hPrevInstance 以前のインスタンスのハンドル\n
///                           アプリケーションの前のインスタンスのハンドルが入ります。\n
///                           Win32 アプリケーションでは、常に NULL です。\n
///                           すでに他のインスタンスが存在するかどうかを調べるには、関数を使って一意の名前の付いたミューテックスを作成してください。\n
///                           CreateMutex 関数は、すでにそのミューテックスが存在していても成功しますが、関数を呼び出すと ERROR_ALREADY_EXISTS が返ります。\n
///                           GetLastError 関数からこの値が返された場合、既に同じアプリケーションの他のインスタンスが存在しており、それが最初のミューテックスを作成しています。
/// @param [in] lpCmdLine     コマンドライン\n
///                           アプリケーションのコマンドラインが格納された NULL で終わる文字列へのポインタが入ります。\n
///                           プログラム名は含まれません。コマンドライン全体を取り出すには、GetCommandLine 関数を使ってください。
/// @param [in] nCmdShow      表示状態\n
///                           ウィンドウの表示状態の指定が入ります。次のいずれかの値が渡されます。\n
///                           <table>
///                           <tr><th>値</th>                <th>意味</th></tr>
///                           <tr><td>SW_HIDE</td>           <td>ウィンドウを非表示にし、他のウィンドウをアクティブにします。</td></tr>
///                           <tr><td>SW_MAXIMIZE</td>       <td>ウィンドウを最大化します。</td></tr>
///                           <tr><td>SW_MINIMIZE</td>       <td>ウィンドウを最小化し、Z オーダーで次のトップレベルウィンドウをアクティブにします。</td></tr>
///                           <tr><td>SW_RESTORE</td>        <td>ウィンドウをアクティブにして表示します。<br>
///                                                              最小化または最大化されていたウィンドウは、元の位置とサイズに戻ります。<br>
///                                                              最小化されているウィンドウを元に戻す場合は、このフラグをセットします。</td></tr>
///                           <tr><td>SW_SHOW</td>           <td>ウィンドウをアクティブにして、現在の位置とサイズで表示します。</td></tr>
///                           <tr><td>SW_SHOWMAXIMIZED</td>  <td>ウィンドウをアクティブにし、最大化して表示します。</td></tr>
///                           <tr><td>SW_SHOWMINIMIZED</td>  <td>ウィンドウをアクティブにし、最小化して表示します。</td></tr>
///                           <tr><td>SW_SHOWMINNOACTIVE</td><td>ウィンドウを最小化して表示します。<br>
///                                                              SW_SHOWMINIMIZED と似ていますが、この値を指定した場合は、ウィンドウはアクティブ化されません。</td></tr>
///                           <tr><td>SW_SHOWNA</td>         <td>ウィンドウを現在の位置とサイズで表示します。<br>
///                                                              SW_SHOW と似ていますが、この値を指定した場合は、ウィンドウはアクティブ化されません。</td></tr>
///                           <tr><td>SW_SHOWNOACTIVATE</td> <td>ウィンドウを直前の位置とサイズで表示します。<br>
///                                                              SW_SHOWNORMAL と似ていますが、この値を指定した場合は、ウィンドウはアクティブ化されません。</td></tr>
///                           <tr><td>SW_SHOWNORMAL</td>     <td>ウィンドウをアクティブにして表示します。<br>
///                                                              ウィンドウが最小化または最大化されていた場合は、その位置とサイズを元に戻します。<br>
///                                                              初めてウィンドウを表示するときには、このフラグを指定します。</td></tr>
///                           </table>
/// @return  関数が WM_QUIT メッセージを受け取って正常に終了する場合は、メッセージの wParam パラメータに格納されている終了コードを返してください。\n
///          関数がメッセージループに入る前に終了する場合は、0 を返してください。
/// @details WinMain 関数は、Win32 アプリケーションの初期エントリポイントです。Windows システムが呼び出します。\n
///          WinMain 関数では、アプリケーションの初期化とメインウィンドウの表示を行ったうえで、
///          アプリケーション実行のその他の部分のためのトップレベルの制御構造であるメッセージ取得/ディスパッチループに入ってください。
///          WM_QUIT メッセージを受け取ったときに、メッセージループを終了させます。\n
///          この時点で、WinMain 関数はアプリケーションを終了させ、WM_QUIT メッセージの wParam パラメータで受け取った値を返さなければなりません。
///          PostQuitMessage 関数を呼び出した結果として WM_QUIT メッセージを受け取った場合は、wParam パラメータの値は、
///          PostQuitMessage 関数の nExitCode パラメータの値となります。\n
///          ANSI アプリケーションは、WinMain 関数の lpCmdLine パラメータによりコマンドライン文字列にアクセスすることができます。
///          ただし、この文字列にはプログラム名は含まれません。\n
///          WinMain 関数が Unicode 文字列を返せないのは、lpCmdLine パラメータがデータ型として LPTSTR ではなく LPSTR を使っているためです。
///          GetCommandLineW 関数を使えば Unicode のコマンドライン文字列を取得できます。
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow );

ウィンドウサンプルプログラム(main.cpp)

//----------------------------------------------------------------------------
/// @file    main.cpp
/// @brief   ウィンドウサンプルプログラム
/// @details ウィンドウサンプルプログラムです。
//----------------------------------------------------------------------------

#include "main.h"
#include "TSampleWindow.h"
#include <TApplication.h>
#include <TLogStream.h>

//----------------------------------------------------------------------------
// 名前空間使用宣言
//----------------------------------------------------------------------------

using namespace Common;
using namespace Window;
using namespace Sample;

//----------------------------------------------------------------------------
// グローバル関数
//----------------------------------------------------------------------------

// ウィンドウズメイン関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
#ifdef _LOGFILE

    // ログファイルを作成します。
    CreateLog( _LOGFILE );

#endif  // _LOGFILE

    // ログに関数ヘッダーを出力します。
    LogOut().Begin( __func__ );

    // ログにタイトルを出力します。
    LogOut().Line( "≪ウィンドウサンプルプログラム≫" );

    // サンプルウィンドウを作成します。
    TSampleWindow sample;

    // アプリケーションを実行します。
    int result = TApplication( & sample ).Run( hInstance, hPrevInstance, lpCmdLine, nCmdShow );

    // ログに関数の結果を出力します。
    LogOut().Data( "result", result );

    // ログに関数フッターを出力します。
    LogOut().End( __func__ );

    return result;
}

解説

なるべく使う側で手間をかけたくないので、
使うときにオブジェクトを生成するようにしました。
それがグローバル関数のLogOut()関数です。
いきなりLogOut()関数が呼ばれた場合は、デフォルトのログ出力ストリームクラスオブジェクトを作成します。
で、プログラムが終了するときに静的なデータと共にオブジェクトも削除するようになってるのでごみは残りません。
ただしデフォルトでなくログファイルに出力したいときは、
明示的にCreateLog()関数を呼んでください。

これを使ったときのログファイルのサンプルをご紹介します。

WindowSample.log

"ログストリームオブジェクトを作成しました。"
{ // WinMain
    "≪ウィンドウサンプルプログラム≫"
    { // Window::TWindow::TWindow
        name = "class Sample::TSampleWindow"
        "ウィンドウクラスオブジェクトを構築しました。"
    } // Window::TWindow::TWindow
    { // Window::TApplication::TApplication
        pWnd = 001DF714
        pWnd->Name() = "class Sample::TSampleWindow"
        "アプリケーションクラスオブジェクトを構築しました。"
    } // Window::TApplication::TApplication
    { // Window::TApplication::Run
        hInstance     = 0x01120000
        hPrevInstance = 0x00000000
        lpCmdLine     = "コマンドライン引数"
        nCmdShow      = 1
        { // Window::TWindow::InitWindow
            hParent = 00000000
            hMenu   = 00000000
            { // Window::TWindow::WindowProc
                hWnd   = 0x000401E8
                uMsg   = "WM_GETMINMAXINFO"
                wParam = 0x00000000
                lParam = 0x001DEF14
            } // Window::TWindow::WindowProc
            { // Window::TWindow::WindowProc
                hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                uMsg   = "WM_NCCREATE"
                wParam = 0x00000000
                lParam = 0x001DEEE8
                { // Window::TWindow::OnMessageProc
                    { // Window::TWindow::OnDefProc
                        result = 1
                    } // Window::TWindow::OnDefProc
                    result = 1
                } // Window::TWindow::OnMessageProc
            } // Window::TWindow::WindowProc
            { // Window::TWindow::WindowProc
                hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                uMsg   = "WM_NCCALCSIZE"
                wParam = 0x00000000
                lParam = 0x001DEF34
                { // Window::TWindow::OnMessageProc
                    { // Window::TWindow::OnDefProc
                        result = 0
                    } // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnMessageProc
            } // Window::TWindow::WindowProc
            { // Window::TWindow::WindowProc
                hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                uMsg   = "WM_CREATE"
                wParam = 0x00000000
                lParam = 0x001DEEAC
                { // Window::TWindow::OnMessageProc
                    { // Window::TWindow::OnDefProc
                        result = 0
                    } // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnMessageProc
            } // Window::TWindow::WindowProc
            m_hWnd  = 000401E8
        } // Window::TWindow::InitWindow
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_SHOWWINDOW"
            wParam = 0x00000001
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_WINDOWPOSCHANGING"
            wParam = 0x00000000
            lParam = 0x001DF44C
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_WINDOWPOSCHANGING"
            wParam = 0x00000000
            lParam = 0x001DF44C
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_ACTIVATEAPP"
            wParam = 0x00000001
            lParam = 0x00000C8C
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_NCACTIVATE"
            wParam = 0x00000001
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    { // Window::TWindow::WindowProc
                        hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                        uMsg   = "WM_GETICON"
                        wParam = 0x00000002
                        lParam = 0x00000000
                        { // Window::TWindow::OnMessageProc
                            { // Window::TWindow::OnDefProc
                                result = 0
                            } // Window::TWindow::OnDefProc
                            result = 0
                        } // Window::TWindow::OnMessageProc
                    } // Window::TWindow::WindowProc
                    { // Window::TWindow::WindowProc
                        hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                        uMsg   = "WM_GETICON"
                        wParam = 0x00000000
                        lParam = 0x00000000
                        { // Window::TWindow::OnMessageProc
                            { // Window::TWindow::OnDefProc
                                result = 0
                            } // Window::TWindow::OnDefProc
                            result = 0
                        } // Window::TWindow::OnMessageProc
                    } // Window::TWindow::WindowProc
                    { // Window::TWindow::WindowProc
                        hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                        uMsg   = "WM_GETICON"
                        wParam = 0x00000001
                        lParam = 0x00000000
                        { // Window::TWindow::OnMessageProc
                            { // Window::TWindow::OnDefProc
                                result = 0
                            } // Window::TWindow::OnDefProc
                            result = 0
                        } // Window::TWindow::OnMessageProc
                    } // Window::TWindow::WindowProc
                    result = 1
                } // Window::TWindow::OnDefProc
                result = 1
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_ACTIVATE"
            wParam = 0x00000001
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    { // Window::TWindow::WindowProc
                        hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                        uMsg   = "WM_IME_SETCONTEXT"
                        wParam = 0x00000001
                        lParam = 0xC000000F
                        { // Window::TWindow::OnMessageProc
                            { // Window::TWindow::OnDefProc
                                { // Window::TWindow::WindowProc
                                    hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                                    uMsg   = "WM_IME_NOTIFY"
                                    wParam = 0x00000002
                                    lParam = 0x00000000
                                    { // Window::TWindow::OnMessageProc
                                        { // Window::TWindow::OnDefProc
                                            result = 0
                                        } // Window::TWindow::OnDefProc
                                        result = 0
                                    } // Window::TWindow::OnMessageProc
                                } // Window::TWindow::WindowProc
                                result = 0
                            } // Window::TWindow::OnDefProc
                            result = 0
                        } // Window::TWindow::OnMessageProc
                    } // Window::TWindow::WindowProc
                    { // Window::TWindow::WindowProc
                        hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                        uMsg   = "WM_SETFOCUS"
                        wParam = 0x00000000
                        lParam = 0x00000000
                        { // Window::TWindow::OnMessageProc
                            { // Window::TWindow::OnDefProc
                                result = 0
                            } // Window::TWindow::OnDefProc
                            result = 0
                        } // Window::TWindow::OnMessageProc
                    } // Window::TWindow::WindowProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_NCPAINT"
            wParam = 0x00000001
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_ERASEBKGND"
            wParam = 0x3F010EFD
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 1
                } // Window::TWindow::OnDefProc
                result = 1
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_WINDOWPOSCHANGED"
            wParam = 0x00000000
            lParam = 0x001DF44C
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_NCCALCSIZE"
            wParam = 0x00000001
            lParam = 0x001DF05C
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_NCPAINT"
            wParam = 0x00000001
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_ERASEBKGND"
            wParam = 0x9B010A39
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 1
                } // Window::TWindow::OnDefProc
                result = 1
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_SIZE"
            wParam = 0x00000000
            lParam = 0x020803B0
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_MOVE"
            wParam = 0x00000000
            lParam = 0x004D0036
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_PAINT"
            wParam = 0x00000000
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Sample::TSampleWindow::OnWmPaint
                } // Sample::TSampleWindow::OnWmPaint
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_GETICON"
            wParam = 0x00000002
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_GETICON"
            wParam = 0x00000000
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_GETICON"
            wParam = 0x00000001
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_IME_NOTIFY"
            wParam = 0x00000001
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_IME_NOTIFY"
            wParam = 0x00000002
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_INPUTLANGCHANGE"
            wParam = 0x00000080
            lParam = 0x04110411
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_NCHITTEST"
            wParam = 0x00000000
            lParam = 0x011A01A8
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 1
                } // Window::TWindow::OnDefProc
                result = 1
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_SETCURSOR"
            wParam = 0x000401E8
            lParam = 0x02000001
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_MOUSEMOVE"
            wParam = 0x00000000
            lParam = 0x00CD0172
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_NCHITTEST"
            wParam = 0x00000000
            lParam = 0x011A01A8
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 1
                } // Window::TWindow::OnDefProc
                result = 1
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_SETCURSOR"
            wParam = 0x000401E8
            lParam = 0x02000001
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_MOUSEMOVE"
            wParam = 0x00000000
            lParam = 0x00CD0172
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_SYSKEYDOWN"
            wParam = 0x00000012
            lParam = 0x20380001
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_SYSKEYDOWN"
            wParam = 0x00000012
            lParam = 0x60380001
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_SYSKEYDOWN"
            wParam = 0x00000073
            lParam = 0x203E0001
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        { // Window::TWindow::WindowProc
            hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
            uMsg   = "WM_SYSCOMMAND"
            wParam = 0x0000F060
            lParam = 0x00000000
            { // Window::TWindow::OnMessageProc
                { // Window::TWindow::OnDefProc
                    { // Window::TWindow::WindowProc
                        hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                        uMsg   = "WM_CLOSE"
                        wParam = 0x00000000
                        lParam = 0x00000000
                        { // Window::TWindow::OnMessageProc
                            { // Window::TWindow::OnDefProc
                                { // Window::TWindow::WindowProc
                                    hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                                    uMsg   = "0x00000090( Unknown )"
                                    wParam = 0x00000000
                                    lParam = 0x00000000
                                    { // Window::TWindow::OnMessageProc
                                        { // Window::TWindow::OnDefProc
                                            result = 0
                                        } // Window::TWindow::OnDefProc
                                        result = 0
                                    } // Window::TWindow::OnMessageProc
                                } // Window::TWindow::WindowProc
                                { // Window::TWindow::WindowProc
                                    hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                                    uMsg   = "WM_WINDOWPOSCHANGING"
                                    wParam = 0x00000000
                                    lParam = 0x001DE674
                                    { // Window::TWindow::OnMessageProc
                                        { // Window::TWindow::OnDefProc
                                            result = 0
                                        } // Window::TWindow::OnDefProc
                                        result = 0
                                    } // Window::TWindow::OnMessageProc
                                } // Window::TWindow::WindowProc
                                { // Window::TWindow::WindowProc
                                    hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                                    uMsg   = "WM_WINDOWPOSCHANGED"
                                    wParam = 0x00000000
                                    lParam = 0x001DE674
                                    { // Window::TWindow::OnMessageProc
                                        { // Window::TWindow::OnDefProc
                                            result = 0
                                        } // Window::TWindow::OnDefProc
                                        result = 0
                                    } // Window::TWindow::OnMessageProc
                                } // Window::TWindow::WindowProc
                                { // Window::TWindow::WindowProc
                                    hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                                    uMsg   = "WM_NCACTIVATE"
                                    wParam = 0x00000000
                                    lParam = 0x00000000
                                    { // Window::TWindow::OnMessageProc
                                        { // Window::TWindow::OnDefProc
                                            result = 1
                                        } // Window::TWindow::OnDefProc
                                        result = 1
                                    } // Window::TWindow::OnMessageProc
                                } // Window::TWindow::WindowProc
                                { // Window::TWindow::WindowProc
                                    hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                                    uMsg   = "WM_ACTIVATE"
                                    wParam = 0x00000000
                                    lParam = 0x00000000
                                    { // Window::TWindow::OnMessageProc
                                        { // Window::TWindow::OnDefProc
                                            result = 0
                                        } // Window::TWindow::OnDefProc
                                        result = 0
                                    } // Window::TWindow::OnMessageProc
                                } // Window::TWindow::WindowProc
                                { // Window::TWindow::WindowProc
                                    hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                                    uMsg   = "WM_ACTIVATEAPP"
                                    wParam = 0x00000000
                                    lParam = 0x00000C8C
                                    { // Window::TWindow::OnMessageProc
                                        { // Window::TWindow::OnDefProc
                                            result = 0
                                        } // Window::TWindow::OnDefProc
                                        result = 0
                                    } // Window::TWindow::OnMessageProc
                                } // Window::TWindow::WindowProc
                                { // Window::TWindow::WindowProc
                                    hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                                    uMsg   = "WM_KILLFOCUS"
                                    wParam = 0x00000000
                                    lParam = 0x00000000
                                    { // Window::TWindow::OnMessageProc
                                        { // Window::TWindow::OnDefProc
                                            result = 0
                                        } // Window::TWindow::OnDefProc
                                        result = 0
                                    } // Window::TWindow::OnMessageProc
                                } // Window::TWindow::WindowProc
                                { // Window::TWindow::WindowProc
                                    hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                                    uMsg   = "WM_DESTROY"
                                    wParam = 0x00000000
                                    lParam = 0x00000000
                                    { // Window::TWindow::OnMessageProc
                                        result = 0
                                    } // Window::TWindow::OnMessageProc
                                } // Window::TWindow::WindowProc
                                { // Window::TWindow::WindowProc
                                    hWnd   = 0x000401E8", ""class Sample::TSampleWindow"
                                    uMsg   = "WM_NCDESTROY"
                                    wParam = 0x00000000
                                    lParam = 0x00000000
                                    { // Window::TWindow::OnMessageProc
                                        { // Window::TWindow::OnDefProc
                                            result = 0
                                        } // Window::TWindow::OnDefProc
                                        result = 0
                                    } // Window::TWindow::OnMessageProc
                                } // Window::TWindow::WindowProc
                                result = 0
                            } // Window::TWindow::OnDefProc
                            result = 0
                        } // Window::TWindow::OnMessageProc
                    } // Window::TWindow::WindowProc
                    result = 0
                } // Window::TWindow::OnDefProc
                result = 0
            } // Window::TWindow::OnMessageProc
        } // Window::TWindow::WindowProc
        result = 0
    } // Window::TApplication::Run
    { // Window::TApplication::~TApplication
        "アプリケーションクラスオブジェクトを解体しました。"
    } // Window::TApplication::~TApplication
    result = 0
} // WinMain
{ // Window::TWindow::~TWindow
    name = "class Sample::TSampleWindow"
    "ウィンドウクラスオブジェクトを解体しました。"
} // Window::TWindow::~TWindow
"ログストリームオブジェクトを削除しました。"

解説

どうでしょう、かなりしつこいログではないでしょうか。
正直デバッグモードでこれを使うとかなり遅くなります。
なので実際には、問題が起こったときにログを出せるようなコードにしとくとよいでしょうね。

あとウィンドウクラスとかはかなり大きいのでブログじゃなくてホームページの方でご紹介させていただきます*1

*1:ところでいまグリザイアの楽園を見ながら記事を書いてるわけですけれども、 やはりエンディングテーマの南條愛乃さんって神ですよね。 こんな超可愛い三十路は、世界中探してもどこにもいないでしょうね。 とはいえアニソンシンガーとしては、オープニングの黒崎真音さまの方が好きなわけですが、 いずれにせよこのアニメはいま神ですな。