Главная > Delphi, Советы, Статьи > MDI и Windows Vista

MDI и Windows Vista

В 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;

Delphi, Советы, Статьи , ,

  1. Пока что нет комментариев.
  1. Пока что нет уведомлений.