Mesoscopic Programming

タコさんプログラミング専門

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

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

エクセルのハイパーリンクを作るやつ

04/26 フォルダの中身をエクセルのハイパーリンクにするやつを作りました。
05/02 UNICODE対応にしたので記事を更新しました。
05/04 ログ機能強化とフォルダ構成の変更を行いました。

main.h

//----------------------------------------------------------------------------
/// @file    main.h
/// @brief   エクセルハイパーリンクメーカーヘッダ
/// @details エクセルハイパーリンクメーカーです。
//----------------------------------------------------------------------------
/// @mainpage エクセルハイパーリンクメーカー
///
/// @section 概要
///          エクセルハイパーリンクを作成します。
///
/// @section history 履歴
/// -        2015/05/01 開発を開始しました。
/// -        2015/05/02 ワイド文字のファイル名が開けない問題が分かったのでワイド文字対応にしました。
/// -        2015/05/03 ログ出力を改良しました。
///
/// @version 0.2.1
/// @date    2015/05/03
/// @author  Copyright (C) 2015 hidakas1961 All rights reserved.
//----------------------------------------------------------------------------

#pragma once

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

/// @brief   ワイド文字メイン関数
/// @param   [in] argc コマンドライン引数の個数
/// @param   [in] argv コマンドライン引数の文字列配列
/// @return  終了コード
/// @details ワイド文字(Unicode?)バージョンのメイン関数です。
int wmain( int argc, wchar_t * argv[] );

main.cpp

//----------------------------------------------------------------------------
/// @file    main.cpp
/// @brief   エクセルハイパーリンクメーカー
/// @details エクセルハイパーリンクメーカーです。
//----------------------------------------------------------------------------

#include "main.h"
#include <TLogStream.h>
#include <locale.h>
#include <codecvt>
#include <conio.h>

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

using namespace std;
using namespace Common;

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

static const size_t maxpath  = 1024;   ///< フルパス最大文字数
static const size_t maxdepth = 100;    ///< 最大ディレクトリ深さ
static bool         hidden   = false;  ///< 非表示ファイル許可フラグ
static bool         sysfile  = false;  ///< システムファイル許可フラグ
static wofstream  * pfout    = 0;      ///< ファイル出力ストリームポインタ
static wostream   * pout     = 0;      ///< 出力ストリームポインタ
static size_t       count    = 0;      ///< リンク数カウンタ
static wchar_t      root[ maxpath ];   ///< 入力ディレクトリ名
static bool         nexts[ maxdepth ]; ///< 次ファイル有無フラグテーブル

//----------------------------------------------------------------------------
// ローカル関数
//----------------------------------------------------------------------------

/// @brief   ファイルスキップ判定関数
/// @param   [in] data ファイル検索データ
/// @return  なし
/// @details ファイルをスキップするか判定します。
static bool IsSkip( WIN32_FIND_DATAW & data )
{
    LogOut().Begin( __func__ );
    LogOut().Hex  ( "data  ", data );

    bool result = false;

    if ( ! wcscmp( data.cFileName, L"." ) || ! wcscmp( data.cFileName, L".." ) )
    {
        result = true;
    }
    else if ( data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN )
    {
        result = ! hidden;
    }
    else if ( data.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM )
    {
        result = ! sysfile;
    }

    LogOut().Data( "result", result );
    LogOut().End ( __func__ );

    return result;
}

/// @brief   属性情報出力関数
/// @param   [in] path  パス
/// @param   [in] pdata ファイル検索データポインタ
/// @return  なし
/// @details 属性情報を出力します。
static void OutputAttributes( const wchar_t * path, WIN32_FIND_DATAW * pdata = 0 )
{
    LogOut().Begin( __func__ );
    LogOut().Data ( "path", path );

    // ファイル属性を取得します。
    DWORD attr;

    if ( pdata )
    {
        // ファイル検索データからファイル属性を取得します。
        attr = pdata->dwFileAttributes;
    }
    else
    {
        // ファイルパスからファイル属性を取得します。
        attr = GetFileAttributesW( path );
    }

    if ( attr != static_cast< DWORD >( -1 ) )
    {
        // ディレクトリでないか調べます。
        if ( ! ( attr & FILE_ATTRIBUTE_DIRECTORY ) )
        {
            // 拡張子を取得します。
            wchar_t ext[ _MAX_EXT ];

            _wsplitpath_s( path, 0, 0, 0, 0, 0, 0, ext, _MAX_EXT );

            if ( ext[ 0 ] == L'.' )
            {
                * pout << ( ext + 1 );
            }
            else
            {
                * pout << L"なし";
            }
        }
    }

    * pout << L"\t";

    LogOut().End( __func__ );
}

/// @brief   インデント出力関数
/// @param   [in] depth ディレクトリ深さ
/// @return  なし
/// @details インデントを出力します。
static void OutputIndent( size_t depth )
{
    LogOut().Begin( __func__ );
    LogOut().Data ( "depth", depth );

    // ディレクトリ深さを巡回します。
    for ( size_t i = 0; i < depth; i++ )
    {
        // ディレクトリ深さを調べます。
        if ( i == depth - 1 )
        {
            // 次のファイル有無フラグを調べます。
            if ( nexts[ i ] )
            {
                * pout << L"├";
            }
            else
            {
                * pout << L"└";
            }
        }
        // 次のファイル有無フラグを調べます。
        else if ( nexts[ i ] )
        {
            * pout << L"│";
        }

        * pout << L"\t";
    }

    LogOut().End( __func__ );
}

