Programming Windows Maniacs - プログラミング ウィンドウズ マニアックス ■ ご利用に際して ■ 更新履歴 ■ お問い合わせ ■ このホームページについて  
ホーム >> シェル >> EXEやDLLからアイコンを抽出するには

EXEやDLLからアイコンを抽出するには

  EXEやDLLには、単一もしくは複数のアイコンが含まれていることが多いです。
  もし作成するアプリケーションに簡易エクスプローラ的機能をつけたい場合、アイコンが表示された方が綺麗に見えるでしょう。

  EXEやDLLからアイコンを抽出するためには、ExtractIconEx () APIを使用します。
  ExtractIconEx () APIは、EXEやDLLに含むアイコンの個数も取得できます。

  以下は、メモ帳(notepad.exe)からアイコンを抽出し、デスクトップに小さいアイコンと大きいアイコンを描画するサンプルになります。
  ※ メモ帳のパスは、"C:\Windows\notepad.exe"と仮定しています。

  ※ 昔フリーソフト用に記載したコードの一部を流用していますので、他のTipsとソースの書き方が異なりますが動作確認済みです。

■■■ extracticon プロジェクト
■ stdafx.h

#ifndef _YUSU_STDAFX

#include <windows.h>
#include <tchar.h>

#include <string>

#include "myassert.h"

#endif
■ myassert.h
//----------------------------------------------------------------------
// ASSERT マクロと実装
//----------------------------------------------------------------------
#ifndef _H_YUSU_ASSERT
#define _H_YUSU_ASSERT
//----------------------------------------------------------------------
// ASSERT マクロ定義
#ifndef ASSERT
    #ifdef _DEBUG
        #include <crtdbg.h>
        #define ASSERT(f) \
            _ASSERTE(f)
    #else
        #define ASSERT(f) \
            NULL
    #endif
#endif
//----------------------------------------------------------------------
#endif
■ icon.h
//----------------------------------------------------------------------
// ICON 管理描画クラス
//----------------------------------------------------------------------
#ifndef _H_YUSU_ICON
#define _H_YUSU_ICON
//----------------------------------------------------------------------
namespace Icon
{
    class TIcon
    {
    protected:
    // アイコンハンドル
        HICON m_hIcon;
    public:
    // コンストラクタ
        TIcon ();
        TIcon ( HICON hIcon );
    // コピーコンストラクタ
        TIcon ( const TIcon &obj );
    // 代入演算子
        TIcon operator = ( TIcon obj );

    // デストラクタ
        virtual ~TIcon ();

    // アタッチ
        HICON Attach ( HICON hIcon );
    // デタッチ
        HICON Detach ();

    // ハンドル取得
        HICON GetHandle ();

    // アイコンサイズ取得
        SIZE GetSize ();

    // DC指定描画(ブラシを指定するとちらつかない(小さいときは気にならない))
        virtual BOOL Draw ( HDC hdc,
            long nX,
            long nY,
            HBRUSH hBackgroundBrush = NULL );
    // DC指定伸縮描画(ブラシを指定するとちらつかない(小さいときは気にならない))
        virtual BOOL DrawStretch ( HDC hdc,
            long nX,
            long nY,
            long nWidth,
            long nHeight,
            HBRUSH hBackgroundBrush = NULL );
    };
}
//----------------------------------------------------------------------
#endif
■ icon.cpp

#include "stdafx.h"

#include "icon.h"

using namespace Icon;
//----------------------------------------------------------------------
// public メンバ
//----------------------------------------------------------------------
// コンストラクタ
TIcon::TIcon ()
: m_hIcon ( NULL )
{
}

TIcon::TIcon ( HICON hIcon )
: m_hIcon ( hIcon )
{
}

// コピーコンストラクタ
TIcon::TIcon ( const TIcon &obj )
{
    if ( obj.m_hIcon == NULL )
    {
        m_hIcon = NULL;
        return;
    }

    ICONINFO iconInfo;
#ifdef _DEBUG
    BOOL bGetIconInfo =
#endif
        GetIconInfo ( obj.m_hIcon, &iconInfo );
#ifdef _DEBUG
    ASSERT ( bGetIconInfo != FALSE );
#endif

    m_hIcon = CreateIconIndirect ( &iconInfo );
    ASSERT ( m_hIcon != NULL );

    DeleteObject ( iconInfo.hbmMask );
    DeleteObject ( iconInfo.hbmColor );
}

