現在、デスクトップの壁紙をサブクラス化して処理をさせたいと考えています。
以下のようなプログラムを組んだのですが、実行させプログラムを終了させると
「問題が発生したため、explorer.exeを終了します。」と出てエクスプローラが再起動されます。
どのように解決すればいいのか見当がつかなかったので、わかる方がいれば教えてもらえないでしょうか。
-- DLLのプログラム --
// .SC_SECTION READ WRITE SHARED
#pragma data_seg(".SC_SECTION")
HHOOK g_hHook = NULL;
HWND g_hTargWnd = NULL;
HINSTANCE g_hInstance = NULL;
WNDPROC g_lpfnProc = NULL;
#pragma data_seg()
// フックをインストール
BOOL SetHook()
{
// Program Managerのウィンドウハンドルを取得
// SHELLDLL_DefViewのウィンドウハンドルを取得
// SysListView32のウィンドウハンドルを取得
g_hTargWnd = FindWindow("SysListView32", NULL);
// スレッドIDを取得
DWORD dwThreadId = GetWindowThreadProcessId(g_hTargWnd, NULL);
// フックをインストール
g_hHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)HookProc, g_hInstance, dwThreadId);
if( !g_hHook )
{
return FALSE;
}
PostMessage(g_hTargWnd, WM_NULL, 0, 0);
}
// フックをアンインストール
void EndHook()
{
// サブクラス化を解除する
ResetSubclass();
// フックをアンインストール
if( g_hHook )
{
UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
}
// フックプロシージャ
LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LPCWPSTRUCT lpCWP = (LPCWPSTRUCT)lParam;
if( nCode >= HC_ACTION )
{
if( !g_bSCInit && lpCWP->hwnd != g_hTargWnd && IsWindow(lpCWP->hwnd) )
{
// サブクラス化する
if( SetSubclass() )
{
g_bSCInit = TRUE;
}
else
{
// サブクラス化に失敗
}
}
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
BOOL SetSubclass()
{
// サブクラス化する
g_lpfnProc = (WNDPROC)GetWindowLong(g_hTargWnd, GWL_WNDPROC);
if( !g_lpfnProc )
{
return FALSE;
}
if( !SetWindowLong(g_hTargWnd, GWL_WNDPROC, (LONG)SubProc) )
{
// サブクラス化に失敗
g_lpfnProc = NULL;
return FALSE;
}
return TRUE;
}
LRESULT CALLBACK SubProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// 省略
return CallWindowProc(g_lpfnProc, hWnd, msg, wParam, lParam);
}
# 一部はしょって書いてます。
メインプログラム起動時に SetHook() を、終了時に EndHook() をコールしています。
長くなりましたが、よろしくお願いします。
(WindowsXP SP1, Visual Studio.net 2003 VC++)
ツイート | ![]() |