/// @brief   ハイパーリンク式出力関数
/// @param   [in] path パス
/// @param   [in] name 表示名
/// @return  なし
/// @details ハイパーリンク式を出力します。
static void OutputHyperLink( const wchar_t * path, const wchar_t * name )
{
    LogOut().Begin( __func__ );
    LogOut().Data ( "path ", path );
    LogOut().Data ( "name ", name );
    LogOut().Data ( "count", count++ );

    * pout << L"=HYPERLINK(\"" << path << L"\",\"" << name << L"\")" << endl;

    LogOut().End( __func__ );
}

/// @brief   ディレクトリ出力関数
/// @param   [in] subdir サブディレクトリ
/// @param   [in] depth  ディレクトリ深さ
/// @return  なし
/// @details ディレクトリを出力します。
static void OutputDirectory( const wchar_t * subdir = 0, size_t depth = 0 )
{
    LogOut().Begin( __func__ );
    LogOut().Data ( "subdir", subdir );
    LogOut().Data ( "depth ", depth );

    // 開始ディレクトリをコピーします。
    wchar_t path[ maxpath ];

    wcscpy_s( path, root );

    size_t len = wcslen( path );

    if ( path[ len - 1 ] != '\\' )
    {
        wcscat_s( path, L"\\" );

        len++;
    }

    // サブディレクトリを追加します。
    size_t len2 = len;

    if ( subdir )
    {
        wcscat_s( path, subdir );

        len2 = wcslen( path );

        if ( path[ len2 - 1 ] != '\\' )
        {
            wcscat_s( path, L"\\" );

            len2++;
        }
    }

    // ワイルドカードを追加します。
    wcscat_s( path, L"*.*" );

    // ファイルを検索します。
    WIN32_FIND_DATAW data, next;

    HANDLE handle = FindFirstFileW( path, & data );

    if ( handle != INVALID_HANDLE_VALUE )
    {
        // 先頭ファイルを検索します。
        bool result;

        while ( ( result = FindNextFileW( handle, & data ) != FALSE ) && IsSkip( data ) );

        // 検索ファイルを巡回します。
        for ( ; result; data = next )
        {
            // 次のファイルを検索します。
            while ( ( result = FindNextFileW( handle, & next ) != FALSE ) && IsSkip( next ) );

            // 次のファイル有無テーブルを設定します。
            nexts[ depth ] = result;

            // パスを作成します。
            path[ len2 ] = '\0';

            wcscat_s( path, data.cFileName );

            // 属性情報を出力します。
            OutputAttributes( path, & data );

            // インデントを出力します。
            OutputIndent( depth + 1 );

            // ハイパーリンク式を出力します。
            OutputHyperLink( path, data.cFileName );

            // サブディレクトリでかつリパースポイントでないか調べます。
            if ( ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) && ! ( data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ) )
            {
                // サブディレクトリを出力します。
                OutputDirectory( path + len, depth + 1 );
            }
        }

        FindClose( handle );
    }

    LogOut().End( __func__ );
}

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

