Что я могу сделать с развернутыми, стилизованными окнами, которые показывают свои границы на соседних мониторах?

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

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

 mghie08 июн. 2012 г., 05:53
Обязательный "Старое новое" ссылка: & quot; Почему у развернутого окна неправильный прямоугольник окна? & quot; (blogs.msdn.com/b/oldnewthing/archive/2012/03/26/10287385.aspx) описывает в своем последнем разделе, почему в последних версиях Windows нет границ для развернутых приложений, видимых на других мониторах. Код, выполняющий собственное рисование области ЧПУ, очевидно, не получает такой специальной обработки.
 Warren P07 июн. 2012 г., 21:43
КК веб-адрес:qc.embarcadero.com/wc/qcmain.aspx
 David Heffernan07 июн. 2012 г., 21:38
Еще больше ошибок стиля VCL. Пожалуйста, проверьте это.
 DaveS_Lifeway07 июн. 2012 г., 23:41
Визуально поведение стилевых приложений на одном мониторе соответствует нестандартным приложениям, поэтому проблем нет.
 RRUZ07 июн. 2012 г., 22:52
Можете ли вы воспроизвести это поведение на одном мониторе? Я спрашиваю, потому что в моем текущем местоположении у меня нет другого монитора, чтобы проверить эту проблему.

Ответы на вопрос(2)

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

После того, как я немного поигрался с этим, я считаю, что это совсем не ошибка в стиле 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;
 02 авг. 2012 г., 11:59
@whos - Конечно, было бы намного лучше (также избавился бы от внутренних кадров). Я думал, что для этого нам нужно сотрудничество с VCL, но, возможно, нет.
 02 авг. 2012 г., 11:52
Раймонд специально говорит «визуальный трюк» так что я полагаю, что мы не изменяем размеры прямоугольника окна, а просто ограничиваем нависающие границы?

Ваш ответ на вопрос