关于win7和xp的屏设置类及其Windows中双显示器

Posted 乌托邦2号

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于win7和xp的屏设置类及其Windows中双显示器相关的知识,希望对你有一定的参考价值。

(1)屏设置

DisplayInfo.h

#pragma once

enum WinVerDef

    WIN_VER_UNKNOWN = -1,
    WIN_VER_95 = 0,
    WIN_VER_98,
    WIN_VER_ME,
    WIN_VER_NT4,
    WIN_VER_2K,
    WIN_VER_XP,
    WIN_VER_XP64,
    WIN_VER_2K3,
    WIN_VER_2K3R2,
    WIN_VER_VISTA,
    WIN_VER_2K8,
    WIN_VER_2K8R2,
    WIN_VER_WIN7,
;



class CDisplayInfo

private:
    CDisplayInfo(void);
    ~CDisplayInfo(void);
public:
    enum DISPLAY_TYPE_SINGLE=8,DISPLAY_TYPE_CLONE=2,DISPLAY_TYPE_EXTEND=4;
    static int GetDisplayMode();
    static int GetDisplayModeXP();
    static int GetDisplayModeWin7();
    static BOOL SetScreenSaver(BOOL bCancle=TRUE,UINT newTime=-1);
    static BOOL SetPowerSaver(BOOL bCancle=TRUE,UINT newTime=-1);
    static BOOL SetDisplayMode(int iType,BOOL ExChange=FALSE);
    static BOOL SetDisplayModeXP(int iType,BOOL ExChange=FALSE);
    static BOOL SetDisplayModeWin7(int iType,BOOL ExChange=FALSE);
    static int GetDisplayCardType();
    static int AnalyCardType(LPCTSTR cardStr);
    static BOOL GetOSVersion( WinVerDef* winVer );
    static BOOL IsOlderSystem( WinVerDef specVer, INT* iResult );
    static BOOL GetPrimaryMonitorInfo(DEVMODE *dvm);
;

DisplayInfo.cpp

#include "StdAfx.h"
#include "DisplayInfo.h"


enum WinVerMajor

    WIN_MAJOR_NT4_ME_98_95          = 4,
    WIN_MAJOR_2K3R2_2K3_XP_2K       = 5,
    WIN_MAJOR_WIN7_2K8R2_2K8_VISTA  = 6,
;

// 定义目前存在的操作系统次版本号

enum WinVerminor

    WIN_MINOR_2K8_VISTA_2K_NT4_95   = 0,
    WIN_MINOR_WIN7_2K8R2_XP         = 1,
    WIN_MINOR_2K3R2_2K3_XP64        = 2,
    WIN_MINOR_98                    = 10,
    WIN_MINOR_ME                    = 90,
;
//typedef void (WINAPI *GetNativeSystemInfoFunc)(LPSYSTEM_INFO);

#define QDC_ALL_PATHS                   0x00000001
#define QDC_ONLY_ACTIVE_PATHS           0x00000002
#define QDC_DATABASE_CURRENT            0x00000004

//
// Definitions used by SetDisplayConfig.
//

#define SDC_TOPOLOGY_INTERNAL           0x00000001
#define SDC_TOPOLOGY_CLONE              0x00000002
#define SDC_TOPOLOGY_EXTEND             0x00000004
#define SDC_TOPOLOGY_EXTERNAL           0x00000008
#define SDC_TOPOLOGY_SUPPLIED           0x00000010
#define SDC_USE_DATABASE_CURRENT        (SDC_TOPOLOGY_INTERNAL | SDC_TOPOLOGY_CLONE | SDC_TOPOLOGY_EXTEND | SDC_TOPOLOGY_EXTERNAL)

#define SDC_USE_SUPPLIED_DISPLAY_CONFIG 0x00000020
#define SDC_VALIDATE                    0x00000040
#define SDC_APPLY                       0x00000080
#define SDC_NO_OPTIMIZATION             0x00000100
#define SDC_SAVE_TO_DATABASE            0x00000200
#define SDC_ALLOW_CHANGES               0x00000400
#define SDC_PATH_PERSIST_IF_REQUIRED    0x00000800
#define SDC_FORCE_MODE_ENUMERATION      0x00001000
#define SDC_ALLOW_PATH_ORDER_CHANGES    0x00002000

typedef enum  
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER                  = -1,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15                   = 0,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO                 = 1,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO        = 2,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO        = 3,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI                    = 4,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI                   = 5,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS                   = 6,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN                  = 8,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI                    = 9,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL   = 10,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED   = 11,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL           = 12,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED           = 13,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE             = 14,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL               = 0x80000000,
    DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32           = 0xFFFFFFFF
 DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY;

typedef enum  
    DISPLAYCONFIG_ROTATION_IDENTITY       = 1,
    DISPLAYCONFIG_ROTATION_ROTATE90       = 2,
    DISPLAYCONFIG_ROTATION_ROTATE180      = 3,
    DISPLAYCONFIG_ROTATION_ROTATE270      = 4,
    DISPLAYCONFIG_ROTATION_FORCE_UINT32   = 0xFFFFFFFF
 DISPLAYCONFIG_ROTATION;

typedef enum  
    DISPLAYCONFIG_SCALING_IDENTITY                 = 1,
    DISPLAYCONFIG_SCALING_CENTERED                 = 2,
    DISPLAYCONFIG_SCALING_STRETCHED                = 3,
    DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX   = 4,
    DISPLAYCONFIG_SCALING_CUSTOM                   = 5,
    DISPLAYCONFIG_SCALING_PREFERRED                = 128,
    DISPLAYCONFIG_SCALING_FORCE_UINT32             = 0xFFFFFFFF
 DISPLAYCONFIG_SCALING;
typedef struct DISPLAYCONFIG_RATIONAL 
    UINT32 Numerator;
    UINT32 Denominator;
 DISPLAYCONFIG_RATIONAL;
typedef enum  
    DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED                  = 0,
    DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE                  = 1,
    DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED                   = 2,
    DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST   = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED,
    DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST   = 3,
    DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32                 = 0xFFFFFFFF
 DISPLAYCONFIG_SCANLINE_ORDERING;

typedef enum  
    DISPLAYCONFIG_PIXELFORMAT_8BPP           = 1,
    DISPLAYCONFIG_PIXELFORMAT_16BPP          = 2,
    DISPLAYCONFIG_PIXELFORMAT_24BPP          = 3,
    DISPLAYCONFIG_PIXELFORMAT_32BPP          = 4,
    DISPLAYCONFIG_PIXELFORMAT_NONGDI         = 5,
    DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32   = 0xffffffff
 DISPLAYCONFIG_PIXELFORMAT;
typedef enum  
    DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE         = 1,
    DISPLAYCONFIG_MODE_INFO_TYPE_TARGET         = 2,
    DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32   = 0xFFFFFFFF
 DISPLAYCONFIG_MODE_INFO_TYPE;

typedef enum  
    DISPLAYCONFIG_TOPOLOGY_INTERNAL       = 0x00000001,
    DISPLAYCONFIG_TOPOLOGY_CLONE          = 0x00000002,
    DISPLAYCONFIG_TOPOLOGY_EXTEND         = 0x00000004,
    DISPLAYCONFIG_TOPOLOGY_EXTERNAL       = 0x00000008,
    DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32   = 0xFFFFFFFF
 DISPLAYCONFIG_TOPOLOGY_ID;