// ワイド文字メイン関数
int wmain( int argc, wchar_t * argv[] )
{
#ifdef _LOGFILE

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

#endif  // _LOGFILE

    LogOut().Begin( __func__ );

    // ロケールを設定します。
    setlocale( LC_ALL, "Japanese" );

    // タイトルを表示します。
    LogOut().Line ( "≪エクセルハイパーリンクメーカー≫" );

    cout << "≪エクセルハイパーリンクメーカー≫" << endl << endl;

    bool            error   = false; ///< エラーフラグ
    const wchar_t * dirname = 0;     ///< ディレクトリ名
    const wchar_t * outfile = 0;     ///< 出力ファイル名

    // コマンドライン引数を巡回します。
    for ( int i = 1; i < argc; i++ )
    {
        // オプションスイッチか調べます。
        if ( argv[ i ][ 0 ] == '-' )
        {
            // オプションスイッチの種類を調べます。
            if ( ! wcscmp( argv[ i ] + 1, L"o" ) )
            {
                // 出力ファイル名を設定します。
                if ( ! outfile )
                {
                    if ( i + 1 < argc && argv[ i + 1 ][ 0 ] != '-' )
                    {
                        outfile = argv[ ++i ];
                    }
                    else
                    {
                        error = true;

                        cout << endl << "出力ファイル名がありません。" << endl;
                        wcout << L"\"" << argv[ i ] << L"\"" << endl;

                        break;
                    }
                }
                else
                {
                    error = true;

                    cout << endl << "出力パスオプションが重複しています。" << endl;
                    wcout << L"\"" << argv[ i ] << L"\"" << endl;

                    break;
                }
            }
            else if ( ! wcscmp( argv[ i ] + 1, L"hidden" ) )
            {
                // 非表示ファイル許可フラグをセットします。
                if ( ! hidden )
                {
                    hidden = true;

                    wcout << L"\"" << argv[ i ] << L"\" : 非表示ファイル許可" << endl;
                }
                else
                {
                    error = true;

                    cout << endl << "非表示ファイル許可オプションが重複しています。" << endl;
                    wcout << L"\"" << argv[ i ] << L"\"" << endl;

                    break;
                }
            }
            else if ( ! wcscmp( argv[ i ] + 1, L"system" ) )
            {
                // システムファイル許可フラグをセットします。
                if ( ! sysfile )
                {
                    sysfile = true;

                    wcout << L"\"" << argv[ i ] << L"\" : システムファイル許可" << endl;
                }
                else
                {
                    error = true;

                    cout << endl << "システムファイル許可オプションが重複しています。" << endl;
                    wcout << L"\"" << argv[ i ] << L"\"" << endl;

                    break;
                }
            }
            else
            {
                error = true;

                cout << endl << "不明なオプションです。" << endl;
                wcout << L"\"" << argv[ i ] << L"\"" << endl;

                break;
            }
        }
        // ディレクトリ名を調べます。
        else if ( ! dirname )
        {
            // ディレクトリ名を設定します。
            dirname = argv[ i ];
        }
        else
        {
            error = true;

            cout << endl << "余分な引数です。" << endl;
            wcout << L"\"" << argv[ i ] << L"\"" << endl;

            break;
        }
    }

    // エラーフラグを調べます。
    while ( ! error )
    {
        // ディレクトリ名を調べます。
        if ( ! dirname )
        {
            // カレントディレクトリを設定します。
            dirname = L".";
        }

        // 入力ディレクトリ名のフルパスを取得します。
        if ( GetFullPathNameW( dirname, maxpath, root, 0 ) )
        {
            wcout << L"入力ディレクトリ : \"" << root << L"\"" << endl;

            // 入力ディレクトリが存在するか調べます。
            DWORD attr = GetFileAttributesW( root );

            if ( attr != static_cast< DWORD >( -1 ) )
            {
                // ディレクトリか調べます。
                if ( attr & FILE_ATTRIBUTE_DIRECTORY )
                {
                    // 出力ファイル名を調べます。
                    if ( outfile )
                    {
                        // フルパスを取得します。
                        wchar_t path[ maxpath ];

                        if ( GetFullPathNameW( outfile, maxpath, path, 0 ) )
                        {
                            wcout << L"出力ファイル名   : \"" << path << L"\"" << endl;

                            // 出力パスがディレクトリ名でないか調べます。
                            DWORD attr = GetFileAttributesW( path );

                            if ( attr != static_cast< DWORD >( -1 ) )
                            {
                                if ( attr & FILE_ATTRIBUTE_DIRECTORY )
                                {
                                    error = true;

                                    cout << endl << "出力ファイル名はディレクトリです。" << endl;

                                    break;
                                }
                            }

                            // ファイル出力ストリームを作成します。
                            pfout = new wofstream( path, ios::binary );

                            // 出力モードを設定します。
                            pfout->imbue( locale( locale(""), new codecvt_utf16< wchar_t, 0x10ffff, static_cast< codecvt_mode >( generate_header | little_endian ) >() ) );

                            // 出力ストリームポインタを設定します。
                            pout = pfout;
                        }
                        else
                        {
                            error = true;

                            cout << endl << "不正なファイル名です。" << endl;

                            break;
                        }
                    }
                    else
                    {
                        // 出力ストリームポインタを設定します。
                        pout = & wcout;
                    }
                }
                else
                {
                    error = true;

                    cout << endl << "ディレクトリではありません。" << endl;

                    break;
                }
            }
            else
            {
                error = true;

                cout << endl << "入力ディレクトリが存在しません。" << endl;

                break;
            }
        }
        else
        {
            error = true;

            cout << endl << "不正なディレクトリ名です。" << endl;

            break;
        }

        // タイトル行を出力します。
        * pout << L"拡張子\tパス" << endl;

        // 開始ディレクトリの属性情報を出力します。
        OutputAttributes( root );

        // 開始ディレクトリのインデントを出力します。
        OutputIndent( 0 );

        // 開始ディレクトリのハイパーリンクを出力します。
        OutputHyperLink( root, root );

        // サブディレクトリを出力します。
        OutputDirectory();

        // 出力ストリームを削除します。
        if ( pfout )
        {
            pfout->close();

            delete pfout;
        }

        cout << endl << "正常に終了しました。" << endl;

        break;
    }

#ifdef _DEBUG

    // キー入力を要求します。
    cout << endl << "何か押してください。" << endl;

    _getch();

#endif  // _DEBUG

    LogOut().End( __func__ );

    return 0;
}

ソースコード

以下のプロジェクトをソリューションに追加してビルドしてください。
開発環境は Windows Vista VC++ 2010 Express です。
共通ライブラリ
Excelハイパーリンクメーカー

以上です。

VC++のフィルター設定とかめんどくさいので

04/25 補助用のツールを作りました。
05/02 UNICODE 対応にしました。
05/04 ログ機能強化とフォルダ構成の変更を行いました。

main.h

//----------------------------------------------------------------------------
/// @file    main.h
/// @brief   VCプロジェクトファイルメーカーヘッダ
/// @details VCプロジェクトファイルメーカーです。
//----------------------------------------------------------------------------
/// @mainpage VCプロジェクトファイルメーカー
///
/// @section 概要
///          VCプロジェクトファイルを作成します。
///
/// @section history 履歴
/// -        2015/05/01 開発を開始しました。
/// -        2015/05/02 ワイド文字のファイル名が開けない問題が分かったのでワイド文字対応にしました。
/// -        2015/05/03 ログ出力を改良しました。
///
/// @version 0.2.1
/// @date    2015/05/03
/// @author  Copyright (C) 2015 hidakas1961 All rights reserved.
//----------------------------------------------------------------------------

#pragma once

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

/// @brief   ワイド文字メイン関数
/// @param   [in] argc コマンドライン引数の個数
/// @param   [in] argv コマンドライン引数の文字列配列
/// @return  終了コード
/// @details ワイド文字(Unicode?)バージョンのメイン関数です。
int wmain( int argc, wchar_t * argv[] );

main.cpp

//----------------------------------------------------------------------------
/// @file    main.cpp
/// @brief   VCプロジェクトファイルメーカー
/// @details VCプロジェクトファイルメーカーです。
//----------------------------------------------------------------------------

#include "main.h"
#include <TLogStream.h>
#include <locale.h>
#include <codecvt>
#include <conio.h>

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

using namespace std;
using namespace Common;

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

/// アイテムグループ出力タイプ
enum enumItemType
{
    ITEM_FILTER,       ///< フィルターファイル用のフィルターアイテムグループ
    ITEM_FILTER_FILE,  ///< フィルターファイル用のファイルアイテムグループ
    ITEM_PROJECT_FILE, ///< プロジェクトファイル用のファイルアイテムグループ
};

