当你在运行一个程序时,总是希望可见的范围越大越好,不要有其他不需要的信息显示在屏幕上,这就涉及到了全屏。
全屏总是一个激动人心的话题。在全屏状态下,我们可以对独占计算机系统资源,提高程序的运行效率。和窗口模式有区别的是,在设置全屏时还必须注意一些事项。
首先,改变显示模式的函数是ChangeDisplaySettings,它是一个标准的Win32函数,其原型如下
LONG ChangeDisplaySettings(
LPDEVMODE lpDevMode, // graphics mode
DWORD dwflags // graphics mode options
);
lpDevMode指向一个描述转变图表的DEVMODE的指针。如果lpDevMode 为空,则程序使用当前注册表中保存的值作为显示模式设置的值。将lpDevMode设置成0,同时将dwFlags设置成0是将显示模式设置成缺省模式的最简单的办法。DEVMODE结构的具体内容如下
typedef struct _devicemode {
BCHAR dmDeviceName[CCHDEVICENAME];
WORD dmSpecVersion;
WORD dmDriverVersion;
WORD dmSize;
WORD dmDriverExtra;
DWORD dmFields;
union {
struct {
short dmOrientation;
short dmPaperSize;
short dmPaperLength;
short dmPaperWidth;
short dmScale;
short dmCopies;
short dmDefaultSource;
short dmPrintQuality;
};
POINTL dmPosition;
DWORD dmDisplayOrientation;
DWORD dmDisplayFixedOutput;
};
short dmColor;
short dmDuplex;
short dmYResolution;
short dmTTOption;
short dmCollate;
BYTE dmFormName[CCHFORMNAME];
WORD dmLogPixels;
DWORD dmBitsPerPel;
DWORD dmPelsWidth;
DWORD dmPelsHeight;
union {
DWORD dmDisplayFlags;
DWORD dmNup;
}
DWORD dmDisplayFrequency;
#if(WINVER >= 0x0400)
DWORD dmICMMethod;
DWORD dmICMIntent;
DWORD dmMediaType;
DWORD dmDitherType;
DWORD dmReserved1;
DWORD dmReserved2;
#if (WINVER >= 0x0500) || (_WIN32_WINNT >= 0x0400)
DWORD dmPanningWidth;
DWORD dmPanningHeight;
#endif
#endif /* WINVER >= 0x0400 */
} DEVMODE;
DEVMODE的dmSize参数必须根据DEVMODE结构的大小设置,dmDriveExtra参数必须初始化来显示DEVMODE随后的驱动数据的字节数。另外还可以选用表11-1中的参数。
表11-1
结构成员 | 含义 |
dmBitsPerPel | 个像素的位数 |
dmPelsWidth | 像素宽度 |
dmPelsHeight | 像度高度 |
dmDisplayFlags | 显示模式标志 |
dmDisplayFrequency | 显示模式刷新频率 |
dmPosition | Windows 98/Me, Windows 2000/XP: 设备在多个显示器配置中的位置 |
除了设置好DEVMOD结构中诸多元素的值之外,还必须要正确地设置dmFields元素中的标志。这些标志表明了DEVMODE结构中哪个元素在改变显示设置时使用了。如果在dmFields中没有设置正确的位,那么显示设置无效。
表11-2
取值 | 含义 |
DM_BITSPERPEL | 使用dmBitsPerPel的值 |
DM_PELSWIDTH | 使用dmPelsWidth的值 |
DM_PELSHEIGHT | 使用dmPelsHeight的值 |
DM_DISPLAYFLAGS | 使用dmDisplayFlags的值 |
DM_DISPLAYFREQUENCY | 使用dmDisplayFrequency的值 |
DM_POSITION | Windows 98/Me, Windows 2000/XP: 使用fdmPosition的值 |
dwflags表示显示模式如何改变,它的取值如表11-3所示。
表11-3
取值 | 含义 |
0 | 表明当前显示模式要动态改变 |
CDS_FULLSCREEN | 本质上讲该显示模式是暂时的。在WindowsNT/2000/XP中,如果更换到另一个桌面或者,则显示模式的改变仍然有效。 |
CDS_GLOBAL | 该设置保存在全局设置区域内,因此它们会影响所有的用户。该标志仅在与CDS_UPDATEREGISTRY标志一起使用时才有效。 |
CDS_NORESET | 显示模式设置将保存在注册表中,但不起作用,该标志只有与CDS_UPDATEREGISTRY标志一起使用时才有效。 |
CDS_RESET | 改变显示模式设置,不管请求的设置与当前设置是否一样。 |
CDS_SET_PRIMARY | 该设备成为首要设备。 |
CDS_TEST | 系统检测是否要设置被请求的显示模式 |
CDS_UPDATEREGISTRY | 表明当前显示模式会动态地变化,并且会更新注册表,该模式信息存贮在USER档案中。 |
在Windows NT/2000/XP中,如果指定了CDS_UPDATEREGISTRY并且在注册表中不能保存该信息,则图形模式不会改变,并且返回DISP_CHANGE_NOTUPDATERD。ChangeDisplaySettings函数的返回值如表11-4所示。
表11-4 ChangeDisplaySettings函数返回值
返回值 | 含义 |
DISP_CHANGE_SUCCESSFUL | 设置改变成功。 |
DISP_CHANGE_BADDUALVIEW | 在Windows XP中设置不成功,是因为系统是双显示配置。 |
DISP_CHANGE_BADFLAGS | 设置的显示模式标志无效。 |
DISP_CHANGE_BADMODE | 系统不支持新的显示模式。 |
DISP_CHANGE_BADPARAM | 设置的参数无效,可以一个显示模式标志或者多个标志的组合。 |
DISP_CHANGE_FAILED | 更改显示模式失败。 |
DISP_CHANGE_NOTUPDATED | 在Windows NT/2000/XP中不能够写入注册表。 |
DISP_CHANGE_RESTART | 为使新的显示模式生效,必须重新启动计算机。 |
当显示模式被动态地改变时,WM_DISPLAYCHANGE消息传递给所有正在运行的应用,对应消息的wParam表示每像素点的新位数,LOWORD(lParam)表示新像素宽度,HIWORD(lParam)表示新像素高度。
为了保证传递给ChangeDisplaySetting的DEVMODE结构是有效的,并且仅包含显示驱动支持的值,可以使用由EnumDisplaySettings函数返回的DEVMODE。EnumDisplaySettings也是一个标准的Win32函数,它可以得到显示设备的一个显示模式信息,多次调用后就可以得到所有的显示模式信息,其原型如下
BOOL EnumDisplaySettings(
LPCTSTR lpszDeviceName, // display device
DWORD iModeNum, // graphics mode
LPDEVMODE lpDevMode // graphics mode settings
);
lpszDeviceName指向一个以null的结尾的字符串,该字符串指定了需要得到显示模式信息的显示设备。该参数可以为NULL,也可以是一个由returned from EnumDisplayDevices返回的DISPLAY_DEVICE.DeviceName。当参数为NULL时,表示应用程序正运行在计算机的当前显示设备上。在Windows 9x中,lpszDeviceName必须为NULL。iModeNum表示要检索的信息类型,该值可以是一个显示模式索引,也可以是表11-5中的值。
表11-5 iModeNum取值
iModeNum取值 | 含义 |
ENUM_CURRENT_SETTINGS | 获取当前显示设备的设置 |
ENUM_REGISTRY_SETTINGS | 获取当前设备保存在注册表中的设置 |
显示模式索引值从零开始,要得到一个显示设备的所有显示模式信息,可以多次调用EnumDisplaySettings函数。第一次调用令iModeNum为0,然后每次调用将iModeNum加1,直到函数返回值为0为止。返回非0值均表明调用成功,也就是说该显示模式存在。
iModeNum为0调用EnumDisplaySettings时,操作系统会初始化显示设备,并将信息保存在缓存中。当iModeNum为非0值调用EnumDisplaySettings时,函数返回的信息是最近一次使用iModeNum置为零调用该函数时存储的信息。
lpDevMode是一个DEVMODE结构指针,该结构存储指定图形模式的信息。在调用EnumDisplaySettings之前,应该将dmSize设置成sizeof(DEVMODE),将dmDriveExtra设置成为接收专用驱动数据可用的附加空间的大小。
EnumDisplaySettings函数设置如下五个DEVMODE成员的值
dmBitsPerpe
dmPelsWidth
dmPelsHeight
dmDisplayFlags
dmDisplayFrequency
如果iModeNum大于显示设备最后的图形模式索引,那么函数调用就会失败。