我很确定 GetSystemMetrics function(SystemParameters 类在内部使用适当的参数调用)为您的系统返回正确的值,它只是返回正确的值Aero 主题是否被禁用的情况。启用 Aero 后,您会获得更强大的边框和更高的窗口标题,这些都是多汁的图形优点。
如果您想获得这些窗口元素的正确大小,而不管用户当前的主题是什么(请记住,您可以使用 Classic 主题、Aero Basic 主题或完整 Aero 主题运行 Windows Vista 及更高版本,所有将有不同大小的 UI 元素),您需要使用 Vista 及更高版本中可用的不同方法。
您需要向窗口发送WM_GETTITLEBARINFOEX message 以请求扩展标题栏信息。 wParam 未使用,应为零。 lParam 包含一个指向TITLEBARINFOEX structure 的指针,它将接收所有信息。调用者负责为此结构分配内存并设置其cbSize 成员。
要从 .NET 应用程序执行所有这些操作,您显然需要执行一些 P/Invoke。首先定义您需要的常量以及TITLEBARINFOEX 结构:
internal const int WM_GETTITLEBARINFOEX = 0x033F;
internal const int CCHILDREN_TITLEBAR = 5;
[StructLayout(LayoutKind.Sequential)]
internal struct TITLEBARINFOEX
{
public int cbSize;
public Rectangle rcTitleBar;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = CCHILDREN_TITLEBAR + 1)]
public int[] rgstate;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = CCHILDREN_TITLEBAR + 1)]
public Rectangle[] rgrect;
}
然后相应地定义SendMessage函数:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr SendMessage(
IntPtr hWnd,
int uMsg,
IntPtr wParam,
ref TITLEBARINFOEX lParam);
最后,您可以使用类似以下代码的方式调用所有这些混乱:
internal static TITLEBARINFOEX GetTitleBarInfoEx(IntPtr hWnd)
{
// Create and initialize the structure
TITLEBARINFOEX tbi = new TITLEBARINFOEX();
tbi.cbSize = Marshal.SizeOf(typeof(TITLEBARINFOEX));
// Send the WM_GETTITLEBARINFOEX message
SendMessage(hWnd, WM_GETTITLEBARINFOEX, IntPtr.Zero, ref tbi);
// Return the filled-in structure
return tbi;
}
编辑:现在在我运行 Windows 7 的笔记本上进行了测试和工作。