static const size_t maxpath  = 1024;   ///< フルパス最大文字数
static const size_t maxdepth = 100;    ///< 最大ディレクトリ深さ
static bool         hidden   = false;  ///< 非表示ファイル許可フラグ
static bool         sysfile  = false;  ///< システムファイル許可フラグ
static wofstream  * pfout    = 0;      ///< ファイル出力ストリームポインタ
static wostream   * pout     = 0;      ///< 出力ストリームポインタ
static size_t       count    = 0;      ///< リンク数カウンタ
static wchar_t      root[ maxpath ];   ///< 入力ディレクトリ名
static bool         nexts[ maxdepth ]; ///< 次ファイル有無フラグテーブル

//----------------------------------------------------------------------------
// ローカル関数
//----------------------------------------------------------------------------

/// @brief   ファイルスキップ判定関数
/// @param   [in] data ファイル検索データ
/// @return  なし
/// @details ファイルをスキップするか判定します。
static bool IsSkip( WIN32_FIND_DATAW & data )
{
    LogOut().Begin( __func__ );
    LogOut().Hex  ( "data  ", data );

    bool result = false;

    if ( ! wcscmp( data.cFileName, L"." ) || ! wcscmp( data.cFileName, L".." ) )
    {
        result = true;
    }
    else if ( data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN )
    {
        result = ! hidden;
    }
    else if ( data.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM )
    {
        result = ! sysfile;
    }

    LogOut().Data( "result", result );
    LogOut().End ( __func__ );

    return result;
}