typedef struct DISPLAYCONFIG_PATH_TARGET_INFO 
    LUID                                  adapterId;
    UINT32                                id;
    UINT32                                modeInfoIdx;
    DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
    DISPLAYCONFIG_ROTATION                rotation;
    DISPLAYCONFIG_SCALING                 scaling;
    DISPLAYCONFIG_RATIONAL                refreshRate;
    DISPLAYCONFIG_SCANLINE_ORDERING       scanLineOrdering;
    BOOL                                  targetAvailable;
    UINT32                                statusFlags;
 DISPLAYCONFIG_PATH_TARGET_INFO;
typedef struct DISPLAYCONFIG_PATH_SOURCE_INFO 
    LUID   adapterId;
    UINT32 id;
    UINT32 modeInfoIdx;
    UINT32 statusFlags;
 DISPLAYCONFIG_PATH_SOURCE_INFO;
typedef struct DISPLAYCONFIG_PATH_INFO 
    DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo;
    DISPLAYCONFIG_PATH_TARGET_INFO targetInfo;
    UINT32                         flags;
 DISPLAYCONFIG_PATH_INFO;
typedef struct DISPLAYCONFIG_2DREGION 
    UINT32 cx;
    UINT32 cy;
 DISPLAYCONFIG_2DREGION;
typedef struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO 
    UINT64                          pixelRate;
    DISPLAYCONFIG_RATIONAL          hSyncFreq;
    DISPLAYCONFIG_RATIONAL          vSyncFreq;
    DISPLAYCONFIG_2DREGION          activeSize;
    DISPLAYCONFIG_2DREGION          totalSize;
    UINT32                          videoStandard;
    DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
 DISPLAYCONFIG_VIDEO_SIGNAL_INFO;

typedef struct DISPLAYCONFIG_TARGET_MODE 
    DISPLAYCONFIG_VIDEO_SIGNAL_INFO targetVideoSignalInfo;
 DISPLAYCONFIG_TARGET_MODE;

typedef struct DISPLAYCONFIG_SOURCE_MODE 
    UINT32                    width;
    UINT32                    height;
    DISPLAYCONFIG_PIXELFORMAT pixelFormat;
    POINTL                    position;
 DISPLAYCONFIG_SOURCE_MODE;

typedef struct DISPLAYCONFIG_MODE_INFO 
    DISPLAYCONFIG_MODE_INFO_TYPE infoType;
    UINT32                       id;
    LUID                         adapterId;
    union 
        DISPLAYCONFIG_TARGET_MODE targetMode;
        DISPLAYCONFIG_SOURCE_MODE sourceMode;
    ;
 DISPLAYCONFIG_MODE_INFO;
typedef LONG (WINAPI *SETDISPLAYCONFIGFUNC)(__in      UINT32 numPathArrayElements,
                                        __in_opt  DISPLAYCONFIG_PATH_INFO *pathArray,
                                        __in      UINT32 numModeInfoArrayElements,
                                        __in_opt  DISPLAYCONFIG_MODE_INFO *modeInfoArray,
                                        __in      UINT32 Flags
                                        );
typedef LONG (WINAPI *GETDISPLAYBUFFERSIZESFUNC)(
                                 __in   UINT32 Flags,
                                 __out  UINT32 *pNumPathArrayElements,
                                 __out  UINT32 *pNumModeInfoArrayElements
                                 );

typedef LONG (WINAPI *QUERYDISPLAYCONFIGFUNC)(
                        __in       UINT32 Flags,
                        __inout    UINT32 *pNumPathArrayElements,
                        __out      DISPLAYCONFIG_PATH_INFO *pPathInfoArray,
                        __inout    UINT32 *pNumModeInfoArrayElements,
                        __out      DISPLAYCONFIG_MODE_INFO *pModeInfoArray,
                        __out_opt  DISPLAYCONFIG_TOPOLOGY_ID *pCurrentTopologyId
                        );


CDisplayInfo::CDisplayInfo(void)



CDisplayInfo::~CDisplayInfo(void)



//功能: 设置/取消屏保
//参数: bCancle: TRUE取消屏保,此时会自动记录原来的屏保时间.FALSE设置屏保,如果newTime为-1,则恢复原来的屏保时间.
//      newTime:屏保时间,如果为-1,则被忽略.
BOOL CDisplayInfo::SetScreenSaver(BOOL bCancle/* =TRUE */,UINT newTime/* =-1 */)

    static UINT ScrSaverTimeOut=600;
    if(bCancle)
    
        //读取原来的屏保时间,以便恢复
        ::SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT,0,&ScrSaverTimeOut,0);

        //取消屏保.
        ::SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,FALSE,0,SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
    
    else
    
        UINT TimeOut=ScrSaverTimeOut;
        if(newTime != UINT(-1))
        
            TimeOut=newTime;
        
        //设置原来的屏保时间
        ::SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT,TimeOut,NULL,SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
        //激活屏保.
        ::SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,TRUE,0,SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
    
    return TRUE;