// 代入演算子
TIcon TIcon::operator = ( TIcon obj )
{
    if ( m_hIcon != NULL )
        DestroyIcon ( m_hIcon );

    if ( obj.m_hIcon == NULL )
    {
        m_hIcon = NULL;
        return *this;
    }

    ICONINFO iconInfo;
#ifdef _DEBUG
    BOOL bGetIconInfo =
#endif
        GetIconInfo ( obj.m_hIcon, &iconInfo );
#ifdef _DEBUG
    ASSERT ( bGetIconInfo != FALSE );
#endif

    m_hIcon = CreateIconIndirect ( &iconInfo );
    ASSERT ( m_hIcon != NULL );

    DeleteObject ( iconInfo.hbmMask );
    DeleteObject ( iconInfo.hbmColor );
    return *this;
}

// デストラクタ
TIcon::~TIcon ()
{
    if ( m_hIcon != NULL )
    {
        DestroyIcon ( m_hIcon );
        m_hIcon = NULL;// 念のため
    }
}

// アタッチ
HICON TIcon::Attach ( HICON hIcon )
{
    ASSERT ( hIcon != NULL );
    if ( m_hIcon != NULL )
        DestroyIcon ( m_hIcon );
    HICON hIconBuf = m_hIcon;
    m_hIcon = hIcon;
    return hIconBuf;
}

// デタッチ
HICON TIcon::Detach ()
{
    HICON hIconBuf = m_hIcon;
    m_hIcon = NULL;
    return hIconBuf;
}

// アイコンサイズ取得
SIZE TIcon::GetSize ()
{
    SIZE sizeResult;
    if ( m_hIcon == NULL )
    {
        sizeResult.cx = 0;
        sizeResult.cy = 0;
    }
    else
    {
        ICONINFO iconInfo;
        memset ( &iconInfo, 0, sizeof ( ICONINFO ) );
#ifdef _DEBUG
        BOOL bGetIconInfo =
#endif
            GetIconInfo ( m_hIcon, &iconInfo );
#ifdef _DEBUG
        ASSERT ( bGetIconInfo != FALSE );
#endif
        BITMAP bm;
        ASSERT ( iconInfo.hbmColor != NULL );
#ifdef _DEBUG
        BOOL bGetObject = 
#endif
            GetObject ( iconInfo.hbmColor, sizeof ( BITMAP ), &bm );
#ifdef _DEBUG
        ASSERT ( bGetObject != FALSE );
#endif
        if ( iconInfo.hbmColor != NULL )
            DeleteObject ( iconInfo.hbmColor );
        if ( iconInfo.hbmMask != NULL )
            DeleteObject ( iconInfo.hbmMask );

        sizeResult.cx = bm.bmWidth;
        sizeResult.cy = bm.bmHeight;
    }
    return sizeResult;
}

// ハンドル取得
HICON TIcon::GetHandle ()
{
    return m_hIcon;
}

// DC指定描画
BOOL TIcon::Draw ( HDC hdc,
    long nX,
    long nY,
    HBRUSH hBackgroundBrush )
{
    ASSERT ( m_hIcon != NULL );
    SIZE sizeIcon = GetSize ();

    return DrawStretch ( hdc,
        nX,
        nY,
        sizeIcon.cx,
        sizeIcon.cy,
        hBackgroundBrush );
}

// DC指定伸縮描画
BOOL TIcon::DrawStretch ( HDC hdc,
    long nX,
    long nY,
    long nWidth,
    long nHeight,
    HBRUSH hBackgroundBrush )
{
    ASSERT ( m_hIcon != NULL );
    return DrawIconEx ( hdc,
        nX,
        nY,
        m_hIcon,
        nWidth,
        nHeight,
        0,
        NULL,
        DI_NORMAL );
}
■ iconlargeandsmall.h
//----------------------------------------------------------------------
// Large サイズと Small サイズを持つアイコン管理クラス
//   処理は、TIconクラスに任せる ( 中身はほとんど構造体 )
//----------------------------------------------------------------------
#ifndef _H_YUSU_ICONS
#define _H_YUSU_ICONS
//----------------------------------------------------------------------
#include "icon.h"

namespace Icon
{
    struct TIconLargeAndSmall
    {
    // コンストラクタ
        TIconLargeAndSmall ();
    // コピーコンストラクタ
        TIconLargeAndSmall ( const TIconLargeAndSmall &obj );
    // 代入演算子
        TIconLargeAndSmall operator = ( TIconLargeAndSmall obj );
    // デストラクタ
        virtual ~TIconLargeAndSmall ();

    // Large アイコン
        TIcon m_iconLarge;
    // Small アイコン
        TIcon m_iconSmall;
    };
}
//----------------------------------------------------------------------
#endif
■ iconlargeandsmall.cpp