/// @brief   ディレクトリ出力関数
/// @param   [in] item   アイテムタイプ
/// @param   [in] subdir サブディレクトリ
/// @param   [in] depth  ディレクトリ深さ
/// @return  なし
/// @details ディレクトリを出力します。
static void OutputDirectory( int item, const wchar_t * subdir = 0, size_t depth = 0 )
{
    LogOut().Begin( __func__ );
    LogOut().Data ( "item  ", item );
    LogOut().Data ( "subdir", subdir );
    LogOut().Data ( "depth ", depth );

    // 開始ディレクトリをコピーします。
    wchar_t path[ maxpath ];

    wcscpy_s( path, root );

    size_t len = wcslen( path );

    if ( path[ len - 1 ] != '\\' )
    {
        wcscat_s( path, L"\\" );

        len++;
    }

    // サブディレクトリを追加します。
    size_t len2 = len;

    if ( subdir )
    {
        wcscat_s( path, subdir );

        len2 = wcslen( path );

        if ( path[ len2 - 1 ] != '\\' )
        {
            wcscat_s( path, L"\\" );

            len2++;
        }
    }

    // ワイルドカードを追加します。
    wcscat_s( path, L"*.*" );

    // ファイルを検索します。
    WIN32_FIND_DATAW data, next;

    HANDLE handle = FindFirstFileW( path, & data );

    if ( handle != INVALID_HANDLE_VALUE )
    {
        // 先頭ファイルを検索します。
        bool result;

        while ( ( result = FindNextFileW( handle, & data ) != FALSE ) && IsSkip( data ) );

        // 検索ファイルを巡回します。
        for ( ; result; data = next )
        {
            // 次のファイルを検索します。
            while ( ( result = FindNextFileW( handle, & next ) != FALSE ) && IsSkip( next ) );

            // 次のファイル有無テーブルを設定します。
            nexts[ depth ] = result;

            // パスを作成します。
            path[ len2 ] = '\0';

            wcscat_s( path, data.cFileName );

            // アイテムの種類を調べます。
            if ( item == ITEM_FILTER )
            {
                if ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
                {
                    * pout << L"    <Filter Include=\"" << ( path + len ) << L"\" />" << endl;
                }
            }
            else if ( item == ITEM_FILTER_FILE )
            {
                if ( ! ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
                {
                    if ( subdir )
                    {
                        * pout << L"    <None Include=\"" << ( path + len ) << L"\">" << endl;
                        * pout << L"      <Filter>" << subdir << L"</Filter>" << endl;
                        * pout << L"    </None>" << endl;
                    }
                    else
                    {
                        * pout << L"    <None Include=\"" << ( path + len ) << L"\" />" << endl;
                    }
                }
            }
            else if ( item == ITEM_PROJECT_FILE )
            {
                if ( ! ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
                {
                    * pout << L"    <None Include=\"" << ( path + len ) << L"\" />" << endl;
                }
            }

            // サブディレクトリでかつリパースポイントでないか調べます。
            if ( ( data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) && ! ( data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ) )
            {
                // サブディレクトリを出力します。
                OutputDirectory( item, path + len, depth + 1 );
            }
        }

        FindClose( handle );
    }

    LogOut().End( __func__ );
}

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

// ワイド文字メイン関数
int wmain( int argc, wchar_t * argv[] )
{
#ifdef _LOGFILE

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

#endif  // _LOGFILE

    LogOut().Begin( __func__ );

    // ロケールを設定します。
    setlocale( LC_ALL, "Japanese" );

    // タイトルを表示します。
    LogOut().Line ( "≪VCプロジェクトファイルメーカー≫" );

    cout << "≪VCプロジェクトファイルメーカー≫" << endl << endl;

    bool            error   = false; ///< エラーフラグ
    const wchar_t * dirname = 0;     ///< ディレクトリ名
    const wchar_t * outfile = 0;     ///< 出力ファイル名

    // コマンドライン引数を巡回します。
    for ( int i = 1; i < argc; i++ )
    {
        // オプションスイッチか調べます。
        if ( argv[ i ][ 0 ] == '-' )
        {
            // オプションスイッチの種類を調べます。
            if ( ! wcscmp( argv[ i ] + 1, L"o" ) )
            {
                // 出力ファイル名を設定します。
                if ( ! outfile )
                {
                    if ( i + 1 < argc && argv[ i + 1 ][ 0 ] != '-' )
                    {
                        outfile = argv[ ++i ];
                    }
                    else
                    {
                        error = true;

                        cout << endl << "出力ファイル名がありません。" << endl;
                        wcout << L"\"" << argv[ i ] << L"\"" << endl;

                        break;
                    }
                }
                else
                {
                    error = true;

                    cout << endl << "出力パスオプションが重複しています。" << endl;
                    wcout << L"\"" << argv[ i ] << L"\"" << endl;

                    break;
                }
            }
            else if ( ! wcscmp( argv[ i ] + 1, L"hidden" ) )
            {
                // 非表示ファイル許可フラグをセットします。
                if ( ! hidden )
                {
                    hidden = true;

                    wcout << L"\"" << argv[ i ] << L"\" : 非表示ファイル許可" << endl;
                }
                else
                {
                    error = true;

                    cout << endl << "非表示ファイル許可オプションが重複しています。" << endl;
                    wcout << L"\"" << argv[ i ] << L"\"" << endl;

                    break;
                }
            }
            else if ( ! wcscmp( argv[ i ] + 1, L"system" ) )
            {
                // システムファイル許可フラグをセットします。
                if ( ! sysfile )
                {
                    sysfile = true;

                    wcout << L"\"" << argv[ i ] << L"\" : システムファイル許可" << endl;
                }
                else
                {
                    error = true;

                    cout << endl << "システムファイル許可オプションが重複しています。" << endl;
                    wcout << L"\"" << argv[ i ] << L"\"" << endl;

                    break;
                }
            }
            else
            {
                error = true;

                cout << endl << "不明なオプションです。" << endl;
                wcout << L"\"" << argv[ i ] << L"\"" << endl;

                break;
            }
        }
        // ディレクトリ名を調べます。
        else if ( ! dirname )
        {
            // ディレクトリ名を設定します。
            dirname = argv[ i ];
        }
        else
        {
            error = true;

            cout << endl << "余分な引数です。" << endl;
            wcout << L"\"" << argv[ i ] << L"\"" << endl;

            break;
        }
    }

    // エラーフラグを調べます。
    while ( ! error )
    {
        // ディレクトリ名を調べます。
        if ( ! dirname )
        {
            // カレントディレクトリを設定します。
            dirname = L".";
        }

        // 入力ディレクトリ名のフルパスを取得します。
        if ( GetFullPathNameW( dirname, maxpath, root, 0 ) )
        {
            wcout << L"入力ディレクトリ : \"" << root << L"\"" << endl;

            // 入力ディレクトリが存在するか調べます。
            DWORD attr = GetFileAttributesW( root );

            if ( attr != static_cast< DWORD >( -1 ) )
            {
                // ディレクトリか調べます。
                if ( attr & FILE_ATTRIBUTE_DIRECTORY )
                {
                    // 出力ファイル名を調べます。
                    if ( outfile )
                    {
                        // フルパスを取得します。
                        wchar_t path[ maxpath ];

                        if ( GetFullPathNameW( outfile, maxpath, path, 0 ) )
                        {
                            wcout << L"出力ファイル名   : \"" << path << L"\"" << endl;

                            // 出力パスがディレクトリ名でないか調べます。
                            DWORD attr = GetFileAttributesW( path );

                            if ( attr != static_cast< DWORD >( -1 ) )
                            {
                                if ( attr & FILE_ATTRIBUTE_DIRECTORY )
                                {
                                    error = true;

                                    cout << endl << "出力ファイル名はディレクトリです。" << endl;

                                    break;
                                }
                            }

                            // ファイル出力ストリームを作成します。
                            pfout = new wofstream( path, ios::binary );

                            // 出力モードを設定します。
                            pfout->imbue( locale( locale(""), new codecvt_utf16< wchar_t, 0x10ffff, static_cast< codecvt_mode >( generate_header | little_endian ) >() ) );

                            // 出力ストリームポインタを設定します。
                            pout = pfout;
                        }
                        else
                        {
                            error = true;

                            cout << endl << "不正なファイル名です。" << endl;

                            break;
                        }
                    }
                    else
                    {
                        // 出力ストリームポインタを設定します。
                        pout = & wcout;
                    }
                }
                else
                {
                    error = true;

                    cout << endl << "ディレクトリではありません。" << endl;

                    break;
                }
            }
            else
            {
                error = true;

                cout << endl << "入力ディレクトリが存在しません。" << endl;

                break;
            }
        }
        else
        {
            error = true;

            cout << endl << "不正なディレクトリ名です。" << endl;

            break;
        }

        // フィルターファイル用のテキストを出力します。
        * pout << L"以下のテキストを \"~.vcxproj.filters\" にコピーしてください。" << endl;
        * pout << L"~ここから~" << endl;
        * pout << L"<?xml version=\"1.0\" encoding=\"utf-8\"?>" << endl;
        * pout << L"<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">" << endl;
        * pout << L"  <ItemGroup>" << endl;

        // フィルターグループを出力します。
        OutputDirectory( ITEM_FILTER );

        * pout << L"  </ItemGroup>" << endl;

        // ファイルグループを出力します。
        * pout << L"  <ItemGroup>" << endl;

        OutputDirectory( ITEM_FILTER_FILE );

        * pout << L"  </ItemGroup>" << endl;
        * pout << L"</Project>" << endl;
        * pout << L"~ここまで~" << endl;

        // プロジェクトファイル用のテキストを出力します。
        * pout << endl << L"以下のテキストを \"~.vcxproj\" の適当な場所に挿入してください。" << endl;
        * pout << L"~ここから~" << endl;
        * pout << L"  <ItemGroup>" << endl;

        // ファイルグループを出力します。
        OutputDirectory( ITEM_PROJECT_FILE );

        * pout << L"  </ItemGroup>" << endl;
        * pout << L"~ここまで~" << endl;

        // 出力ストリームを削除します。
        if ( pfout )
        {
            pfout->close();

            delete pfout;
        }

        cout << endl << "正常に終了しました。" << endl;

        break;
    }

#ifdef _DEBUG

    // キー入力を要求します。
    cout << endl << "何か押してください。" << endl;

    _getch();

#endif  // _DEBUG

    LogOut().End( __func__ );

    return 0;
}
ソースコード

以下のプロジェクトをソリューションに追加してビルドしてください。
開発環境は Windows Vista VC++ 2010 Express です。
共通ライブラリ
VCプロジェクトファイルメーカー

以上です。

エクセルのハイパーリンクのJPGファイルをIE以外で開くには?

エクセル用のハイパーリンク作成ツールを作っていて気がついたのですが、
何故だかハイパーリンクのJPGファイルを開こうとすると、
JPGファイルの既定のプログラムの設定を無視して、
超大っ嫌いなIEが立ち上がってしまうんですよね。
せっかくデフォルトのブラウザをクロームに設定しているっつぅのに。(--〆)

そこでグーグル先生でいろいろ調べたんだけど、
ハイパーリンクのファイルの関連付けは単純には変えられないらしくて、
結局レジストリをいじることになりました。

解決策はレジストリエディタで

\HKEY_CLASSES_ROOT\.jpg

を丸ごと削除することでした。
削除するのは怖いので名前を変えてみたのですが、
ちゃんとハイパーリンクでJPGの既定のプログラムが立ち上がるようになりました。

おしまい。

DLLとストリームのサンプルプログラム

DLLにしてみるテスト

いつもよく使う関数やマクロを共通ライブラリにしようと思って、
どうせならDLLの練習を兼ねてDLLにしてみました。

家で使っているのはVC++ 2010 Expressなんですが、
こいつは2012 Expressなどと違って空のソリューションが作れない仕様になっているのね。
だから最初に何らかのプロジェクトも一緒に作ってやる必要があるんですよね。

ところが新規でプロジェクトを作るときってのは、
最初にプロジェクト名を聞いてきて、デフォルトではソリューション名も同じにされちゃうんですよね。
それでわざわざソリューション名のところで別の名前を入力する必要があるわけなんです。

で、CommonというDLLプロジェクトを最初に作って、
次にSampleというアプリケーションプロジェクトを追加したわけなんですが、
何もない空っぽのDLLプロジェクトをビルドしようとすると、Common.libが無いとか言って怒られるんですよね。
本当は無くても動くんだけど、しょうがないのでDllMain()を追加しました。

Common.h

//----------------------------------------------------------------------------
/// @file    Common.h
/// @brief   共通ライブラリモジュールヘッダ
/// @details すべてに共通のライブラリです。
//----------------------------------------------------------------------------

#pragma once

#include <windows.h>

//----------------------------------------------------------------------------
// マクロ定義
//----------------------------------------------------------------------------

#ifdef COMMON_EXPORTS
#define COMMON_API __declspec(dllexport) ///< DLL宣言マクロ
#else  // COMMON_EXPORTS
#define COMMON_API __declspec(dllimport) ///< DLL宣言マクロ
#endif // COMMON_EXPORTS

#ifndef __func__
#define __func__ __FUNCTION__ ///< 関数名事前定義マクロ
#endif // __func__

/// @brief   トークン文字列取得マクロ
/// @details トークンを文字列として取得します。
#define STRING( token ) #token

/// @brief   マクロトークン文字列取得マクロ
/// @details マクロを展開して得られたトークンを文字列として取得します。
#define MACRO_STRING( macro ) STRING( macro )

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

/// @brief   DLLメイン関数
/// @param   [in] hModule            モジュールハンドル
/// @param   [in] ul_reason_for_call 関数を呼び出す理由
/// @param   [in] lpReserved         予約済み
/// @retval  TRUE  成功
/// @retval  FALSE 失敗
/// @details DLLモジュールのエントリーポイントです。
COMMON_API BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved );

//----------------------------------------------------------------------------
/// @brief   共通ライブラリ名前空間
/// @details 共通ライブラリ名前空間です。
//----------------------------------------------------------------------------
namespace Common {}

Common.cpp

//----------------------------------------------------------------------------
/// @file  Common.cpp
/// @brief 共通ライブラリモジュール
//----------------------------------------------------------------------------

#include "Common.h"

// DLLメイン関数
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
    switch ( ul_reason_for_call )
    {
    case DLL_PROCESS_ATTACH :

        // ここでDLLの初期化処理を行います。

        break;

    case DLL_THREAD_ATTACH :
    case DLL_THREAD_DETACH :

        break;

    case DLL_PROCESS_DETACH :

        // ここでDLLの終了処理を行います。

        break;
    }

    return TRUE;
}