//功能: 设置/取消显示器电源自动关闭.
//参数: bCancle: TRUE取消自动关闭显示器电源,FLASE设置自动关闭显示器电源.
//      newTime: 新的显示器电源自动关闭时间,如果为-1,设置时按原来显示器电源时间设置.
BOOL CDisplayInfo::SetPowerSaver(BOOL bCancle/* =TRUE */,UINT newTime/* =-1 */)

    static UINT PowerTimeout=900;
    if(bCancle)
    
        //获得原来电源时间.
        ::SystemParametersInfo(SPI_GETPOWEROFFTIMEOUT,0,&PowerTimeout,0);
        //取消自动关闭显示器
        //这里不能用SPI_SETPOWEROFFACTIVE,用这个标记不能成功.
        ::SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT,FALSE,0,SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
    
    else
    
        UINT TimeOut=PowerTimeout;
        if(newTime != UINT(-1))
        
            TimeOut=newTime;
        
        //设置原来的电源时间.
        ::SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT,TimeOut,NULL,SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
        //激活自动关闭显示器.
        ::SystemParametersInfo(SPI_SETPOWEROFFACTIVE,TRUE,0,SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
    
    return TRUE;


//功能: 获得Win7n以前OS当前多显示器的显示模式.
//返回值: DISPLAY_TYPE_SINGLE:单显示器;
//        DISPLAY_TYPE_CLONE ;复制模式
//        DISPLAY_TYPE_EXTEND:扩展模式;
int CDisplayInfo::GetDisplayModeXP()

    if( 1 != GetDisplayCardType())//是否ATI显卡
    
        return 0;
    
    DISPLAY_DEVICE DispDev;
    TCHAR szSaveDeviceName[0x60];
    BOOL bRet = TRUE;

    DEVMODE dvm;
    dvm.dmSize=sizeof(DEVMODE);
    dvm.dmDriverExtra=0;
    dvm.dmFields=DM_POSITION;

    ZeroMemory(&DispDev, sizeof(DISPLAY_DEVICE));
    DispDev.cb = sizeof(DISPLAY_DEVICE);


    DWORD d1=0,d2=0,d1m0=0,d1m1=0,d2m0=0,d2m1=0;

    CString Str,outStr;
    int i=0,j=0;
    BOOL bRet2=TRUE;
    DWORD erro=0;
    int jDev=0;
    while(bRet)
    
        bRet=EnumDisplayDevices(NULL,i,&DispDev,0);//遍历当前设备.
        if(bRet)
        
            memset(szSaveDeviceName,0,0x60);
            lstrcpy(szSaveDeviceName, DispDev.DeviceName);
            bRet2=TRUE;
            j=0;
            OutputDebugString(szSaveDeviceName);
            Str.Format(TEXT("%08X  ------------------------------------"),DispDev.StateFlags);
            OutputDebugString(Str);
            if(i==0)
            
                d1=DispDev.StateFlags;
            
            else if(i==1)
            
                d2=DispDev.StateFlags;
            
            while(bRet2)
            
                bRet2=EnumDisplayDevices(szSaveDeviceName,j,&DispDev,0);//遍历指定设备下的其它设备参数.
                if(bRet2)
                
                    j++;
                    if(_tcsstr(DispDev.DeviceName,TEXT("Default_Monitor"))!=NULL)
                    
                        continue;
                    
                    BOOL t=EnumDisplaySettings(DispDev.DeviceName,ENUM_CURRENT_SETTINGS,&dvm);//遍历指定设备的当前配置.
                    if(t==FALSE)
                    
                        erro=GetLastError();
                    
                    OutputDebugString(DispDev.DeviceName);
                    //OutputDebugString(DispDev.DeviceString);
                    OutputDebugString(DispDev.DeviceID);//LED
                    //OutputDebugString(DispDev.DeviceKey);
                    Str.Format(TEXT("%08X\\r\\n"),DispDev.StateFlags);
                    OutputDebugString(Str);
                    if(i==0)
                    
                        if(jDev==0)
                        
                            d1m0=DispDev.StateFlags;
                        
                        else if(jDev==1)
                        
                            d1m1=DispDev.StateFlags;
                        
                    
                    else if(i==1)
                    
                        if(jDev==0)
                        
                            d2m0=DispDev.StateFlags;
                        
                        else if(jDev==1)
                        
                            d2m1=DispDev.StateFlags;
                        
                    
                    jDev++;
                

            
        
        ++i;
    

    if((d1&DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)==DISPLAY_DEVICE_ATTACHED_TO_DESKTOP &&
        (d2&DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)==DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
    
        OutputDebugString(TEXT("扩展模式"));
        return DISPLAY_TYPE_EXTEND;
    

    if( (d1m0&DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)==DISPLAY_DEVICE_ATTACHED_TO_DESKTOP &&
        (d1m1&DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)==DISPLAY_DEVICE_ATTACHED_TO_DESKTOP )
    
        OutputDebugString(TEXT("复制模式"));
        return DISPLAY_TYPE_CLONE;
    

    OutputDebugString(TEXT("单显示器"));
    return DISPLAY_TYPE_SINGLE;


//功能: 获得Win7下当前多显示器的显示模式.
//返回值: DISPLAY_TYPE_SINGLE:单显示器;
//        DISPLAY_TYPE_CLONE ;复制模式
//        DISPLAY_TYPE_EXTEND:扩展模式;
int CDisplayInfo::GetDisplayModeWin7()

    QUERYDISPLAYCONFIGFUNC    QueryDisplayConfig=NULL;
    HMODULE hMod=LoadLibrary(TEXT("user32.dll"));
    if(hMod)
    
        QueryDisplayConfig=(QUERYDISPLAYCONFIGFUNC)GetProcAddress(hMod,"QueryDisplayConfig");
        if( QueryDisplayConfig)
        
            UINT32 NumPathArrayElements = 0;
            UINT32 NumModeInfoArrayElements = 0;
            LONG returnValue=0;
            DISPLAYCONFIG_TOPOLOGY_ID topID=DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32;
            returnValue = QueryDisplayConfig(
                QDC_DATABASE_CURRENT,
                NULL, NULL,
                NULL, NULL,
                &topID);
            if(returnValue == ERROR_SUCCESS)
            
                int ret=0;
                switch(topID)
                
                case DISPLAYCONFIG_TOPOLOGY_CLONE:
                    ret=DISPLAY_TYPE_CLONE;
                    break;
                case DISPLAYCONFIG_TOPOLOGY_EXTEND:
                    ret=DISPLAY_TYPE_EXTEND;
                    break;
                default:
                    ret=DISPLAY_TYPE_SINGLE;
                    break;
                
                return ret;
            
        
    
    return 0;



//功能: 获得当前多显示器的显示模式.
//返回值: DISPLAY_TYPE_SINGLE:单显示器;
//        DISPLAY_TYPE_CLONE ;复制模式
//        DISPLAY_TYPE_EXTEND:扩展模式;
int CDisplayInfo::GetDisplayMode()

    WinVerDef OsVer;
    int ret=0;
    if(GetOSVersion(&OsVer))
    
        switch(OsVer)
        
        case WIN_VER_WIN7:
            ret=GetDisplayModeWin7();
            break;
        default:
            ret=GetDisplayModeXP();
            break;
        
    
    return ret;


BOOL CDisplayInfo::GetPrimaryMonitorInfo(DEVMODE *dvm)

    if(dvm==NULL)
    
        return FALSE;
    
    dvm->dmSize=sizeof(DEVMODE);

    DISPLAY_DEVICE DispDev;
    BOOL bRet = TRUE;
    ZeroMemory(&DispDev, sizeof(DISPLAY_DEVICE));
    DispDev.cb = sizeof(DISPLAY_DEVICE);
    int i=0;
    DWORD erro=0;
    while(bRet)
    
        bRet=EnumDisplayDevices(NULL,i,&DispDev,0);
        if(bRet)
        
            if(DispDev.StateFlags&DISPLAY_DEVICE_PRIMARY_DEVICE)
            
                bRet=EnumDisplaySettings(DispDev.DeviceName,ENUM_CURRENT_SETTINGS,dvm);
                if(bRet)
                
                    return TRUE;
                
            
        
        i++;
    
    return FALSE;


//功能:设置多显示器显示模式
//参数:iType;显示模式,可选以下三种:
//     DISPLAY_TYPE_SINGLE; 单显示器
//     DISPLAY_TYPE_CLONE;  复制模式
//     DISPLAY_TYEP_EXTEND; 扩展模式

BOOL CDisplayInfo::SetDisplayMode(int iType,BOOL ExChange/* =FALSE */)

    WinVerDef osVer;
    if(GetOSVersion(&osVer))
    
        if(osVer==WIN_VER_WIN7)
        
            OutputDebugString(TEXT("Win7"));
            SetDisplayModeWin7(iType,ExChange);
        
        else
        
            OutputDebugString(TEXT("Other OS"));
            SetDisplayModeXP(iType,ExChange);
        
        return TRUE;
    
    return FALSE;


//临时测试用
void OutPath(DISPLAYCONFIG_PATH_INFO *pPath)

    CString Str;
    Str=TEXT("--------------------PATH-----------------------\\r\\n");
    OutputDebugString(Str);
    Str.Format(TEXT("state:%08X\\r\\n"),pPath->flags);
    OutputDebugString(Str);
    Str.Format(TEXT("source:\\r\\nadapterID_H:%08X L:%08X\\r\\nID:%08X\\r\\nModeIndex:%08X\\r\\nFlag:%08X"),
        pPath->sourceInfo.adapterId.HighPart,pPath->sourceInfo.adapterId.LowPart,
        pPath->sourceInfo.id,pPath->sourceInfo.modeInfoIdx,pPath->sourceInfo.statusFlags);
    OutputDebugString(Str);
    Str.Format(TEXT("target:\\r\\nadapterId H: %08X L:%08X ID:%08X Index:%08X"),
        pPath->targetInfo.adapterId.HighPart,pPath->targetInfo.adapterId.LowPart,
        pPath->targetInfo.id,pPath->targetInfo.modeInfoIdx);
    OutputDebugString(Str);

    switch(pPath->targetInfo.outputTechnology)//输出类型.
    
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO :
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO :
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN:
        OutputDebugStringA("outputTechnology: outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE\\r\\n");
        break;
    case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL :
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL\\r\\n");
        break;
    /*case DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32:
        OutputDebugStringA("outputTechnology: DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32\\r\\n");
        break;*/
    

    Str.Format(TEXT("refreshRate--Numerator:%-08X Denominator:%08X"),
        pPath->targetInfo.refreshRate.Numerator,pPath->targetInfo.refreshRate.Denominator);

    switch(pPath->targetInfo.rotation)
    
    case DISPLAYCONFIG_ROTATION_IDENTITY:
        OutputDebugString(TEXT("rotation: DISPLAYCONFIG_ROTATION_IDENTITY\\r\\n"));
        break;
    case DISPLAYCONFIG_ROTATION_ROTATE90:
        OutputDebugString(TEXT("rotation: DISPLAYCONFIG_ROTATION_ROTATE90\\r\\n"));
        break;
    case DISPLAYCONFIG_ROTATION_ROTATE180:
        OutputDebugString(TEXT("rotation: DISPLAYCONFIG_ROTATION_ROTATE180\\r\\n"));
        break;
    case DISPLAYCONFIG_ROTATION_ROTATE270:
        OutputDebugString(TEXT("rotation: DISPLAYCONFIG_ROTATION_ROTATE270\\r\\n"));
        break;
    case DISPLAYCONFIG_ROTATION_FORCE_UINT32:
        OutputDebugString(TEXT("rotation: DISPLAYCONFIG_ROTATION_FORCE_UINT32\\r\\n"));
        break;
    

    switch(pPath->targetInfo.scaling)
    
    case DISPLAYCONFIG_SCALING_IDENTITY:
        OutputDebugString(TEXT("scaling: DISPLAYCONFIG_SCALING_IDENTITY\\r\\n"));
        break;
    case DISPLAYCONFIG_SCALING_CENTERED:
        OutputDebugString(TEXT("scaling: DISPLAYCONFIG_SCALING_CENTERED\\r\\n"));
        break;
    case DISPLAYCONFIG_SCALING_STRETCHED:
        OutputDebugString(TEXT("scaling: DISPLAYCONFIG_SCALING_STRETCHED\\r\\n"));
        break;
    case DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX:
        OutputDebugString(TEXT("scaling: DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX\\r\\n"));
        break;
    case DISPLAYCONFIG_SCALING_CUSTOM:
        OutputDebugString(TEXT("scaling: DISPLAYCONFIG_SCALING_CUSTOM\\r\\n"));
        break;
    case DISPLAYCONFIG_SCALING_PREFERRED:
        OutputDebugString(TEXT("scaling: DISPLAYCONFIG_SCALING_PREFERRED\\r\\n"));
        break;
    case DISPLAYCONFIG_SCALING_FORCE_UINT32:
        OutputDebugString(TEXT("scaling: DISPLAYCONFIG_SCALING_FORCE_UINT32\\r\\n"));
        break;
    
    switch(pPath->targetInfo.scanLineOrdering)
    
    case DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED:
        OutputDebugString(TEXT("scanLineOrdering: DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED\\r\\n"));
        break;
    case DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE:
        OutputDebugString(TEXT("scanLineOrdering: \\r\\n"));
        break;
    case DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED:
        OutputDebugString(TEXT("scanLineOrdering: DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE\\r\\n"));
        break;
    /*case DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST:
        OutputDebugString(TEXT("scanLineOrdering: DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST\\r\\n"));
        break;*/
    case DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST:
        OutputDebugString(TEXT("scanLineOrdering: DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST\\r\\n"));
        break;
    case DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32:
        OutputDebugString(TEXT("scanLineOrdering: DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32\\r\\n"));
        break;
    
    Str.Format(TEXT("state:%08X  valiable:%08X"),
        pPath->targetInfo.statusFlags,pPath->targetInfo.targetAvailable);
    OutputDebugString(Str);


//临时测试用
void OutMode(DISPLAYCONFIG_MODE_INFO *pMode)

    CString Str;
    OutputDebugString(TEXT("-----------------------MODE------------------------\\r\\n"));
    Str.Format(TEXT("adpterID H:%08X L:%98X ID:%08X"),
        pMode->adapterId.HighPart,pMode->adapterId.LowPart,pMode->id);
    OutputDebugString(Str);
    switch(pMode->infoType)
    
    case DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE:
        OutputDebugString(TEXT("infotype DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE\\r\\n"));
        break;
    case DISPLAYCONFIG_MODE_INFO_TYPE_TARGET:
        OutputDebugString(TEXT("infotype DISPLAYCONFIG_MODE_INFO_TYPE_TARGET\\r\\n"));
        break;
    case DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32:
        OutputDebugString(TEXT("infotype DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32\\r\\n"));
        break;
    
    switch(pMode->sourceMode.pixelFormat)
    
    case DISPLAYCONFIG_PIXELFORMAT_16BPP:
        OutputDebugString(TEXT("source pixelFormat: DISPLAYCONFIG_PIXELFORMAT_16BPP\\r\\n"));
        break;
    case DISPLAYCONFIG_PIXELFORMAT_8BPP:
        OutputDebugString(TEXT("source pixelFormat: DISPLAYCONFIG_PIXELFORMAT_8BPP\\r\\n"));
        break;
    case DISPLAYCONFIG_PIXELFORMAT_32BPP:
        OutputDebugString(TEXT("source pixelFormat: DISPLAYCONFIG_PIXELFORMAT_32BPP\\r\\n"));
        break;
    case DISPLAYCONFIG_PIXELFORMAT_24BPP:
        OutputDebugString(TEXT("source pixelFormat: DISPLAYCONFIG_PIXELFORMAT_24BPP\\r\\n"));
        break;
    case DISPLAYCONFIG_PIXELFORMAT_NONGDI:
        OutputDebugString(TEXT("source pixelFormat: DISPLAYCONFIG_PIXELFORMAT_NONGDI\\r\\n"));
        break;
    case DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32:
        OutputDebugString(TEXT("source pixelFormat: DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32\\r\\n"));
        break;
    
    Str.Format(TEXT("source pos(%d,%d) Width:%d Height:%d\\r\\n"),
        pMode->sourceMode.position.x,pMode->sourceMode.position.y,
        pMode->sourceMode.width,pMode->sourceMode.height);
    OutputDebugString(Str);

    Str.Format(TEXT("target activeSize(CX=%d,cy=%d)\\r\\n"),
        pMode->targetMode.targetVideoSignalInfo.activeSize.cx,pMode->targetMode.targetVideoSignalInfo.activeSize.cy);
    OutputDebugString(Str);
    Str.Format(TEXT("target totalsize(cx=%d,cy=%d)"),
        pMode->targetMode.targetVideoSignalInfo.totalSize.cx,
        pMode->targetMode.targetVideoSignalInfo.totalSize.cy);
    OutputDebugString(Str);
    Str.Format(TEXT("target pixelRate:%016X videoStander:%08X\\r\\n"),
        pMode->targetMode.targetVideoSignalInfo.pixelRate,
        pMode->targetMode.targetVideoSignalInfo.videoStandard);
    OutputDebugString(Str);

    Str.Format(TEXT("target Hfreq Numerator:%08X Denominator:%08X\\r\\n"),
        pMode->targetMode.targetVideoSignalInfo.hSyncFreq.Numerator,
        pMode->targetMode.targetVideoSignalInfo.hSyncFreq.Denominator);
    OutputDebugString(Str);
    Str.Format(TEXT("target Vfreq Numerator:%08X Denominator:%08X\\r\\n"),
        pMode->targetMode.targetVideoSignalInfo.vSyncFreq.Numerator,
        pMode->targetMode.targetVideoSignalInfo.vSyncFreq.Denominator);
    OutputDebugString(Str);
    switch(pMode->targetMode.targetVideoSignalInfo.scanLineOrdering)
    
        case DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED:
        OutputDebugString(TEXT("scanLineOrdering: DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED\\r\\n"));
        break;
    case DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE:
        OutputDebugString(TEXT("scanLineOrdering: \\r\\n"));
        break;
    case DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED:
        OutputDebugString(TEXT("scanLineOrdering: DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE\\r\\n"));
        break;
    /*case DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST:
        OutputDebugString(TEXT("scanLineOrdering: DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST\\r\\n"));
        break;*/
    case DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST:
        OutputDebugString(TEXT("scanLineOrdering: DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST\\r\\n"));
        break;
    case DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32:
        OutputDebugString(TEXT("scanLineOrdering: DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32\\r\\n"));
        break;
    




BOOL CDisplayInfo::SetDisplayModeWin7(int iType,BOOL ExChange/* =FALSE */)

    SETDISPLAYCONFIGFUNC      SetDisplayConfig=NULL;
    GETDISPLAYBUFFERSIZESFUNC GetDisplayConfigBufferSizes=NULL;
    QUERYDISPLAYCONFIGFUNC    QueryDisplayConfig=NULL;
    HMODULE hMod=LoadLibrary(TEXT("user32.dll"));
    if(hMod)
    
        OutputDebugString(TEXT("Load OK"));
        SetDisplayConfig=(SETDISPLAYCONFIGFUNC)GetProcAddress(hMod,"SetDisplayConfig");
        GetDisplayConfigBufferSizes=(GETDISPLAYBUFFERSIZESFUNC)(GetProcAddress(hMod,"GetDisplayConfigBufferSizes"));
        QueryDisplayConfig=(QUERYDISPLAYCONFIGFUNC)GetProcAddress(hMod,"QueryDisplayConfig");
        if(SetDisplayConfig && GetDisplayConfigBufferSizes && QueryDisplayConfig)
        
            UINT32 NumPathArrayElements = 0;
            UINT32 NumModeInfoArrayElements = 0;
            LONG returnValue;
            returnValue = GetDisplayConfigBufferSizes(
                QDC_ALL_PATHS,
                &NumPathArrayElements,
                &NumModeInfoArrayElements); // Returns Success
            if (returnValue != ERROR_SUCCESS)
            
                OutputDebugString(TEXT("GetDisplayConfigBufferSizes error"));
            
            DISPLAYCONFIG_PATH_INFO *pPathInfoArray =
                new DISPLAYCONFIG_PATH_INFO[NumPathArrayElements];

            DISPLAYCONFIG_MODE_INFO *pModeInfoArray =
                new DISPLAYCONFIG_MODE_INFO[NumModeInfoArrayElements];

            DISPLAYCONFIG_TOPOLOGY_ID topID=DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32;
            returnValue = QueryDisplayConfig(
                QDC_ALL_PATHS,
                &NumPathArrayElements, pPathInfoArray,
                &NumModeInfoArrayElements, pModeInfoArray,
                NULL);
            if(returnValue != ERROR_SUCCESS)
            
                OutputDebugString(TEXT(" QueryDisplayConfig erro"));
            
            CString Str;
            for(int iPath=0;iPath<NumPathArrayElements;++iPath)
            
                OutPath(&pPathInfoArray[iPath]);
            
            for(int iMode=0;iMode<NumModeInfoArrayElements;++iMode)
            
                OutMode(&pModeInfoArray[iMode]);
            
            /*switch(topID)
            
            case DISPLAYCONFIG_TOPOLOGY_CLONE:
                OutputDebugString(TEXT("DISPLAYCONFIG_TOPOLOGY_CLONE"));
                break;
            case DISPLAYCONFIG_TOPOLOGY_INTERNAL:
                OutputDebugString(TEXT("DISPLAYCONFIG_TOPOLOGY_INTERNAL"));
                break;
            case DISPLAYCONFIG_TOPOLOGY_EXTEND:
                OutputDebugString(TEXT("DISPLAYCONFIG_TOPOLOGY_EXTEND"));
                break;
            case DISPLAYCONFIG_TOPOLOGY_EXTERNAL:
                OutputDebugString(TEXT("DISPLAYCONFIG_TOPOLOGY_EXTERNAL"));
                break;
            case DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32:
                OutputDebugString(TEXT("DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32"));
                break;
            default:
                break;
            */

            OutputDebugString(TEXT("Get OK"));
            //returnValue=SetDisplayConfig(NumPathArrayElements,pPathInfoArray,NumModeInfoArrayElements,pModeInfoArray,SDC_TOPOLOGY_CLONE|SDC_APPLY);
            returnValue=SetDisplayConfig(0,NULL,0,NULL,iType|SDC_APPLY);//设置DC_TOPOLOGY_XXX前面4个参数must be 0;
            switch(returnValue)
            
            case ERROR_SUCCESS:
                OutputDebugString(TEXT("ERRO_SUCESS"));
                break;
            case ERROR_INVALID_PARAMETER:
                OutputDebugString(TEXT("ERROR_INVALID_PARAMETER"));
                break;
            case ERROR_NOT_SUPPORTED:
                OutputDebugString(TEXT("ERROR_NOT_SUPPORTED"));
                break;
            case ERROR_ACCESS_DENIED:
                OutputDebugString(TEXT("ERROR_ACCESS_DENIED"));
                break;
            case ERROR_GEN_FAILURE:
                OutputDebugString(TEXT("ERROR_GEN_FAILURE"));
                break;
            case ERROR_INSUFFICIENT_BUFFER:
                OutputDebugString(TEXT("ERROR_INSUFFICIENT_BUFFER"));
                break;
            default:
                OutputDebugString(TEXT("unkonw"));
            
            FreeLibrary(hMod);
            return TRUE;
        
        FreeLibrary(hMod);
    
    return FALSE;


BOOL CDisplayInfo::SetDisplayModeXP(int iType,BOOL ExChange/*=0*/)

    DEVMODE dvm1;
    memset(&dvm1, 0, sizeof(dvm1));
    dvm1.dmSize = sizeof(dvm1);
    DEVMODE dvm2;
    memset(&dvm2, 0, sizeof(DEVMODE));
    dvm2.dmSize = sizeof(DEVMODE);

    TCHAR PriDevName[0x100]=0;
    TCHAR AddDevName[0x100]=0;

    DISPLAY_DEVICE DispDev;
    BOOL bRet = TRUE;
    ZeroMemory(&DispDev, sizeof(DISPLAY_DEVICE));
    DispDev.cb = sizeof(DISPLAY_DEVICE);
    int i=0;
    int nOffset=0;
    BOOL bAnaly=FALSE;
    while(bRet)
    
        bRet=EnumDisplayDevices(NULL,i,&DispDev,0);
        if(bAnaly==FALSE)
        
            bAnaly=TRUE;
            if(1==AnalyCardType(DispDev.DeviceName))//只能是API显示卡
            
                return FALSE;
            
            bAnaly=TRUE;
        
        if(bRet)
        
            if(DispDev.StateFlags&DISPLAY_DEVICE_PRIMARY_DEVICE)
            
                _tcscpy_s(PriDevName,0x100,DispDev.DeviceName);
                bRet=EnumDisplaySettingsEx(DispDev.DeviceName,ENUM_CURRENT_SETTINGS,&dvm1,EDS_RAWMODE);
            
            else if((DispDev.StateFlags&0xFFFF)<8)
            
                _tcscpy_s(AddDevName,0x100,DispDev.DeviceName);
            
        
        i++;
        if(i==2)
        
            break;
        
    
    if(i==1)//只有一个显示器,不能进行模式设置.
    
        return FALSE;
    

    dvm1.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_POSITION ;
    dvm2.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_POSITION ;
    //dvm2=dvm1;
    dvm2.dmPelsHeight=dvm1.dmPelsHeight;
    dvm2.dmPelsWidth=dvm1.dmPelsWidth;
    switch(iType)
    
    case DISPLAY_TYPE_SINGLE:
        dvm2.dmPelsHeight=0;//设置成单显示器.
        dvm2.dmPelsWidth=0;
        break;
    case DISPLAY_TYPE_CLONE://当两个显示器同时有效时,偏移不重叠.克隆模式就不能直接设置.
        //dvm2.dmPelsHeight=0;
        //dvm2.dmPelsWidth=0;
        break;
    case DISPLAY_TYPE_EXTEND:
        nOffset=dvm1.dmPelsWidth;//强制横向向右扩展,
        break;
    default:
        break;
    
    dvm1.dmPosition.x=0;
    dvm1.dmPosition.y=0;
    dvm2.dmPosition.x=nOffset;
    dvm2.dmPosition.y=0;

    CString Str;
    Str.Format(TEXT("Pri: %s (%d,%d,%d,%d)\\r\\n"),PriDevName,dvm1.dmPosition.x,dvm1.dmPosition.y,
        dvm1.dmPelsWidth,dvm1.dmPelsHeight);
    OutputDebugString(Str);
    Str.Format(TEXT("Add: %s (%d,%d,%d,%d)\\r\\n"),AddDevName,dvm2.dmPosition.x,dvm2.dmPosition.y,
        dvm2.dmPelsWidth,dvm2.dmPelsHeight);
    OutputDebugString(Str);

    if(ExChange && (iType==DISPLAY_TYPE_EXTEND || iType==DISPLAY_TYPE_SINGLE))//如果需要交换显示,则改变主显示器
    
        ChangeDisplaySettingsEx(PriDevName, &dvm2, NULL, CDS_NORESET | CDS_UPDATEREGISTRY , 0);
        ChangeDisplaySettingsEx(AddDevName, &dvm1, NULL, CDS_SET_PRIMARY | CDS_NORESET | CDS_UPDATEREGISTRY, 0);
    
    else
    
        ChangeDisplaySettingsEx(PriDevName, &dvm1, NULL, CDS_SET_PRIMARY | CDS_NORESET | CDS_UPDATEREGISTRY, 0);
        ChangeDisplaySettingsEx(AddDevName, &dvm2, NULL, CDS_NORESET | CDS_UPDATEREGISTRY , 0);
    

    ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, 0);//使有效

    return TRUE;


int CDisplayInfo::AnalyCardType(LPCTSTR cardStr)

    if(cardStr==NULL)
    
        return 0;
    
    OutputDebugString(cardStr);
    TCHAR buf[0x100]=0;
    _tcscpy_s(buf,0x100,cardStr);
    _tcsupr_s(buf,100);
    if(_tcsstr(buf,TEXT("ATI")))
    
        return 1;
    
    else if(_tcsstr(buf,TEXT("NVIDIA")))
    
        return 2;
    
    else
    
        return 3;
    


//功能:获得显卡类型,ATI=1,NVDIA.=2...
int CDisplayInfo::GetDisplayCardType()

    DISPLAY_DEVICE DispDev;
    TCHAR szSaveDeviceName[0x60];
    BOOL bRet = TRUE;



    ZeroMemory(&DispDev, sizeof(DISPLAY_DEVICE));
    DispDev.cb = sizeof(DISPLAY_DEVICE);

    CString Str,outStr;
    int i=0;
    BOOL bRet2=TRUE;
    DWORD erro=0;
    while(bRet)
    
        bRet=EnumDisplayDevices(NULL,i,&DispDev,0);
        if(bRet)
        
            memset(szSaveDeviceName,0,0x60);
            lstrcpy(szSaveDeviceName, DispDev.DeviceName);
            bRet2=TRUE;
            OutputDebugString(szSaveDeviceName);
            OutputDebugString(DispDev.DeviceString);
            return AnalyCardType(DispDev.DeviceString);
        
        i++;
    
    return 0;


//功能:返回系统版本号
//参数:winVer返回版本号.
BOOL CDisplayInfo::GetOSVersion( WinVerDef* winVer )

    OSVERSIONINFOEX osversionInfo;
    ZeroMemory( &osversionInfo, sizeof(osversionInfo) );
    osversionInfo.dwOSVersionInfoSize = sizeof(osversionInfo);
    *winVer = WIN_VER_UNKNOWN;

    /*BOOL bOsVersionInfoEx=FALSE;//是否是早期版本,FALSE为早期版本,TRUE为校新版本.
    if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osversionInfo)) )
    
        osversionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);//更早期系统需要从注册表中读取一些版本信息.
        if (! GetVersionEx ( (OSVERSIONINFO *) &osversionInfo) )
            return FALSE;
    */

     if ( NULL == winVer || FALSE == GetVersionEx((LPOSVERSIONINFO)&osversionInfo) )
     
         return FALSE;
     
    switch( osversionInfo.dwMajorVersion )
    
    case WIN_MAJOR_NT4_ME_98_95:
        switch( osversionInfo.dwMinorVersion )
        
        case WIN_MINOR_2K8_VISTA_2K_NT4_95:
            if ( VER_PLATFORM_WIN32_NT == osversionInfo.dwPlatformId )
            
                OutputDebugString(TEXT("WIN_VER_NT4"));
                *winVer = WIN_VER_NT4;
            
            else
            
                OutputDebugString(TEXT("WIN_VER_95"));
                *winVer = WIN_VER_95;
            
            break;
        case WIN_MINOR_98:
            OutputDebugString(TEXT("WIN_VER_98"));
            *winVer = WIN_VER_98;
            break;
        case WIN_MINOR_ME:
            *winVer = WIN_VER_ME;
            OutputDebugString(TEXT("WIN_VER_ME"));
            break;
        default:
            break;
        
        break;
    case WIN_MAJOR_2K3R2_2K3_XP_2K:
        switch( osversionInfo.dwMinorVersion )
        
        case WIN_MINOR_2K8_VISTA_2K_NT4_95:
            *winVer = WIN_VER_2K;
            OutputDebugString(TEXT("WIN_VER_2K"));
            break;
        case WIN_MINOR_WIN7_2K8R2_XP:
            *winVer = WIN_VER_XP;
            OutputDebugString(TEXT("WIN_VER_XP"));
            break;
        case WIN_MINOR_2K3R2_2K3_XP64:
            if ( VER_NT_WORKSTATION == osversionInfo.wProductType )
            
                *winVer = WIN_VER_XP64;
                OutputDebugString(TEXT("WIN_VER_XP64"));
                break;
            
            if ( 0 != GetSystemMetrics( SM_SERVERR2 ) )
            
                *winVer = WIN_VER_2K3R2;
                OutputDebugString(TEXT("WIN_VER_2K3_R2"));
            
            else
            
                *winVer = WIN_VER_2K3;
                OutputDebugString(TEXT("WIN_VER_2K3"));
            
            break;
        default:
            break;
        
        break;
    case WIN_MAJOR_WIN7_2K8R2_2K8_VISTA:
        switch( osversionInfo.dwMinorVersion )
        
        case WIN_MINOR_2K8_VISTA_2K_NT4_95:
            if ( VER_NT_WORKSTATION == osversionInfo.wProductType )
            
                OutputDebugString(TEXT("WIN_VER_VISTA"));
                *winVer = WIN_VER_VISTA;
            
            else
            
                *winVer = WIN_VER_2K8;
                OutputDebugString(TEXT("WIN_VER_2K8"));
            
            break;
        case WIN_MINOR_WIN7_2K8R2_XP:
            if ( VER_NT_WORKSTATION == osversionInfo.wProductType )
            
                *winVer = WIN_VER_WIN7;
                OutputDebugString(TEXT("WIN_VER_WIN7"));
            
            else
            
                *winVer = WIN_VER_2K8R2;
                OutputDebugString(TEXT("WIN_VER_2K8_R2"));
            
            break;
        default:
            break;
        
        break;
    default:
        break;
    
    return TRUE;


//功能:判断当前操作系统是否比sepcVer指定的系统更新
BOOL CDisplayInfo::IsOlderSystem( WinVerDef specVer, INT* iResult )

    if ( NULL == iResult )
    
        return FALSE;
    
    WinVerDef currVer = WIN_VER_UNKNOWN;
    if ( FALSE == GetOSVersion( &currVer ) || WIN_VER_UNKNOWN == currVer )
    
        return FALSE;
    
    else
    
        *iResult = currVer - specVer;
    
    return TRUE;

(2)VC++实现Windows中双显示器(主屏、扩展屏)

Windows中鼠标右键桌面->“屏幕分辨率”时出现的“更改显示器的外观”对话框下实现了双屏操作的诸多功能,如:主屏的设置、主屏和扩展屏的分辨率、方向、屏幕合并等。实际项目中需要通过VC++代码实现这些功能,用了将近一周的事件,在网上经过几番搜索、整合及改写,终于开发出了所需功能。以下将cpp源码贴出,以弥补此方面网上资料的匮乏。完整工程见上传资源Windows下双屏各种设置的VC++实现(完整源码工程)(VS2010下开发)。
// Multi_DisplayDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "Multi_Display.h"
#include "Multi_DisplayDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx

public:
 CAboutDlg();

// 对话框数据
 enum IDD = IDD_ABOUTBOX ;

 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
 DECLARE_MESSAGE_MAP()
;

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

 CDialogEx::DoDataExchange(pDX);

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CMulti_DisplayDlg 对话框


CMulti_DisplayDlg::CMulti_DisplayDlg(CWnd* pParent /*=NULL*/)
 : CDialogEx(CMulti_DisplayDlg::IDD, pParent)

 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

void CMulti_DisplayDlg::DoDataExchange(CDataExchange* pDX)

 CDialogEx::DoDataExchange(pDX);

BEGIN_MESSAGE_MAP(CMulti_DisplayDlg, CDialogEx)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDOK, &CMulti_DisplayDlg::OnBnClickedOk)
 ON_CBN_SELCHANGE(IDC_COMBO1, &CMulti_DisplayDlg::OnCbnSelchangeCombo1)
 ON_CBN_DROPDOWN(IDC_COMBO1, &CMulti_DisplayDlg::OnCbnDropdownCombo1)
 ON_BN_CLICKED(IDC_BUTTON1, &CMulti_DisplayDlg::OnBnClickedButton1)
 ON_BN_CLICKED(IDC_BUTTON2, &CMulti_DisplayDlg::OnBnClickedButton2)
