個人的にVistaが使いにくいと思うところと、その対策

遅まきながら、最近になってやっと本格的に開発環境をVista/Windows Server 2008(64bit)に移行したんですが(*´∀`*)
Vistaは使いにくいなんてよく言いますが、マシンスペック的な事に関して言えば、Core 2 Quadに64bitを有効活用したメモリを乗せれば特に重いと感じることは無いわけで。
ただ、個人的にどうしても受け入れられなかったのが、TreeViewのTVS_EX_AUTOHSCROLLとTVS_EX_FADEINOUTEXPANDOS。


主なところでは、エクスプローラーのフォルダとか、Eclipseのパッケージ・エクスプローラーとかがねぇ( ゚д゚)、ペッ
自動スクロールとか、[+]が消えたり表示されたりとか、うざいっちゅ〜ねん(゜Д゜)
っで、その対策として、グローバルフックしてTreeViewのスタイルを強制的に書き換えるツールを作ってみました*1
以下、フック用DLLのソースから抜粋。

#include "commctrl.h"
#include "tchar.h"

#pragma data_seg(".sharedata")
HHOOK g_hHookWnd = NULL;
#pragma data_seg()

HINSTANCE g_hInstance = NULL;

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        g_hInstance = hModule;
        break;
    }
    return TRUE;
}

void SetTreeViewStyle(HWND hWnd)
{
    LONG lStyle = ::GetWindowLong( hWnd, GWL_STYLE );
    if ( ( lStyle & TVS_HASLINES ) == 0 )
    {
        lStyle |= TVS_HASLINES;
        ::SetWindowLong( hWnd, GWL_STYLE, lStyle );
    }

    LRESULT lResult = TreeView_GetExtendedStyle( hWnd );
    if ( ( lResult | TVS_EX_AUTOHSCROLL ) ||
         ( lResult | TVS_EX_FADEINOUTEXPANDOS ) )
    {
        TreeView_SetExtendedStyle( hWnd, 0, TVS_EX_AUTOHSCROLL | TVS_EX_FADEINOUTEXPANDOS );
    }
}

LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if ( nCode == HC_ACTION )
    {
        CWPSTRUCT* pCwp = (CWPSTRUCT*)lParam;
        if ( ( pCwp->message == WM_CREATE ) ||
             ( pCwp->message == WM_SIZE ) )
        {
            TCHAR szClassName[ 256 ];
            ::GetClassName( pCwp->hwnd, szClassName, 256 );
            if ( ::_tcscmp( szClassName, L"SysTreeView32" ) == 0 )
            {
                SetTreeViewStyle( pCwp->hwnd );
            }
        }
    }

    return ::CallNextHookEx( g_hHookWnd, nCode, wParam, lParam );
}

__declspec(dllexport) void InstallHook()
{
    g_hHookWnd = ::SetWindowsHookEx( WH_CALLWNDPROC, CallWndProc, g_hInstance, 0 );
}

__declspec(dllexport) void UninstallHook()
{
    ::UnhookWindowsHookEx( g_hHookWnd );
}

常駐EXE側でInstallHook()を呼び出してフック開始、UninstallHook()でフック終了。
スタイルの設定に関しては、とりあえずWM_SIZEのタイミングで再設定するようにしてみましたが(´ω`)
TVS_EX_AUTOHSCROLL、TVS_EX_FADEINOUTEXPANDOSの他に、ついでにTVS_HASLINESも設定してみたり。


あと、常駐EXE起動時に、既に表示されているTreeViewに対しても設定を行うように、こんな処理も追加。

BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam)
{
    TCHAR szClassName[ 256 ];
    ::GetClassName( hWnd, szClassName, 256 );
    if ( ::_tcscmp( szClassName, L"SysTreeView32" ) == 0 )
    {
        SetTreeViewStyle( hWnd );
    }

    return TRUE;
}

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
    ::EnumChildWindows( hWnd, EnumChildProc, 0 );
    return TRUE;
}

__declspec(dllexport) void InitTreeViewStyle()
{
    ::EnumWindows( EnumWindowsProc, NULL );
}

フックに関しては32bit(主にEclipse)と64bit(主にExlopre)の両方が必要なわけで、x64の構成も用意。


それにしてもC++は久しぶりんこかも(・ω・)
色々と忘れていてダメダメ(´・ω・`)
Windows系の仕事に関しては、Windows Mobile含めてほぼC#だけでやるようになっちゃったからな〜。*2

*1:Eclipseだけに限れば、SWTのソースを書き換えるっていう方法もあるようですが

*2:P/Invokeガンガンな所はあるけどネ(・∀・;)