サンプルプロジェクトのほうは、デバッグコンソールにストリームでログを出力するだけのものです。

main.h

//----------------------------------------------------------------------------
/// @file    main.h
/// @brief   メインモジュールヘッダ
/// @details メインモジュールです。
//----------------------------------------------------------------------------

#pragma once

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

/// @brief   メイン関数
/// @return  なし
/// @details メイン関数です。
extern void main();

/// @brief   テスト関数
/// @param   [in] param 引数
/// @return  戻り値
/// @details テスト用の関数です。
extern int func( int param );

main.cpp

//----------------------------------------------------------------------------
/// @file    main.cpp
/// @brief   メインモジュール
/// @details メインモジュールです。
//----------------------------------------------------------------------------
/// @mainpage コンソールサンプルプログラム
///
/// @section summary 概要
///          コンソールアプリケーションのサンプルプログラムです。
///
/// @section history 履歴
/// -        2015/04/04 開発を開始しました。
/// -        2015/04/05 まだ開発中です。
///
/// @version 1.0.0
/// @date    2015/04/05
/// @author  Copyright (C) 2015 hidakas1961 All rights reserved.
//----------------------------------------------------------------------------

#include "main.h"
#include <TDebugOut.h>
#include <TLogOut.h>
#include <conio.h>

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