END_MESSAGE_MAP()


// CMulti_DisplayDlg 消息处理程序

BOOL CMulti_DisplayDlg::OnInitDialog()

 CDialogEx::OnInitDialog();
 
 // 将“关于...”菜单项添加到系统菜单中。

 // IDM_ABOUTBOX 必须在系统命令范围内。
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 
  BOOL bNameValid;
  CString strAboutMenu;
  bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
  ASSERT(bNameValid);
  if (!strAboutMenu.IsEmpty())
  
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  
 

 // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
 //  执行此操作
 SetIcon(m_hIcon, TRUE);   // 设置大图标
 SetIcon(m_hIcon, FALSE);  // 设置小图标

 // TODO: 在此添加额外的初始化代码
 GetAllMonitors();
 comboBox = (CComboBox*)GetDlgItem(IDC_COMBO1);
 comboBox->ResetContent();
 for (int i = 0; i < dev_list.size(); i++)  
   
  CString string1;//; = CString(i);
  string1.Format(_T("%d"), i+1);
  //ZeroMemory(&string1, sizeof(string1));
  //sprintf(temp, "%d", i+1);
  comboBox->AddString(string1);
   
 comboBox->SetCurSel(0);
 UpdateData(false);

 return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE

void CMulti_DisplayDlg::OnSysCommand(UINT nID, LPARAM lParam)

 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 
 else
 
  CDialogEx::OnSysCommand(nID, lParam);
 

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CMulti_DisplayDlg::OnPaint()

 if (IsIconic())
 
  CPaintDC dc(this); // 用于绘制的设备上下文

  SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

  // 使图标在工作区矩形中居中
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // 绘制图标
  dc.DrawIcon(x, y, m_hIcon);
 
 else
 
  CDialogEx::OnPaint();
 

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMulti_DisplayDlg::OnQueryDragIcon()

 return static_cast<HCURSOR>(m_hIcon);

