MRU を扱うクラス (CMruList)

Windows 2000 or lator
(2007.05.21)
#pragma once
 
// WAC.com Class Liblary for Visual C++
// Copyright (C) WAC.com Inc. All rights reserved.
//
// This file is a part of the WAC.com Class Liblary.
// The use and distribution terms for this software are covered by the
// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
// any other, from this software.
 
// '06.06.14 : 新規作成 (sha)
// '07.05.21 : コードの整備 (sha)
 
#include "Module.h"
 
#if _MSC_VER < 1400
#if !defined(_countof)
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#endif
#endif
 
 
/////////////////////////////////////////////////////////////////////////////
// MRUList関連の定義
// Platform SDKには、定義されていない
 
#define MRUF_STRING_LIST    0                    /* list will contain strings */
#define MRUF_BINARY_LIST    1                    /* list will contain binary data */
#define MRUF_DELAYED_SAVE    2                    /* only save list order to reg. is FreeMRUList */
 
typedef int (CALLBACK * MRUCMPPROC)(LPCWSTR pString1, LPCWSTR pString2);
 
typedef struct
{
    DWORD cbSize;
    UINT uMax;
    UINT fFlags;
    HKEY hKey;
    LPCWSTR lpszSubKey;
    MRUCMPPROC lpfnCompare;
} MRUINFO, *LPMRUINFO;
 
 
/////////////////////////////////////////////////////////////////////////////
// 関数の定義
 
typedef int (WINAPI *FUNC_ADDMRUSTRINGW)(HANDLE hMRU, LPCWSTR szString);
typedef int (WINAPI *FUNC_CREATEMRULISTW)(LPMRUINFO lpmi);
typedef int (WINAPI *FUNC_ENUMMRULISTW)(HANDLE hMRU, int nItem, void *lpData, UINT uLen);
typedef int (WINAPI *FUNC_FREEMRULIST)(HANDLE hMRU);
 
 
/////////////////////////////////////////////////////////////////////////////
// CMruInfo
 
class CMruInfo : public MRUINFO
{
public:
    CMruInfo()
    {
        ::ZeroMemory(this, sizeof(MRUINFO));
        this->cbSize = sizeof(MRUINFO);
    }
    CMruInfo(UINT uNewMax, UINT fNewFlags, HKEY hNewKey, LPCWSTR lpszNewSubKey, MRUCMPPROC lpfnNewCompare = NULL)
    {
        ::ZeroMemory(this, sizeof(MRUINFO));
        this->cbSize = sizeof(MRUINFO);
        this->uMax = uNewMax;
        this->fFlags = fNewFlags;
        this->hKey = hNewKey;
        this->lpszSubKey = lpszNewSubKey;
        this->lpfnCompare = lpfnNewCompare;
    }
};
 
 
/////////////////////////////////////////////////////////////////////////////
// CMruListT
// Windows 2000 or lator
 
