Поработав над этим некоторое время, я пришел к выводу, что это вообще не ошибка vcl-стилей. Это действительно связано с поведением в статье упомянутый в комментарии к вопросу mghie.
Конкретное поведение заключается в том, что размер развернутого окна больше, чем рабочая область монитора, на котором развернуто окно. Предположительно, оконный менеджер скрывает выступающие границы. По-видимому, это не совсем так с индивидуальными рамками. Обратите внимание, что собственный пример настраиваемой оконной рамки в MSDN, похоже, страдает той же проблемой (см. сообщение под названием «Ошибка, когда окно развернуто» в материалах сообщества). Приложение 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;
person
Sertac Akyuz
schedule
02.08.2012
WorkareaRect
активного монитора, но это создало другие проблемы, похуже исходной проблемы с границами. Если вы найдете обходной путь, опубликуйте его. Спасибо! - person James L.   schedule 29.06.2012