void CMulti_DisplayDlg::GetAllMonitors()

 std::list<DISPLAY_DEVICE> devices;
 std::list<DEVMODE> modes;
 int devId = 0;
 bool ret = false;
 bool isPrimary = false;

 //list all DisplayDevices (Monitors)
 do
 
  DISPLAY_DEVICE displayDevice;
  ZeroMemory(&displayDevice, sizeof(DISPLAY_DEVICE));
  displayDevice.cb = sizeof(displayDevice);

  ret = EnumDisplayDevices(NULL, devId, &displayDevice, 0);
  if (ret == true)
  
   if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
   
    devices.push_back(displayDevice);
    isPrimary = ((displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) == DISPLAY_DEVICE_PRIMARY_DEVICE);
    if (isPrimary)
     PrimaryNum = devId;
   
  
  devId++;
  while (ret);
 dev_list = devices;

 std::list<DISPLAY_DEVICE>::iterator it;
 for (it = dev_list.begin(); it != dev_list.end(); it++)
 
  DEVMODE deviceMode;
  deviceMode.dmSize = sizeof(DEVMODE);
  deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS; // | DM_DISPLAYORIENTATION;

  EnumDisplaySettings(it->DeviceName, (int)ENUM_REGISTRY_SETTINGS, &deviceMode);
  modes.push_back(deviceMode);
 
 dev_mode_list = modes;