template <bool t_bManaged>
class CMruListT
{
protected:
    typedef CMruListT                            thisClass;
 
public:
    CMruListT()
    {
        m_hMRU = NULL;
    }
    CMruListT(HANDLE hMRU)
    {
        m_hMRU = hMRU;
    }
    CMruListT(LPMRUINFO lpmi)
    {
        HRESULT hr = S_OK;
 
        hr = this->Create(lpmi);
        if (FAILED(hr))
        {
            // 無視する。。
        }
    }
    virtual ~CMruListT()
    {
        HRESULT hr = S_OK;
 
        if (t_bManaged && m_hMRU != NULL)
        {
            hr = this->Free();
            if (FAILED(hr))
            {
                // 無視する。。
            }
        }
    }
 
public:
    bool IsValid()
    {
        rturn (m_hMRU == NULL) ? false : true;
    }
    
public:
    void Attach(HANDLE hMRU)
    {
        ATLASSERT(m_hMRU == NULL);
        ATLASSERT(hMRU != NULL);
        m_hMRU = hMRU;
    }
    HANDLE Detach()
    {    
        ATLASSERT(m_hMRU != NULL);
        MSIHANDLE hMRU = m_hMRU;
        m_hMRU = NULL;
        return h;
    }
 
public:
    CMruListT& operator =(HANDLE hMRU)
    {
        m_hMRU = hMRU;
        return *this;
    }
    operator HANDLE()
    { 
        return m_hMRU; 
    }
 
public:
    HRESULT AddString(LPCWSTR szString)
    {
        int nr = thisClass::Probe_AddMRUStringW(m_hMRU, szString);
        if (nr < 0)
        {
            return E_FAIL;
        }
 
        return S_OK;
    }
    HRESULT Create(LPMRUINFO lpmi)
    {
        m_hMRU = (HANDLE)thisClass::Probe_CreateMRUListW(lpmi);
        if (m_hMRU == NULL)
        {
            return E_FAIL;
        }
 
        return S_OK;
    }
    HRESULT Enum(int nItem, void *lpData, UINT uLen)
    {
        int nr = thisClass::Probe_EnumMRUListW(m_hMRU, nItem, lpData, uLen);
        if (nr < 0)
        {
            return E_FAIL;
        }
 
        return S_OK;
    }
#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
#ifndef _CSTRING_NS
    HRESULT Enum(int nItem, CStringW& strData)
#else
    HRESULT Enum(int nItem, _CSTRING_NS::CStringW& strData)
#endif
    {
        WCHAR szData[512] = { 0 };
        int nr = thisClass::Probe_EnumMRUListW(m_hMRU, nItem, szData, _countof(szData));
        if (nr < 0)
        {
            return E_FAIL;
        }
 
        strData = szData;
 
        return S_OK;
    }
#endif
    HRESULT GetCount(int& nItem)
    {
        int nr = thisClass::Probe_EnumMRUListW(m_hMRU, -1, NULL, 0);
        if (nr < 0)
        {
            return E_FAIL;
        }
 
        nItem = nr;
 
        return S_OK;
    }
    HRESULT Free()
    {
        int nr = thisClass::Probe_FreeMRUList(m_hMRU);
        if (nr < 0)
        {
            return E_FAIL;
        }
 
        return S_OK;
    }
 
public:
    static int Probe_AddMRUStringW(HANDLE hMRU, LPCWSTR szString)
    {
        CModule module;
 
        HINSTANCE hInst = module.LoadLibrary(_T("comctl32.dll"));
        if (hInst == NULL)
        {
            return -1;
        }
 
        CString strProcName = _T("AddMRUStringW");
        FUNC_ADDMRUSTRINGW func = (FUNC_ADDMRUSTRINGW)module.GetProcAddress(strProcName);
        if (func == NULL)
        {
            return -1;
        }
 
        return (*func)(hMRU, szString);
    }
    static int Probe_CreateMRUListW(LPMRUINFO lpmi)
    {
        CModule module;
 
        HINSTANCE hInst = module.LoadLibrary(_T("comctl32.dll"));
        if (hInst == NULL)
        {
            return -1;
        }
 
        CString strProcName = _T("CreateMRUListW");
        FUNC_CREATEMRULISTW func = (FUNC_CREATEMRULISTW)module.GetProcAddress(strProcName);
        if (func == NULL)
        {
            return -1;
        }
 
        return (*func)(lpmi);
    }
    static int Probe_EnumMRUListW(HANDLE hMRU, int nItem, void *lpData, UINT uLen)
    {
        CModule module;
 
        HINSTANCE hInst = module.LoadLibrary(_T("comctl32.dll"));
        if (hInst == NULL)
        {
            return -1;
        }
 
        CString strProcName = _T("EnumMRUListW");
        FUNC_ENUMMRULISTW func = (FUNC_ENUMMRULISTW)module.GetProcAddress(strProcName);
        if (func == NULL)
        {
            return -1;
        }
 
        return (*func)(hMRU, nItem, lpData, uLen);
    }
    static int Probe_FreeMRUList(HANDLE hMRU)
    {
        CModule module;
 
        HINSTANCE hInst = module.LoadLibrary(_T("comctl32.dll"));
        if (hInst == NULL)
        {
            return -1;
        }
 
        CString strProcName = _T("FreeMRUList");
        FUNC_FREEMRULIST func = (FUNC_FREEMRULIST)module.GetProcAddress(strProcName);
        if (func == NULL)
        {
            return -1;
        }
 
        return (*func)(hMRU);
    }
 
public:
    HANDLE m_hMRU;
};
 
typedef CMruListT<false>                        CMruListHandle;
typedef CMruListT<true>                            CMruList;
// CMruListのサンプルコード
HRESULT TestMruList()
{
    USES_CONVERSION;
 
    HRESULT hr = S_OK;
 
    CMruList mruList;
 
    // 作成
    WCHAR szNewSubKey[] = L"Software\\WAC.com\\TestMruList";
    CMruInfo mruInfo(10, MRUF_STRING_LIST, HKEY_CURRENT_USER, szNewSubKey);
    hr = mruList.Create(&mruInfo);
    if (FAILED(hr))
    {
        ATLASSERT(0);
        return hr;
    }
 
    // キーの削除
    ::SHDeleteKey(HKEY_CURRENT_USER, CW2T(szNewSubKey));                            // SHLWAPI 4.71
 
    // 追加
    for (int i = 0; i < 20; i++)
    {
        CStringW strFileName;
        strFileName.Format(_T("Hoge%02d.jpg"), i);
 
        hr = mruList.AddString(strFileName);
        if (FAILED(hr))
        {
            ATLASSERT(0);
            continue;
        }
    }
 
    // 個数の取得
    int nCount = 0;
    hr = mruList.GetCount(nCount);
    if (FAILED(hr))
    {
        // 無視する。。
        ATLASSERT(0);
    }
 
    // 列挙
    for (int i = 0; i < nCount; i++)
    {
#if 0
        WCHAR szFileName[_MAX_PATH] = { 0 };
        hr = mruList.Enum(i, szFileName, _countof(szFileName));
        if (FAILED(hr))
        {
            ATLASSERT(0);
            continue;
        }
#else
        CStringW strFileName;
        hr = mruList.Enum(i, strFileName);
        if (FAILED(hr))
        {
            ATLASSERT(0);
            continue;
        }
#endif
    }
 
    // 解放
    hr = mruList.Free();
    if (FAILED(hr))
    {
        // 無視する。。
        ATLASSERT(0);
    }
 
    return S_OK;
}
一覧に戻る
© 2003 WAC.com All Right Reserved.