#include "stdafx.h"

#include "iconlargeandsmall.h"

using namespace Icon;
//----------------------------------------------------------------------
// public メンバ
//----------------------------------------------------------------------
// コンストラクタ
TIconLargeAndSmall::TIconLargeAndSmall ()
{
}
// コピーコンストラクタ
TIconLargeAndSmall::TIconLargeAndSmall ( const TIconLargeAndSmall &obj )
{
    m_iconLarge = obj.m_iconLarge;
    m_iconSmall = obj.m_iconSmall;
}

// 代入演算子
TIconLargeAndSmall TIconLargeAndSmall::operator = ( TIconLargeAndSmall obj )
{
    m_iconLarge = obj.m_iconLarge;
    m_iconSmall = obj.m_iconSmall;
    return *this;
}

// デストラクタ
TIconLargeAndSmall::~TIconLargeAndSmall ()
{
}

■ extracticons.h
//----------------------------------------------------------------------
// ICON 抽出
//----------------------------------------------------------------------
#ifndef _H_YUSU_EXTRACT_ICON
#define _H_YUSU_EXTRACT_ICON
//----------------------------------------------------------------------
#include "icon.h"
#include "iconlargeandsmall.h"
namespace Icon
{

// 単一アイコン 抽出 関数
    // nPos に zero-based な インデックスを指定する
    BOOL ExtractIconFromFile ( const _TCHAR *pszFileName,
        UINT nIndex,
        TIconLargeAndSmall &iconLargeAndSmall );
// アイコンの含む個数を取得
    UINT ExtractIconCountFromFile ( const _TCHAR *pszFileName );

}
//----------------------------------------------------------------------
#endif
■ extracticons.cpp


#include "stdafx.h"

#include "extracticons.h"

// 単一アイコン 抽出 関数
// nPos に zero-based な インデックスを指定する
BOOL Icon::ExtractIconFromFile ( const _TCHAR *pszFileName,
    UINT nIndex,
    TIconLargeAndSmall &iconLargeAndSmall )
{
    ASSERT ( pszFileName != NULL );

    HICON hIconLarge;
    HICON hIconSmall;

// アイコン取得
    UINT nResult = ExtractIconEx ( pszFileName,
        nIndex,
        &hIconLarge,
        &hIconSmall,
        1 );
    if ( nResult <= 0 )
        return FALSE;

    TIcon iconLarge;
    TIcon iconSmall;
    if ( hIconLarge != NULL )
        iconLarge.Attach ( hIconLarge );
    if ( hIconSmall != NULL )
        iconSmall.Attach ( hIconSmall );
    iconLargeAndSmall.m_iconLarge = iconLarge;
    iconLargeAndSmall.m_iconSmall = iconSmall;

    return TRUE;
}

// アイコンの含む個数を取得
UINT Icon::ExtractIconCountFromFile ( const _TCHAR *pszFileName )
{
    ASSERT ( pszFileName != NULL );
    // 個数取得
        UINT nCount = ExtractIconEx ( pszFileName,
            -1,
            NULL,
            NULL,
            0 );
    return nCount;
}

■ main.cpp

#include "stdafx.h"

#include "extracticons.h"
#include "iconlargeandsmall.h"

// エントリポイント
int WINAPI _tWinMain ( HINSTANCE hThisInstance,
    HINSTANCE,
    _TCHAR *,
    int )
{
    // メモ帳
    const _TCHAR cszNotepad[] = _TEXT ( "C:\\windows\\notepad.exe" );

    // アイコン数 取得
    UINT nCount;
    nCount = Icon::ExtractIconCountFromFile ( cszNotepad );

    // アイコンがあれば、アイコンHICONを取得
    if ( 0 != nCount )
    {
        Icon::TIconLargeAndSmall iconsNotepad;
        if ( Icon::ExtractIconFromFile ( cszNotepad, 0, iconsNotepad ) )
        {
            // アイコンが読み込めれば、
            // 画面(デスクトップ)に 小さいアイコンと大きいアイコンを描画
            HDC hDC = GetDC ( NULL );

            iconsNotepad.m_iconSmall.Draw ( hDC, 0, 0 );
            iconsNotepad.m_iconLarge.Draw ( hDC, 0, 100 );
            
            ReleaseDC ( NULL, hDC );
        }
    }

    return 0;
}
  ■ ご利用に際して ■ 更新履歴 ■ お問い合わせ ■ このホームページについて Copyright © 2014 A.Morita