uxtheme.libを使用したアプリケーションをuxtheme.DLLの無いOSで動作させるには – プログラミング – Home

uxtheme.libを使用したアプリ...
 
通知
すべてクリア

[解決済] uxtheme.libを使用したアプリケーションをuxtheme.DLLの無いOSで動作させるには


もにゃ
 もにゃ
(@もにゃ)
ゲスト
結合: 16年前
投稿: 7
Topic starter  

お世話になります。
下記のコードを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;
}


引用未解決
トピックタグ
金魚ちゃん
 金魚ちゃん
(@金魚ちゃん)
ゲスト
結合: 16年前
投稿: 52
 

> #pragma comment(lib, uxtheme.lib)
この行を削れば起動時のエラーを回避できます。

この場合はLoadLibrary()とGetProcAddress()関数で利用したい関数群を
すべて取得します。そうすれば Uxtheme.dll がないOSでも起動して
独自のエラー処理が行えます。

なお Uxtheme.dll がない場合は通常のテーマなしで起動を
続けるようにすれば良いでしょう。

あるいは uxtheme.dll をプログラムと一緒に配布するとか。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

#pragma消すとOpenThemeData関数の定義がないってリンクエラーになるはずです。
GetProcAddress関数を使うように変更が必要でしょう。

それと、FreeLibraryはLoadLibraryが成功したときのみだけ呼び出したほうが良いですね。

具体的なコードは
http://mspace.sakuraweb.com/comp/prog/dll.html
を参考にしてみてください。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

リンカの設定で uxtheme.dll を遅延読み込み(/DELAYLOAD)に
指定する方法もあります。


返信引用
もにゃ
 もにゃ
(@もにゃ)
ゲスト
結合: 16年前
投稿: 7
Topic starter  

皆さんありがとうございます。

リンカ→入力: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;
}


返信引用
もにゃ
 もにゃ
(@もにゃ)
ゲスト
結合: 16年前
投稿: 7
Topic starter  

とりあえず思いついた方法ですが、
クラス化して扱ってしまおうかと検討しています。
ライブラリのチェックも一発ですし。
皆さんはどうしているんですか?
もう少しネットも調べてみますが、
c++初心者でして、ネットの情報うまいこと吸いだせません;;

class Ctheme
{
public:
Ctheme();
~Ctheme();
 void Create(); //初期化
HTHEME OpenThemeData( HWND hWnd, LPCWSTR pszClassList);
};


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

/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;
}

という感じでしょうか。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

せっかくなので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;
}

リンカの設定を忘れずに。


返信引用
もにゃ
 もにゃ
(@もにゃ)
ゲスト
結合: 16年前
投稿: 7
Topic starter  

皆様、多くのサンプルありがとうございます。
だいぶ情報も集まってきてちょっと消化不良気味です…
ですが、学ぶべきことは見えてきたのでこれからも精進していきます。
本当にありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました