お世話になります。
下記のコードをWindows2000で動作させると、Uxtheme.dllが見つかりませんというエラ
ーが出ます。
当然と言えば当然なのですが、このようなアプリケーションをWindows2000に対応させる
ためにはどのようにコードしたら良いのでしょうか?
#include <windows.h>
#include <Uxtheme.h>
#pragma comment(lib, uxtheme.lib)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, 
int nCmdShow)
{
HINSTANCE hLib = LoadLibrary(Luxtheme.DLL);
if (hLib || 0)
{
    HTHEME hTheme;
    hTheme = OpenThemeData(0,Lprogress);
    if (hTheme == NULL)
    {
        MessageBox(0,Lテーマ無理ッス!,L",MB_OK);
    } else {
        MessageBox(0,Lテーマ行けます!,L",MB_OK);
    } 
} else {
    MessageBox(0,Lテーマ無理ッス!,L",MB_OK);
}
FreeLibrary(hLib); 
return 0;
}
> #pragma comment(lib, uxtheme.lib)
この行を削れば起動時のエラーを回避できます。
この場合はLoadLibrary()とGetProcAddress()関数で利用したい関数群を
すべて取得します。そうすれば Uxtheme.dll がないOSでも起動して
独自のエラー処理が行えます。
なお Uxtheme.dll がない場合は通常のテーマなしで起動を
続けるようにすれば良いでしょう。
あるいは uxtheme.dll をプログラムと一緒に配布するとか。
#pragma消すとOpenThemeData関数の定義がないってリンクエラーになるはずです。
GetProcAddress関数を使うように変更が必要でしょう。
それと、FreeLibraryはLoadLibraryが成功したときのみだけ呼び出したほうが良いですね。
具体的なコードは
 http://mspace.sakuraweb.com/comp/prog/dll.html 
を参考にしてみてください。
リンカの設定で uxtheme.dll を遅延読み込み(/DELAYLOAD)に
指定する方法もあります。
皆さんありがとうございます。
リンカ→入力:DLLの遅延読み込み(/DELAYLOAD)
すごく便利ですね。
コンパイラはVC++でのみ利用可能なのでしょうね。
重宝しそうです。
リンカによる DLL の遅延読み込み
   http://msdn.microsoft.com/ja-jp/library/151kt790(VS.80).aspx 
DLL の遅延読み込みの制約
   http://msdn.microsoft.com/ja-jp/library/yx1x886y(VS.80).aspx 
コードによる遅延読み込みの場合、関数を新規作成(OpenThemeData2)しましたが、
これを(OpenThemeData)として扱う方法ってあるのでしょうか?
もしかして、Uxtheme.hから作らないといけないのですかね…
#include <windows.h>
#include <Uxtheme.h>
//#pragma comment(lib, uxtheme.lib)
typedef HANDLE (WINAPI *LPFNOPENTHEMEDATA)( HWND, LPCWSTR );
HTHEME OpenThemeData2( HWND hWnd, LPCWSTR pszClassList) 
{
	HANDLE hTheme = NULL;
	HMODULE hLibrary = ::LoadLibrary( Luxtheme.dll );
	if ( hLibrary != NULL )
	{
		LPFNOPENTHEMEDATA lpfnOpenThemeData;
		lpfnOpenThemeData = (LPFNOPENTHEMEDATA)::GetProcAddress( 
hLibrary, OpenThemeData );
		if ( lpfnOpenThemeData != NULL )
			hTheme = lpfnOpenThemeData( hWnd, pszClassList);
		::FreeLibrary( hLibrary );
	}
	return hTheme;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, 
int nCmdShow)
{
//HINSTANCE hLib = LoadLibrary(Luxtheme.DLL);
//if (hLib || 0)
//{
    HTHEME hTheme;
    hTheme = OpenThemeData2(0,Ledit);
    if (hTheme == NULL)
    {
        MessageBox(0,Lテーマ無理ッス!,L",MB_OK);
    } else {
        MessageBox(0,Lテーマ行けます!,L",MB_OK);
    }
//    FreeLibrary(hLib); 
//} else {
//    MessageBox(0,Lテーマ無理ッス! no DLL,L",MB_OK);
//}
return 0;
}
とりあえず思いついた方法ですが、
クラス化して扱ってしまおうかと検討しています。
ライブラリのチェックも一発ですし。
皆さんはどうしているんですか?
もう少しネットも調べてみますが、
c++初心者でして、ネットの情報うまいこと吸いだせません;;
class Ctheme
{
public:
  Ctheme();
  ~Ctheme();
 void Create();  //初期化
  HTHEME OpenThemeData( HWND hWnd, LPCWSTR pszClassList); 
};
/DELAYLOADはやったことがないので、動的にdllをロードする場合
// ThemeFunction.h
class CThemeFunction
{
private:
    static CThemeFunction m_Instance;
    HMODULE m_hModule;
    typedef HANDLE (WINAPI *LPFNOPENTHEMEDATA)(HWND, LPCWSTR);
    LPFNOPENTHEMEDATA m_lpfnOpenThemeData;
    typedef HRESULT (WINAPI* LPFNCLOSETHEMEDATA)(HANDLE);
    LPFNCLOSETHEMEDATA m_lpfnCloseThemeData;
    CThemeFunction();
    virtual ~CThemeFunction();
bool IsUsable() const { return (this->m_hModule != NULL); }
public:
    static HANDLE OpenThemeData(HWND hWnd, LPCWSTR pszClassList);
    static HRESULT CloseThemeData(HANDLE hTheme);
};
// ThemeFunction.cpp
CThemeFunction CThemeFunction::m_Instance;
CThemeFunction::CThemeFunction()
: m_hModule(NULL)
, m_lpfnOpenThemeData()
, m_lpfnCloseThemeData()
{
    this->m_hModule = ::LoadLibrary(_T(uxTheme.dll));
    if (this->m_hModule != NULL)
    {
        this->m_lpfnOpenThemeData  = reinterpret_cast<LPFNOPENTHEMEDATA>
(::GetProcAddress(this->m_hModule, OpenThemeData));
        this->m_lpfnCloseThemeData = reinterpret_cast<LPFNCLOSETHEMEDATA>
(::GetProcAddress(this->m_hModule, CloseThemeData));
    }
}
CThemeFunction::~CThemeFunction()
{
    if (this->IsUsable())
    {
        ::FreeLibrary(this->m_hModule);
    }
}
HANDLE CThemeFunction::OpenThemeData(HWND hWnd, LPCWSTR pszClassList)
{
    HANDLE hTheme = NULL;
    if (m_Instance.IsUsable())
    {
        if (m_Instance.m_lpfnOpenThemeData != NULL)
        {
            hTheme = (*m_Instance.m_lpfnOpenThemeData)(hWnd, pszClassList);
        }
    }
    return hTheme;
}
HRESULT CThemeFunction::CloseThemeData(HANDLE hTheme)
{
    HRESULT hr = S_OK;
    if (m_Instance.IsUsable())
    {
        if (m_Instance.m_lpfnCloseThemeData != NULL)
        {
            hr = (*m_Instance.m_lpfnCloseThemeData)(hTheme);
        }
    }
    return hr;
}
という感じでしょうか。
せっかくなのでDELAYLOADでやる例も載せておきます。
//Theme.h
#ifndef THEME_H_
#define THEME_H_
#include <windows.h>
#include <uxtheme.h>
#include <tmschema.h>
class Theme {
public:
    Theme();
    virtual ~Theme();
    bool Open(HWND hWnd, LPCWSTR pszClassList);
    void Close();
    bool DrawBackground(HDC hDC, int iPartId, int iStateId, const RECT& rect,
const RECT* pClipRect = NULL) const;
private:
    Theme(const Theme&);
    Theme& operator=(const Theme&);
    static bool IsThemingSupported();
    static bool themingSupported;
    HTHEME hTheme;
};
#endif
//Theme.cpp
#include theme.h
#pragma comment(lib, uxtheme.lib)
bool Theme::themingSupported = IsThemingSupported();
Theme::Theme() : hTheme(NULL)
{
}
Theme::~Theme()
{
    Close();
}
bool Theme::Open(HWND hWnd, LPCWSTR pszClassList)
{
    if(!themingSupported) {
        return false;
    }
    Close();
    hTheme = OpenThemeData(hWnd, pszClassList);
    return hTheme != NULL;
}
void Theme::Close()
{
    if(!themingSupported) {
        return;
    }
    if(hTheme != NULL) {
        CloseThemeData(hTheme);
        hTheme = NULL;
    }
}
bool Theme::DrawBackground(HDC hDC, int iPartId, int iStateId, const RECT& rect,
const RECT* pClipRect) const
{
    if(!themingSupported) {
        return false;
    }
    return SUCCEEDED(DrawThemeBackground(hTheme, hDC, iPartId, iStateId, &rect,
pClipRect));
}
bool Theme::IsThemingSupported()
{
    HINSTANCE hThemeDll = LoadLibrary(TEXT(uxtheme.dll));
    if(hThemeDll != NULL) {
        FreeLibrary(hThemeDll);
        return true;
    }
    return false;
}
リンカの設定を忘れずに。
皆様、多くのサンプルありがとうございます。
だいぶ情報も集まってきてちょっと消化不良気味です…
ですが、学ぶべきことは見えてきたのでこれからも精進していきます。
本当にありがとうございました。
