Я почти уверен, что функция GetSystemMetrics
(которую класс SystemParameters
вызывает внутри с соответствующими аргументами) - это , возвращающая правильные значения для вашей системы, этопросто возвращая правильные значения в случае, если тема Aero отключена.Включив Aero, вы получите более широкие границы и более высокие заголовки окон - все это сочные графические качества.
Если вы хотите получить правильный размер этих элементов окна, независимо от текущей темы пользователя (помните,Вы можете запустить Windows Vista и более поздние версии с классической темой, темой Aero Basic или полной темой Aero, каждая из которых будет иметь элементы пользовательского интерфейса разного размера), вам нужно использовать другой метод, доступный в Vista и более поздних версиях.
Вам необходимо отправить в окно WM_GETTITLEBARINFOEX
сообщение , чтобы запросить расширенную информацию в строке заголовка.wParam
не используется и должен быть равен нулю.lParam
содержит указатель на TITLEBARINFOEX
структуру , которая получит всю информацию.Вызывающая сторона отвечает за выделение памяти для этой структуры и установку ее члена 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.