VC++开发GIS系统(66)补充知识MFC中判断系统版本

在之前的文章《VC++开发GIS系统(64)CTreeCtrl中替换加号为三角形小键头》中我介绍了使用SetWindowTheme函数来更改CTreeCtrl中的加号为三角形的方法,但是有一个问题:

SetWindowTheme函数对系统的要求是windows vista,如果在低于这个系统版本这个函数会失效,那么怎么判断系统版本呢?

方法1 常规函数方法

有人已经将此封装成了函数:C++中获取操作系统的名称和版本名称

//读取操作系统的名称
void GetSystemName(CString& osname)
{
    SYSTEM_INFO info;        //用SYSTEM_INFO结构判断64位AMD处理器 
    GetSystemInfo(&info);    //调用GetSystemInfo函数填充结构 
    OSVERSIONINFOEX os; 
    os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);   

    osname = _T("unknown OperatingSystem.");

    if(GetVersionEx((OSVERSIONINFO *)&os))
    { 
        //下面根据版本信息判断操作系统名称 
        switch(os.dwMajorVersion)//判断主版本号
        {
        case 4:
            switch(os.dwMinorVersion)//判断次版本号 
            { 
            case 0:
                if(os.dwPlatformId==VER_PLATFORM_WIN32_NT)
                    osname =_T("Microsoft Windows NT 4.0"); //1996年7月发布 
                else if(os.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
                    osname =_T("Microsoft Windows 95");
                break;
            case 10:
                osname =_T("Microsoft Windows 98");
                break;
            case 90:
                osname =_T("Microsoft Windows Me");
                break;
            }
            break;

        case 5:
            switch(os.dwMinorVersion)   //再比较dwMinorVersion的值
            { 
            case 0:
                osname =_T("Microsoft Windows 2000");//1999年12月发布
                break;

            case 1:
                osname =_T("Microsoft Windows XP");//2001年8月发布
                break;

            case 2:
                if(os.wProductType==VER_NT_WORKSTATION 
                    && info.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
                {
                    osname =_T("Microsoft Windows XP Professional x64 Edition");
                }
                else if(GetSystemMetrics(SM_SERVERR2)==0)
                    osname =_T("Microsoft Windows Server 2003");//2003年3月发布 
                else if(GetSystemMetrics(SM_SERVERR2)!=0)
                    osname =_T("Microsoft Windows Server 2003 R2");
                break;
            }
            break;

        case 6:
            switch(os.dwMinorVersion)
            {
            case 0:
                if(os.wProductType == VER_NT_WORKSTATION)
                    osname =_T("Microsoft Windows Vista");
                else
                    osname =_T("Microsoft Windows Server 2008");//服务器版本 
                break;
            case 1:
                if(os.wProductType == VER_NT_WORKSTATION)
                    osname =_T("Microsoft Windows 7");
                else
                    osname =_T("Microsoft Windows Server 2008 R2");
                break;
            }
            break;
        }
    }//if(GetVersionEx((OSVERSIONINFO *)&os))

} 

//读取操作系统的版本名称
void GetVersionMark(CString& vmark)
{
    OSVERSIONINFOEX os; 
    os.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX); 
    vmark = _T("");

    if(GetVersionEx((OSVERSIONINFO*)&os))
    { 
        switch(os.dwMajorVersion)
        {                //先判断操作系统版本 
        case 5: 
            switch(os.dwMinorVersion)
            { 
            case 0:                  //Windows 2000 
                if(os.wSuiteMask==VER_SUITE_ENTERPRISE) 
                    vmark=_T("Advanced Server"); 
                break; 
            case 1:                  //Windows XP 
                if(os.wSuiteMask==VER_SUITE_EMBEDDEDNT) 
                    vmark=_T("Embedded"); 
                else if(os.wSuiteMask==VER_SUITE_PERSONAL) 
                    vmark=_T("Home Edition"); 
                else 
                    vmark=_T("Professional"); 
                break; 
            case 2: 
                if(GetSystemMetrics(SM_SERVERR2)==0 
                    &&os.wSuiteMask==VER_SUITE_BLADE)  //Windows Server 2003 
                    vmark=_T("Web Edition");
                else if(GetSystemMetrics(SM_SERVERR2)==0 
                    && os.wSuiteMask==VER_SUITE_COMPUTE_SERVER)
                    vmark=_T("Compute Cluster Edition");
                else if(GetSystemMetrics(SM_SERVERR2)==0
                    && os.wSuiteMask==VER_SUITE_STORAGE_SERVER)
                    vmark=_T("Storage Server");
                else if(GetSystemMetrics(SM_SERVERR2)==0 
                    && os.wSuiteMask==VER_SUITE_DATACENTER)
                    vmark=_T("Datacenter Edition");
                else if(GetSystemMetrics(SM_SERVERR2)==0 
                    && os.wSuiteMask==VER_SUITE_ENTERPRISE)
                    vmark=_T("Enterprise Edition");
                else if(GetSystemMetrics(SM_SERVERR2)!=0
                    && os.wSuiteMask==VER_SUITE_STORAGE_SERVER)
                    vmark=_T("Storage Server");
                break;
            }
            break;

        case 6:
            switch(os.dwMinorVersion)
            {
            case 0:
                if(os.wProductType!=VER_NT_WORKSTATION 
                    && os.wSuiteMask==VER_SUITE_DATACENTER)
                    vmark=_T("Datacenter Server");
                else if(os.wProductType!=VER_NT_WORKSTATION 
                    && os.wSuiteMask==VER_SUITE_ENTERPRISE)
                    vmark=_T("Enterprise");
                else if(os.wProductType==VER_NT_WORKSTATION 
                    && os.wSuiteMask==VER_SUITE_PERSONAL)  //Windows Vista
                    vmark =_T("Home");
                break;
            }
            break;
        }
    }
}

方法2 预编译宏

这个方法其实我在文章《VC++开发GIS系统(3)关于#ifndef#define#endif的说明》中有过介绍,其实windwows已经预定义了关于系统信息的宏,Window各个版本对应的宏值如下:

Win8

_WIN32_WINNT>=0x0602
WINVER>=0x0602

Win7

_WIN32_WINNT>=0x0601
WINVER>=0x0601

Windows Server 2008 R2

_WIN32_WINNT>=0x0601
WINVER>=0x0601

Windows Server 2008

_WIN32_WINNT>=0x0600
WINVER>=0x0600

Windows Vista

_WIN32_WINNT>=0x0600
WINVER>=0x0600

Windows Server 2003

_WIN32_WINNT>=0x0502
WINVER>=0x0502

Windows XP

_WIN32_WINNT>=0x0501
WINVER>=0x0501

Windows 2000

_WIN32_WINNT>=0x0500
WINVER>=0x0500

Windows NT 4.0

_WIN32_WINNT>=0x0400
WINVER>=0x0400

Windows Me

_WIN32_WINDOWS=0x0500
WINVER>=0x0500

Windows 98

_WIN32_WINDOWS>=0x0410
WINVER>=0x0410

Windows 95

_WIN32_WINDOWS>=0x0400
WINVER>=0x0400

详细可参考:Windows中一些宏的含义 - 金石开

代码修改

知道方法,本文的兼容性修改也就简单多了

#if _WIN32_WINNT>= 0x0600
    SetWindowTheme(m_wndPrjView, L"Explorer", NULL);
#endif
VC++开发GIS系统(65)CTreeCtrl中不显示虚线 VC++开发GIS系统(67)工程面板CTreeCtrl响应右键菜单

作者:,GIS爱好者。
分享本文,请您带上本文链接
分享到:

发表评论