void CMulti_DisplayDlg::SwitchPrimaryScreen(int newPrimary, int oldPrimary)

 MoveNewPrimary(newPrimary, oldPrimary);
 MoveOldPrimary(newPrimary, oldPrimary);
 CommitChange();

void CMulti_DisplayDlg::MoveOldPrimary(int newPrimary, int oldPrimary)

 int index = 0;
 std::list<DISPLAY_DEVICE>::iterator it1;
 for (it1 = dev_list.begin(); it1 != dev_list.end(); it1++)
 
  if (index == oldPrimary)
   break;
  index++;
 
 index = 0;
 std::list<DEVMODE>::iterator it2;
 for (it2 = dev_mode_list.begin(); it2 != dev_mode_list.end(); it2++)
 
  if (index == newPrimary)
   break;
  index++;
 
 index = 0;
 std::list<DEVMODE>::iterator it3;
 for (it3 = dev_mode_list.begin(); it3 != dev_mode_list.end(); it3++)
 
  if (index == oldPrimary)
   break;
  index++;
 
 it3->dmPosition.x = it2->dmPelsWidth;
 it3->dmPosition.y = 0;
 DEVMODE deviceMode = *it3;
 int ret = ChangeDisplaySettingsEx(it1->DeviceName, &deviceMode, NULL, CDS_UPDATEREGISTRY | CDS_NORESET, NULL);

