SystemParametersInfo ( SPI_GETNONCLIENTMETRICS... 在VC 2008 里不能正常工作

本文介绍了解决SystemParametersInfo在VC2008中返回0的问题,通过调整NONCLIENTMETRICS结构体大小确保跨Windows版本兼容性。

NONCLIENTMETRICS ncms = {0} ;

ncms.cbSize = sizeof(NONCLIENTMETRICS);
int s = sizeof(NONCLIENTMETRICS);

BOOL b = SystemParametersInfo (SPI_GETNONCLIENTMETRICS, (int)&s, &ncms, 0);

DWORD dw = GetLastError();

上面这段代码在VC 6.0 中工作正常,但是在VC 2008 里 SystemParametersInfo 返回 0,而 GetLastError 返回的却是 0



简单订正如下:
ncms.cbSize = sizeof(NONCLIENTMETRICS) - sizeof(ncms.iPaddedBorderWidth);

实际是由于从 Vista 和 Windows Server 2008 开始 NONCLIENTMETRICS 在最后增加了iPaddedBorderWidth字段,如果你的程序打算同时支持 vista 或 XP ,Windows 2000, Windows Server 2003,那么应该先调用 GetVersionEx 检测Windows版本,然后决定是否需要减去 sizeof (ncms.iPaddedBorderWidth) ;


            


<think>我们被要求使用SystemParametersInfo函数来获取屏幕工作区域的尺寸。工作区域是指屏幕中不包括任务栏等系统工具栏的区域。 函数原型(WinAPI): BOOL SystemParametersInfoW( UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni ); 对于SPI_GETWORKAREA,uiAction参数应设置为SPI_GETWORKAREA(即0x0030),pvParam应指向一个RECT结构,该结构将接收工作区域的坐标(左上角和右下角)。 注意:uiParam未使用,应设为0;fWinIni参数在此情况下通常设为0(因为不需要更新用户配置文件)。 步骤: 1. 定义一个RECT结构体变量来接收工作区域。 2. 调用SystemParametersInfo函数,指定uiAction为SPI_GETWORKAREA,并将RECT结构体的地址作为pvParam传入。 3. 检查函数返回值,如果成功,则RECT结构体中就包含了工作区域的坐标。 示例代码(C++): #include <Windows.h> // 获取工作区域 RECT workArea; if (SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0)) { // 成功获取,workArea的left, top, right, bottom即为工作区域的坐标 int width = workArea.right - workArea.left; // 工作区域宽度 int height = workArea.bottom - workArea.top; // 工作区域高度 // 可以输出或使用这些值 } else { // 处理错误 DWORD error = GetLastError(); // 错误处理代码 } 注意:工作区域的坐标是相对于屏幕左上角的。例如,如果任务栏在屏幕底部,那么工作区域的bottom就是屏幕高度减去任务栏高度。 另外,我们也可以使用GetMonitorInfo函数来获取特定显示器的工作区域,但这用户要求的是使用SystemParametersInfo。 引用说明:根据引用[1]中提到了获取屏幕分辨率的方法,其中也提到了SystemParametersInfo,但这我们用于获取工作区域。引用[2]中则展示了使用GetSystemMetrics获取屏幕尺寸并调整控件大小的示例,但我们的需求是工作区域,所以使用SPI_GETWORKAREA更直接。 相关问题: 1. 如何获取多显示器环境下每个显示器的工作区域? 2. 工作区域和屏幕分辨率有什么区别? 3. 如何动态响应工作区域的变化(例如当用户调整任务栏位置时)?</think>### 获取屏幕工作区域尺寸的方法 在 Windows 系统中,`SystemParametersInfo` 函数配合 `SPI_GETWORKAREA` 参数可用于获取屏幕工作区域尺寸。工作区域指屏幕中不包括任务栏、停靠工具栏等系统界面元素的可用区域。 #### C++ 示例代码 ```cpp #include <Windows.h> void GetWorkAreaSize() { RECT workArea; // 获取工作区域尺寸 if (SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0)) { int width = workArea.right - workArea.left; // 工作区域宽度 int height = workArea.bottom - workArea.top; // 工作区域高度 // 输出结果(示例) printf("工作区域尺寸: %dx%d\n", width, height); printf("坐标范围: L:%d T:%d R:%d B:%d", workArea.left, workArea.top, workArea.right, workArea.bottom); } else { printf("获取失败! 错误码: %d", GetLastError()); } } ``` #### 关键说明: 1. **参数解析** - `SPI_GETWORKAREA`:指定获取工作区域的操作类型(值为 `0x0030`) - `workArea`:接收工作区域坐标的 `RECT` 结构体 - 返回值:成功返回非零值,失败返回0(需配合 `GetLastError()` 诊断) 2. **RECT 结构体** ```cpp typedef struct tagRECT { LONG left; // 左上角X坐标 LONG top; // 左上角Y坐标 LONG right; // 右下角X坐标 LONG bottom; // 右下角Y坐标 } RECT; ``` 实际尺寸计算: - 宽度 = `right - left` - 高度 = `bottom - top` 3. **与屏幕分辨率的区别** - 屏幕分辨率:包含任务栏的全屏尺寸(可用 `GetSystemMetrics(SM_CXSCREEN)` 获取) - 工作区域:排除系统UI的可用区域(通常小于屏幕分辨率) #### 应用场景 1. 窗口最大化时自动适应可用区域 2. 多显示器环境下精确定位窗口[^1] 3. 响应式界面布局调整(如横竖屏切换)[^2] --- ### 相关问题 1. 如何动态响应工作区域变化(例如任务栏位置改变)? 2. 在多显示器系统中如何获取特定显示器的工作区域? 3. `SystemParametersInfo` 还能获取哪些系统参数信息? 4. 工作区域尺寸与窗口最大化有何关系? 5. 如何区分工作区域和虚拟屏幕(Virtual Screen)的概念? [^1]: 引用自计算机硬件信息获取方法文档 [^2]: 引用自模式尺寸功能实现示例
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值