using namespace std;
using namespace Common;

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

static TDebugOut debugout;           ///< デバッグ出力ストリーム
static TLogOut   logout( debugout ); ///< ログ出力ストリーム

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

// メイン関数
void main()
{
    // 共通DLLはプロジェクト設定のほうでロード済みなので(やっても良いみたいですが)不要です。
    // LoadLibraryA( "Common" );

    logout << "サンプルプログラムです。" << endl;
    logout << __FILE__ << ":" << __LINE__ << endl << endl;

    logout.Begin( __func__ );

    int result = func( 123 );

    logout.DataValue( "func()", result );
    logout.End( __func__ );

    cout << endl << "何か押してください。" << endl;

    _getch();
}

// テスト関数
int func( int param )
{
    logout.Begin( __func__ );

    int result = -param;

    logout.DataValue( "result", result );

    logout.End( __func__ );

    return result;
}

うちのパソコンはCPUがセレロンでOSがビスタという超しょぼいノートパソコンなので、
C++の標準ライブラリを使おうとすると、信じられないくらい遅くなって精神的に良くないので、
今まで避けて通ってきたのですが、仕事でC++を使うことになって止むなく標準ライブラリに着手しました。

今まで画面出力関係はすべてprintf()でまかなってきたのですが、やはりcoutとかいうストリーム使うと、
いちいちcharとTCHARで関数を使い分ける必要もなくて、超便利なことに気が付いてしまいました。
そこでまずはログ出力用の出力ストリームクラスを作ってみました。

TLogOut.h

//----------------------------------------------------------------------------
/// @file    TLogOut.h
/// @brief   ログ出力クラスヘッダ
/// @details ログ出力クラスです。
//----------------------------------------------------------------------------

#pragma once

#include "Common.h"
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdarg.h>

//----------------------------------------------------------------------------
// 共通ライブラリ名前空間
//----------------------------------------------------------------------------
namespace Common
{
    //------------------------------------------------------------------------
    /// @brief   ログ出力クラス
    /// @details ログ出力クラスです。
    //------------------------------------------------------------------------
    class TLogOut
    {
        //--------------------------------------------------------------------
        // 定数
        //--------------------------------------------------------------------

    private :

        static const int m_defIndent = 2; ///< デフォルトインデント数

        //--------------------------------------------------------------------
        // 動的変数
        //--------------------------------------------------------------------

    private :

        std::ofstream * m_ofs;    ///< ファイル出力ストリームポインタ
        std::ostream  * m_out;    ///< 出力ストリームポインタ
        int             m_indent; ///< インデント数
        int             m_block;  ///< ブロック数
        const char    * m_header; ///< ヘッダー文字列

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

    public :

        /// @brief デフォルト構築子
        /// @param [in] stream ストリーム参照アドレス
        /// @param [in] indent インデント数
        /// @param [in] header ヘッダー文字列
        inline explicit TLogOut( std::ostream & stream = std::clog, int indent = m_defIndent, const char * header = 0 )
            : m_ofs( 0 ), m_out( & stream ), m_indent( indent ), m_block( 0 ), m_header( header ) {}

        /// @brief ログファイル名指定構築子
        /// @param [in] filename ファイル名
        /// @param [in] indent   インデントタブ空白数
        /// @param [in] header   ヘッダー文字列
        inline explicit TLogOut( const char * filename, int indent = m_defIndent, const char * header = 0 )
            : m_ofs( new std::ofstream( filename ) ), m_out( m_ofs ), m_indent( indent ), m_block( 0 ), m_header( header ) {}

        /// @brief 解体子
        inline virtual ~TLogOut() { if ( m_ofs ) m_ofs->close(); }

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

    public :

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

        //--------------------------------------------------------------------
        // 動的テンプレート関数
        //--------------------------------------------------------------------

    public :

        /// @brief   データ出力関数
        /// @param   [in] name  データ名
        /// @param   [in] value 値
        /// @return  ログ出力ストリーム参照アドレス
        /// @details データ名と値を出力します。
        template< class T > std::ostream & DataValue( const char * name, T value ) const
        {
            // ヘッダーを出力します。
            Header( m_block );

            // データ名と値を出力します。
            return * m_out << name << " = " << value << std::endl;
        }

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

    public :

        /// @brief   インデント数設定関数
        /// @param   [in] indent インデント数
        /// @return  ログ出力ストリーム参照アドレス
        /// @details インデント数を設定します。
        inline virtual std::ostream & Indent( int indent ) { m_indent = indent; return * m_out; }

        /// @brief   ヘッダー文字列設定関数
        /// @param   [in] header ヘッダー文字列
        /// @return  ログ出力ストリーム参照アドレス
        /// @details ヘッダー文字列を設定します。
        inline virtual std::ostream & Header( const char * header ) { m_header = header; return * m_out; }