void CMulti_DisplayDlg::MoveNewPrimary(int newPrimary, int oldPrimary)

 int index = 0;
 std::list<DISPLAY_DEVICE>::iterator it1;
 for (it1 = dev_list.begin(); it1 != dev_list.end(); it1++)
 
  if (index == newPrimary)
   break;
  index++;
 
 index = 0;
 std::list<DEVMODE>::iterator it2;
 for (it2 = dev_mode_list.begin(); it2 != dev_mode_list.end(); it2++)
 
  if (index == newPrimary)
   break;
  index++;
 

 it2->dmPosition.x = 0;
 it2->dmPosition.y = 0;
 DEVMODE deviceMode = *it2;
 
 int ret = ChangeDisplaySettingsEx(it1->DeviceName, &deviceMode, NULL, CDS_SET_PRIMARY | CDS_UPDATEREGISTRY | CDS_NORESET, NULL);

void CMulti_DisplayDlg::CommitChange()

 ChangeDisplaySettingsEx (NULL, NULL, NULL, 0, NULL);

int CMulti_DisplayDlg::GetPrimaryScreen()

 return PrimaryNum;

int CMulti_DisplayDlg::SetPrimaryScreen(int num)

 int oldprimary = GetPrimaryScreen();
 int newPrimary = num;

 if ((num >= dev_list.size()) || (num < 0))
  return -1;

 if (oldprimary == newPrimary)
  return 0;

 SwitchPrimaryScreen(newPrimary, oldprimary);
 PrimaryNum = newPrimary;

 return oldprimary;

