procedure TScrollingWinControl.WMSize(var Message: TWMSize);
var
NewState: TWindowState;
////////////////////////////////////////////////////////////////////////////////
//
// Дата изменений: {V}
// 26/11/2004 {V}
// Причина изменений: {V}
// {V}
// ***************************** ОКРУЖЕНИЕ ********************************* {V}
// Есть форма, на которой находятся два компонента, один с Align = alNone, {V}
// другой с Align = alClient. {V}
// {V}
// ***************************** ПРОБЛЕМА ********************************** {V}
// При восстановлении окна у компонента, у которого Align = alClient не {V}
// рисовались полосы прокрутки, в случае когда на форме в правом нижнем углу {V}
// находился компонент с Align = alNone. {V}
// {V}
// *************************** ЧТО ПРОСХОДИЛО ****************************** {V}
// 1. После восстановления окна компонент с Align = alNone уходил за пределы {V}
// клиентской области формы, у формы появлялись полосы прокрутки; {V}
// 2. TControl.AlignControls вызываемая по WM_SIZE, перед размещением {V}
// компонентов, вычисляет клиентскую область используя {V}
// TControl.AdjustClientRect (virtual), которая перекрыта у {V}
// TScrollingWinControl и учитывает скроллеры окна: {V}
//
// Rect := Bounds(-HorzScrollBar.Position, -VertScrollBar.Position,
// Max(HorzScrollBar.Range, ClientWidth), Max(ClientHeight,
// VertScrollBar.Range));
// inherited AdjustClientRect(Rect);
//
// 3. Учитывая, что до восстановления окна компонент с Align = alNone {V}
// находился в правом, нижнем углу получается, что после вычисления {V}
// клиентская область до восстановления и после восстановления осталась {V}
// такой же и для компонента с Align = alClient размер окна не {V}
// изменился (AdjustClientRect до и после одинаковая); {V}
// 4. Далее происходит размещение компонента Align = alNone не на основе {V}
// AdjustClientRect, а на основе клиентской области windows ClientRect. {V}
// Его перемещают, в соответствии с его Anchors, в пределы клиентской {V}
// области формы и скроллеры исчезают; {V}
// 5. AdjustClientRect изменилась, но компоненты которые уже разместили об {V}
// этом не узнали; {V}
// {V}
// ****************************** РЕЗЮМЕ *********************************** {V}
// Поэтому реакция на изменение размеров происходит в цикле, и если на {V}
// выходе размер вычисляемой клиентской области изменился то нужно {V}
// переразместить компоненты; {V}
//
////////////////////////////////////////////////////////////////////////////////
lBeforeClientRect : TRect; {V}
lAfterClientRect : TRect; {V}
lCycleCount : Integer;
////////////////////////////////////////////////////////////////////////////////
begin
////////////////////////////////////////////////////////////////////////////////
lCycleCount := 0;
repeat {V}
Inc(lCycleCount);
lBeforeClientRect := GetClientRect; {V}
AdjustClientRect(lBeforeClientRect); {V}
////////////////////////////////////////////////////////////////////////////////
Inc(FAutoRangeCount);
try
inherited;
NewState := wsNormal;
case Message.SizeType of
SIZENORMAL: NewState := wsNormal;
SIZEICONIC: NewState := wsMinimized;
SIZEFULLSCREEN: NewState := wsMaximized;
end;
Resizing(NewState);
finally
Dec(FAutoRangeCount);
end;
FUpdatingScrollBars := True;
try
CalcAutoRange;
finally
FUpdatingScrollBars := False;
end;
if FHorzScrollBar.Visible or FVertScrollBar.Visible then
UpdateScrollBars;
////////////////////////////////////////////////////////////////////////////////
lAfterClientRect := GetClientRect; {V}
AdjustClientRect(lAfterClientRect); {V}
until EqualRect(lBeforeClientRect, lAfterClientRect) {V}
or (lCycleCount > 8); // устраняем зависание - http://mdp.garant.ru/pages/viewpage.action?pageId=300033419&focusedCommentId=333546939#comment-333546939
////////////////////////////////////////////////////////////////////////////////
end;
Комментариев нет:
Отправить комментарий