        /// @brief   ヘッダー出力関数
        /// @param   [in] block ブロック数
        /// @return  ログ出力ストリーム参照アドレス
        /// @details ログヘッダー文字列を出力します。
        inline virtual std::ostream & Header( int block ) const
        {
            // ヘッダー文字列を出力します。
            if ( m_header ) * m_out << m_header;

            // ブロック数を巡回します。
            for ( int n = 0; n < block; n++ )
            {
                // インデント数を巡回します。
                for ( int m = 0; m < m_indent; m++ )
                {
                    // 空白を出力します。
                    * m_out << " ";
                }
            }

            return * m_out;
        }

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

            // ブロック開始文字とブロック名を出力します。
            return * m_out << "{ " << name << std::endl;
        }

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

            // ブロック終了文字とブロック名を出力します。
            return * m_out << "} " << name << std::endl;
        }

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

            // 展開後の文字列サイズを取得します。
            va_list args;

            va_start( args, format );

            size_t size = _vscprintf( format, args ) + 1;

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

            vsprintf_s( buffer, size, format, args );

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

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

            va_end( args );

            return * m_out;
        }
    };
}

これだけだと標準ストリームとファイルストリームぐらいにしか出せないので、
どうせならいつもデバッグに使っているDebugOutputString()に出せるようにしたいと思いました。

そこでstd::ostreamクラスの派生クラスを作りました。

TDebogOut.h

//----------------------------------------------------------------------------
/// @file    TDebugOut.h
/// @brief   デバッグ出力クラスヘッダ
/// @details デバッグ出力クラスです。
//----------------------------------------------------------------------------

#pragma once

#include "Common.h"
#include <iostream>
#include <windows.h>

//----------------------------------------------------------------------------
// 共通ライブラリ名前空間
//----------------------------------------------------------------------------
namespace Common
{
    //------------------------------------------------------------------------
    /// @brief   デバッグ出力クラス
    /// @details デバッグ出力クラスです。
    //------------------------------------------------------------------------
    class TDebugOut : public std::ostream
    {
        //--------------------------------------------------------------------
        /// @brief   ストリームバッファクラス
        /// @details ストリームバッファクラスです。
        //--------------------------------------------------------------------
        class TStreamBuf : public std::streambuf
        {
            //----------------------------------------------------------------
            // 定数
            //----------------------------------------------------------------

        private :

            static const size_t m_blocksize = 256; ///< バッファーブロックサイズ

            //----------------------------------------------------------------
            // 動的変数
            //----------------------------------------------------------------

        private :

            char * m_buffer; ///< 文字列バッファー
            size_t m_size;   ///< バッファーサイズ
            size_t m_len;    ///< 文字列長

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

        public :

            /// @brief デフォルト構築子
            inline explicit TStreamBuf() : std::streambuf(), m_buffer( 0 ), m_size( 0 ), m_len( 0 ) {}

            /// @brief 解体子
            inline virtual ~TStreamBuf() { delete[] m_buffer; }

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

        public :

            /// @brief   オーバーフロー関数
            /// @param   [in] ch 文字コード
            /// @return  文字コード
            /// @details 1文字を書き込みます。
            inline virtual int_type overflow( int_type ch = EOF )
            {
                // EOF でないか調べます。
                if ( ch != EOF )
                {
                    // バッファーサイズを調べます。
                    while ( m_size < m_len + 2 )
                    {
                        // バッファーサイズを更新します。
                        if ( m_size += m_blocksize >= m_len + 2 )
                        {
                            // 新規文字列バッファーを確保します。
                            char * buffer = new char[ m_size += m_blocksize ];

                            // 確保に失敗したか調べます。
                            if ( ! buffer ) throw( 0 );

                            // 現在のバッファー内容をコピーして削除します。
                            if ( m_buffer )
                            {
                                memcpy( buffer, m_buffer, m_len + 1 );

                                delete[] m_buffer;
                            }

                            // バッファポインタを更新します。
                            m_buffer = buffer;

                            break;
                        }
                    }

                    // バッファーに書き込みます。
                    m_buffer[ m_len++ ] = ch;
                }

                return ch;
            }

            /// @brief   同期関数
            /// @return  終了コード
            /// @details バッファー文字列を出力します。
            inline virtual int sync()
            {
                // バッファー文字列をデバッグコンソールに出力します。
                if ( m_buffer )
                {
                    m_buffer[ m_len ] = 0;

                    OutputDebugStringA( m_buffer );
                }

                // バッファーを削除します。
                delete[] m_buffer;

                m_buffer = 0;
                m_size   = 0;
                m_len    = 0;

                return 0;
            }
        };

        //--------------------------------------------------------------------
        // 動的変数
        //--------------------------------------------------------------------

    private :

        std::streambuf * m_streambuf; ///< ストリームバッファー

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

    public :

        /// @brief デフォルト構築子
        inline explicit TDebugOut() : std::ostream( m_streambuf = new TStreamBuf ) {}

        /// @brief 解体子
        inline virtual ~TDebugOut() { delete m_streambuf; }
    };
}

はずかしい話ですが、DebugOutputStringA()の方でも漢字が出せるということを今まで知りませんでした。
もう恥ずかしくって"tchar.h"なんてインクルードできないです。

サンプルドキュメント

DLLで文字列定数を使うときの注意点

たぶんだけど、DLLで作ったクラス内で文字列定数をインラインで使用することはできない。
ていうかたぶん、ポインタを使うことはできないのではないのか。
それはたぶん、DLLだから実際にリンクされるまでアドレスが決定しないからなんだろね。

たとえば

class TClass
{
private :
    static const char * m_str1;
    const char        * m_str2;
public :
    inline TClass() : m_str2( m_str1 ) {}
};
const char * TClass::m_str1 = "String";

これだとリンクエラーになるのだが、これを

class TClass
{
private :
    static const char * m_str1;
    const char        * m_str2;
public :
    TClass();
};
const char * TClass::m_str1 = "String";
TClass::TClass() : m_str2( m_str1 ) {}

これだとエラーにならないのだ。