int CMulti_DisplayDlg::SetCloneView(int mode)

 /*UINT32 PathArraySize = 0;   
 UINT32 ModeArraySize = 0;   
 DISPLAYCONFIG_PATH_INFO* PathArray;   
 DISPLAYCONFIG_MODE_INFO* ModeArray;   
 DISPLAYCONFIG_TOPOLOGY_ID CurrentTopology;  

 //Determine the size of the path array that is required to hold all valid paths
 GetDisplayConfigBufferSizes(QDC_ALL_PATHS, &PathArraySize, &ModeArraySize); //retrieve the sizes of the DISPLAYCONFIG_PATH_INFO and DISPLAYCONFIG_MODE_INFO buffers that are required

 //Allocate memory for path and mode information arrays
 PathArray = (DISPLAYCONFIG_PATH_INFO*)malloc(PathArraySize * sizeof(DISPLAYCONFIG_PATH_INFO));  
 memset(PathArray, 0, PathArraySize * sizeof(DISPLAYCONFIG_PATH_INFO));  

 ModeArray = (DISPLAYCONFIG_MODE_INFO*)malloc(ModeArraySize * sizeof(DISPLAYCONFIG_MODE_INFO));  
 ZeroMemory(ModeArray, ModeArraySize * sizeof(DISPLAYCONFIG_MODE_INFO));   
 
 //Request all of the path information
 LONG ret = QueryDisplayConfig(QDC_DATABASE_CURRENT,&PathArraySize, PathArray, &ModeArraySize, ModeArray, &CurrentTopology); //obtain the path and mode information for all posible paths
 // Above CurrentTopology variable will aquire the current display setting (ie Extend, Duplicate etc)  

 free(PathArray);   
 free(ModeArray);   
 */
 //Set the new topology.
 SetDisplayConfig(0,NULL,0,NULL, mode | SDC_APPLY); //change to the clone topology

 return 0;

int CMulti_DisplayDlg::ChangeScreenOrientation(int num, int rotation)

 int index = 0;
 std::list<DEVMODE>::iterator it;

 for (it = dev_mode_list.begin(); it != dev_mode_list.end(); it++)
 
  if (index == num)
   break;
  index++;
 
 DWORD dwTemp = it->dmPelsHeight;
 switch(rotation)
 
  case 0:
   if(it->dmDisplayOrientation == DMDO_DEFAULT)
    it->dmDisplayOrientation = DMDO_90;
   else if(it->dmDisplayOrientation == DMDO_90)
    it->dmDisplayOrientation = DMDO_DEFAULT;
   it->dmPelsHeight= it->dmPelsWidth;
   it->dmPelsWidth = dwTemp;
   break;
  case 1:
   if(it->dmDisplayOrientation == DMDO_DEFAULT)
    it->dmDisplayOrientation = DMDO_90;
   else if(it->dmDisplayOrientation == DMDO_90)
    it->dmDisplayOrientation = DMDO_DEFAULT;
   it->dmPelsHeight= it->dmPelsWidth;
   it->dmPelsWidth = dwTemp;
   break;
 

 DEVMODE deviceMode;
 ZeroMemory(&deviceMode, sizeof(deviceMode));
 deviceMode.dmSize = sizeof(deviceMode);
 deviceMode = *it;

 index = 0;
 std::list<DISPLAY_DEVICE>::iterator it1;
 for (it1 = dev_list.begin(); it1 != dev_list.end(); it1++)
 
  if (index == num)
   break;
  index++;
 

 //long lRet = ChangeDisplaySettingsEx(it1->DeviceName, &deviceMode, NULL, CDS_UPDATEREGISTRY | CDS_NORESET, NULL);
 //CommitChange();
 long lRet = ChangeDisplaySettingsEx(it1->DeviceName, &deviceMode, NULL, CDS_UPDATEREGISTRY, NULL);

 return lRet;

void CMulti_DisplayDlg::OnBnClickedOk()

 // TODO: 在此添加控件通知处理程序代码
 SetPrimaryScreen(selIndex);
 
 //CDialogEx::OnOK();

int count1 = 0;
void CMulti_DisplayDlg::OnBnClickedButton1()

 // TODO: 在此添加控件通知处理程序代码
 long lRet;

 selIndex = comboBox->GetCurSel();//取得选中的索引
 if(selIndex < 0 )
  return;
 count1++;
 if(count1 %2)
 
  lRet = ChangeScreenOrientation(selIndex, 1);
 
 else
 
  lRet = ChangeScreenOrientation(selIndex, 0);
 

int count = 0;
void CMulti_DisplayDlg::OnBnClickedButton2()

 // TODO: 在此添加控件通知处理程序代码
 count++;
 if(count %2)
 
  SetCloneView(SDC_TOPOLOGY_CLONE); 
  GetDlgItem(IDC_BUTTON2)->SetWindowTextW(_T("恢复"));
 
 else
 
  SetCloneView(SDC_TOPOLOGY_EXTEND);
  GetDlgItem(IDC_BUTTON2)->SetWindowTextW(_T("屏幕复制"));
 

void CMulti_DisplayDlg::OnCbnSelchangeCombo1()

 // TODO: 在此添加控件通知处理程序代码
 //取得选中的值
 CString selStr;
 selIndex = comboBox->GetCurSel();//取得选中的索引
 //comboBox->GetLBText(nIndex,selStr);

 //MessageBox(selStr);

void CMulti_DisplayDlg::OnCbnDropdownCombo1()

 // TODO: 在此添加控件通知处理程序代码
 GetAllMonitors();
 comboBox = (CComboBox*)GetDlgItem(IDC_COMBO1);
 comboBox->ResetContent();
 for (int i = 0; i < dev_list.size(); i++)  
   
  CString string1;//; = CString(i);
  string1.Format(_T("%d"), i+1);
  //ZeroMemory(&string1, sizeof(string1));
  //sprintf(temp, "%d", i+1);
  comboBox->AddString(string1);
  

 UpdateData(false);

附上几个有用的链接:

https://msdn.microsoft.com/en-us/library/ff569533(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/dd183413(VS.85).aspx

以上是关于关于win7和xp的屏设置类及其Windows中双显示器的主要内容,如果未能解决你的问题,请参考以下文章

关于win7和xp的屏设置类及其Windows中双显示器

关于win7和xp的屏设置类及其Windows中双显示器

C# winform 在win7 下界面出错

WINDOWS XP 如何在VMware虚拟机上设置网络连接?

我安装win7 xp mode出现一个vhd文件 Windows XP Mode base.vhd打不开怎么办

问: win10页面与xp、win7的不一样,打印范围或纸张比例大小不一