Вопрос по vcl-styles, delphi, delphi-xe2, maximize-window – Что я могу сделать с развернутыми, стилизованными окнами, которые показывают свои границы на соседних мониторах?

22

В системе с несколькими мониторами «пустой» Приложение VCL максимизирует нормально, но то же приложение с включенными стилями (и один выбран по умолчанию) максимизирует неправильно. То, что я вижу, - это правый край окна, простирающийся на 2-й монитор (мой основной находится слева). Когда я начал сравнивать с другими приложениями Windows, я заметил, что в Windows 7 (по крайней мере), развернутые окна даже не имеют сторонних границ слева, справа или снизу. И действительно, стандартное приложение VCL (не в стиле) ведет себя так же, без границ, не связанных с клиентом.

Как это исправить? Я заметил, что TFormStyleHook имеет обработчик для WMNCCalcSize, который я пока не анализировал, но заставляет задуматься, может ли VCL неправильно обрабатывать это сообщение для развернутого окна.

Визуально поведение стилевых приложений на одном мониторе соответствует нестандартным приложениям, поэтому проблем нет. DaveS_Lifeway
Можете ли вы воспроизвести это поведение на одном мониторе? Я спрашиваю, потому что в моем текущем местоположении у меня нет другого монитора, чтобы проверить эту проблему. RRUZ
КК веб-адрес:qc.embarcadero.com/wc/qcmain.aspx Warren P
Еще больше ошибок стиля VCL. Пожалуйста, проверьте это. David Heffernan
Обязательный "Старое новое" ссылка: & quot; Почему у развернутого окна неправильный прямоугольник окна? & quot; (blogs.msdn.com/b/oldnewthing/archive/2012/03/26/10287385.aspx) описывает в своем последнем разделе, почему в последних версиях Windows нет границ для развернутых приложений, видимых на других мониторах. Код, выполняющий собственное рисование области ЧПУ, очевидно, не получает такой специальной обработки. mghie

Ваш Ответ

2   ответа
1

который я нашел, - обработать событие WM_SIZE и изменить область окна, чтобы обрезать лишнюю границу.

5

После того, как я немного поигрался с этим, я считаю, что это совсем не ошибка в стиле vcl. Это действительно связано с поведением встатья упоминается вкомментарий на вопросmghie.

Особое поведение заключается в том, что размер развернутого окна больше, чем рабочая область монитора, на которой развернуто окно. Предположительно, оконный менеджер скрывает границы выступа. По-видимому, это не совсем так с настроенными кадрами. Обратите внимание, что MSDN принадлежитпример пользовательской оконной рамы похоже, страдает от той же проблемы (см. пост под названием"Bug when window is Maximized " в контенте сообщества). Приложение VCL отличается от примера MSDN тем, что оно не основано на DWM, но я все еще думаю, что это та же проблема.

Выступающие границы имеют размер границы размера системы (SM_C [X | Y] SIZEFRAME), но это не имеет отношения к обходному пути ниже, так как он игнорирует предлагаемый размер / положение ОС и использует рабочую область.

К сожалению, я не думаю, что этот обходной путь применим вообще. С одной стороны, упомянутое поведение не задокументировано, с другой - обходной путь не идеален; там еще нечетный пиксель. Если вы привязываете окно именно к рабочей области, диспетчер окон решает сместить окно туда, где, по его мнению, должно быть расположено окно (со скрытыми рамками). (VCL, вероятно, можно было бы изменить, чтобы сделать то, что делает оконный менеджер, и принять во внимание свисание и не рисовать их или что-то подобное, но это было бы больше работы, и это все еще будет обходить недокументированное поведение ...)

Тем не мение;

type
  TForm1 = class(TForm)
    ..
  protected
    // overriding styles is not necessary since TFormStyleHook.WMGetMinMaxInfo
    // first calls the default window procedure 
    procedure WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo);
      message WM_GETMINMAXINFO;

..

procedure TForm1.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo);
var
  R: TRect;
begin
  // always arrives with MinMaxInfo.ptMaxPosition = (-SM_CXFRAME, -SM_CYFRAME)
  // and MinMaxInfo.ptMaxSize = (PrimaryMonitor.Width (?) + 2 * SM_CXFRAME, ... )
  inherited;

  // should test for OS, styles etc. before running the below 
  R := Monitor.WorkareaRect;
  InflateRect(R, -1, -1);             // odd pixel
  OffsetRect(R, -Monitor.Left, -Monitor.Top);
  Message.MinMaxInfo.ptMaxPosition := R.TopLeft;
  Message.MinMaxInfo.ptMaxSize := Point(R.Width, R.Height);
end;
Раймонд специально говорит «визуальный трюк» так что я полагаю, что мы не изменяем размеры прямоугольника окна, а просто ограничиваем нависающие границы?
@whos - Конечно, было бы намного лучше (также избавился бы от внутренних кадров). Я думал, что для этого нам нужно сотрудничество с VCL, но, возможно, нет.

Похожие вопросы