关于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中双显示器的主要内容,如果未能解决你的问题,请参考以下文章
WINDOWS XP 如何在VMware虚拟机上设置网络连接?