Top  上へ  目次



Windows8.1対応再び



 2ヶ月近い前の記事のほじくり返しですが、GetVersionEx()が嘘の値を返してくる話の続きです。

 話の発端は、INASOFTさんの記事を見て→X-Finderの作者さんのツイート見て→お前のところはどうなってんだ?みたいな経路みたいです。
 そーいや、投げっぱなしジャーマン状態で放置プレイしてました。


 んで王道の対処方法は、INASOFTさんの対応どおりMS社が指定しているマニフェスト記述だと思います。
 ただ、INASOFTさんでも不審に思われているように、うちもMS社の回答に違和感を感じたわけで、全然違うアプローチを取ってます。

//OSのバージョン番号を返す
BOOL GetOSVersion(DWORD *nMajor, DWORD *nMinor, DWORD *nBuildNo)
{
    OSVERSIONINFO ver = { 0 };
    BOOL bRet = FALSE;
    ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    if (::GetVersionEx(&ver))
    {
        int nVer = ver.dwMajorVersion * 100 + ver.dwMinorVersion;
        if (nVer == 602)
        {
            TCHAR szFileName[MAX_PATH * 2];
            if (::GetSystemDirectory(szFileName, MAX_PATH * 2))
            {
                _tcscat_s(szFileName, MAX_PATH * 2, _T("\\shell32.dll"));
                DLLVERSIONINFO dvi = { 0 };
                HMODULE hModule = LoadLibrary(szFileName);
                if(hModule != NULL)
                {
                    DLLGETVERSIONPROC DllGetVersion =
                        (DLLGETVERSIONPROC)GetProcAddress(hModule, "DllGetVersion");
                    if(DllGetVersion != NULL)
                    {
                        dvi.cbSize = sizeof(dvi);
                        DllGetVersion(&dvi);
                        ver.dwMajorVersion = dvi.dwMajorVersion;
                        ver.dwMinorVersion = dvi.dwMinorVersion;
                        ver.dwBuildNumber = dvi.dwBuildNumber;
                        bRet = TRUE;
                    }
                    FreeLibrary(hModule);
                }
            }
        }
        else
            bRet = TRUE;
    }
    if (nMajor)*nMajor = ver.dwMajorVersion;
    if (nMinor)*nMinor = ver.dwMinorVersion;
    if (nBuildNo)*nBuildNo = ver.dwBuildNumber;
    return bRet;
}
 shell32.dllのDllGetVersion()は正しい値を返してくるので、これを採用しています。
 また8.1以前のOSにもそれなりに対応してますが、互換性重視のために6.2の場合だけ個別判定しています。
 将来、挙動が変わるものがあれば個別に分岐させればいいやと言う感じですね。
 強いて言えば、shell32.dllを入れ替えてる方もいらっしゃるよーですが、不適切なOSの改造にあたるんでスルーで良いかなと。




 さて、ツイッターへのリプライをば

>As/Rの新型ツリーはX-Finderのシステム互換ツリー(Vista以降)やTablacus Explorerのツリー(Vista以降)と同じコントロールのようだ。

 根っこの部分は他にろくな選択肢がありませんし、いずれ同じ方向に向かうのは必然かと思います。
 ただ、こちらはカスタマイズ要件を満たすためにCTreeCtrlから派生させた普通のツリーに、INameSpaceTreeControlをぶら下げてますので微妙に違う気がします。
 描画、各種イベント、D&Dの制御は丸ごと自前でやってますし。

 あと、こういったインターフェイス依存の実装は、新しいOSになるとバグだらけになるケースを経験されていると思います。
 その辺りが、IShellNameSpaceやExplorerBrowserを使わなかった理由でもあり、今後も乗り気になれなさげな部分ですね。
 またINameSpaceTreeControlもガッツリ使ってみて、メリットもデメリットも見えてきました。
 こちらも万能じゃないですし、いずれはフルスクラッチしたいですね・・・時間と気力と体力が続けば・・・。


 さて、改めて他人の作品を見ると・・・うーん。
 作り手として共感できるところは多いですけど、表現方法はえらい違いすぎてコメントのしようがないですね(苦笑)
 うちはFDやFILMTNの影響が濃いんだな、と改めて思いました。はい。
 ま、お互い頑張りましょう。