MDI и Windows Vista
13 Август 2009
В Windows Vista во многих MDI приложениях часто наблюдается баг (субъективно – в SP1/SP2 значительно реже) при максимизации дочернего окна – оно занимает не всю отведенную ему область. Справа остается небольшое пространство.
Ответ был найден на MSDN форуме, но применительно к MFC. Но в Delphi эта проблема также встречается и решается аналогично. Вот исходный код, который поможет исправить проблему. Его нужно добавить к дочернему окну (FormStyle = fsMDIChild).
type TMDIChild = class(TForm) private procedure WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo); message WM_GETMINMAXINFO; ... end; ... (* Оригинальный комментарий к решению: -------------------------------------------------------------------------------- Заплатка на MFC версий ниже 8.0 В MFC версиях 8.0 на Vista есть проблема, когда окно дочернего MDI фрейма максимизируется при максимизированном родительском MDI фрейме. В этом случаи максимальный размер окна ограничивается данными структуры MINMAXINFO, которые были вычесленны ранее системой при заданных стилях окна. Однако сам MFC в процессе ресайза этого окна любит менять ему стили на ходу в результате система путается и MINMAXINFO содержит неправильные данные. Это было не критично на XP и более старых системах, т.к. ошибка была в 1 пиксель, теперь же на Vista, когда бордюр имеет занчительную ширину (4 пикселя), эта ошибка стала заметна (как раз на эту ширину - 4 пикселя). Чтобы исправить ошибу я вручную правлю структуру MINMAXINFO под максимально возможный размер окна. -------------------------------------------------------------------------------- Smike: Похоже этот баг перенесли и в Delphi :) *) procedure TMDIChild.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo); begin if WindowState <> wsMaximized then inherited else with Message.MinMaxInfo^ do begin if ptMaxTrackSize.X < ptMaxSize.X then ptMaxTrackSize.X := ptMaxSize.X; if ptMaxTrackSize.Y < ptMaxSize.Y then ptMaxTrackSize.Y := ptMaxSize.Y; end; { // Если не жалко пару десятков килобайт // в исполняемом файле - можно использовать функции модуля Math if WindowState <> wsMaximized then inherited else with Message.MinMaxInfo^ do begin ptMaxTrackSize.X := Max(ptMaxTrackSize.X, ptMaxSize.X); ptMaxTrackSize.Y := Max(ptMaxTrackSize.Y, ptMaxSize.Y); end;} end;