Пропорциональный ресайз форм
От: defrag  
Дата: 01.12.04 07:06
Оценка:
О, всезнающий All

Нужно чтобы изменение размеров формы происходило пропорционально, точнее чтобы пропорционально изменялось одно из окон на форме, а форма под него подстраивалась


procedure TForm1.OnCanResize(Sender: TObject; var NewWidth,
  NewHeight: Integer; var Resize: Boolean);
var
  w, h: longint;
begin
  if Height <> NewHeight then
  begin
    h := NewHeight - 210;
    w := round(h / ih * iw);
    NewWidth := w + 12;
    Resize := true;
    exit;
  end;


  if Width <> NewWidth then
  begin
    w := NewWidth - 12;
    h := round(w / iw * ih);
    NewHeight := h + 210;
    Resize := true;
    exit;
  end;
end;


Пыервый блок должен срабатывать, когда мы производим вертикальное изменение размеров, второй — при горизонтальном изменении.

Так вот, когда делаю вертикальный ресайз мышкой — все замечательно, плавно и красиво.
А когда начинаю горизонтальный ресайз, то начинаются глюкобаги. Размеры формы меняются скачкообразно: первоначальный размер — текущее положение мыши — первоначальный размер — текущее положение мыши

Что за грабли?
Re: Пропорциональный ресайз форм
От: Softwarer http://softwarer.ru
Дата: 01.12.04 07:55
Оценка:
Здравствуйте, defrag, Вы писали:

Отладчик Вам в помощь — это надо просто смотреть. По описанию — впечатление, что Вы организовали рекурсивный вызов либо собственной процедуры, либо какой-то из VCL-ных. Ставьте use debug DCU's, брейкпоинты — и смотрите, как ходит управление между Вашим и системным кодом.
Re: Пропорциональный ресайз форм
От: defrag  
Дата: 01.12.04 08:25
Оценка:
Сделал кое что другое

поставил брейкпоинт на

if Width <> NewWidth then

и стал изменять вертикальный размер. По идее до этого блока контроль не должен доходить никогда, но...
При окончании ресайза, происходит срабатывание брейкпоинта (напомню, ресайз вертикальный, значит горизонтальный размер постоянный) при этом NewWidth равно ширине до начала ресайза.
Re[2]: Пропорциональный ресайз форм
От: Softwarer http://softwarer.ru
Дата: 01.12.04 08:31
Оценка:
Здравствуйте, defrag, Вы писали:

D>и стал изменять вертикальный размер. По идее до этого блока контроль не должен доходить никогда, но...


Почему это никогда? Вы изменяете ширину — при этом снова происходит Resize и снова вызывается Ваша процедура. Посмотрите стек вызовов — увидите.
Re: Пропорциональный ресайз форм
От: byterus Россия  
Дата: 01.12.04 08:40
Оценка: 5 (1)
Здравствуйте, defrag, Вы писали:

Используйте локальные переменные для вычисления размеров, а когда закончите расчеты установите все параметры сразу методом TForm.SetBounds.
MySQL stored procedure debugging
Re[2]: Пропорциональный ресайз форм
От: defrag  
Дата: 01.12.04 11:27
Оценка:
Здравствуйте, byterus, Вы писали:

B>Здравствуйте, defrag, Вы писали:


B>Используйте локальные переменные для вычисления размеров, а когда закончите расчеты установите все параметры сразу методом TForm.SetBounds.


А это лучше делать в обработчике OnCanResize или перехватиь WM_SIZING?
Re[3]: Пропорциональный ресайз форм
От: byterus Россия  
Дата: 01.12.04 11:48
Оценка:
Здравствуйте, defrag, Вы писали:

D>Здравствуйте, byterus, Вы писали:


B>>Здравствуйте, defrag, Вы писали:


B>>Используйте локальные переменные для вычисления размеров, а когда закончите расчеты установите все параметры сразу методом TForm.SetBounds.


D>А это лучше делать в обработчике OnCanResize или перехватиь WM_SIZING?


В идеале нужно перекрыть метод SetBounds. Если обрабатывать OnResize то боюсь что можно нарваться на бесконечный цикл.
MySQL stored procedure debugging
Re[4]: Пропорциональный ресайз форм
От: defrag  
Дата: 01.12.04 12:39
Оценка:
Здравствуйте, byterus, Вы писали:

B>Здравствуйте, defrag, Вы писали:


D>>Здравствуйте, byterus, Вы писали:


B>>>Здравствуйте, defrag, Вы писали:


B>>>Используйте локальные переменные для вычисления размеров, а когда закончите расчеты установите все параметры сразу методом TForm.SetBounds.


D>>А это лучше делать в обработчике OnCanResize или перехватиь WM_SIZING?


B>В идеале нужно перекрыть метод SetBounds. Если обрабатывать OnResize то боюсь что можно нарваться на бесконечный цикл.


Не OnResize, а OnCanResize, он по своей сути похож на перехват WM_SIZING.
Re[5]: Пропорциональный ресайз форм
От: byterus Россия  
Дата: 02.12.04 03:17
Оценка:
Здравствуйте, defrag, Вы писали:

D>Здравствуйте, byterus, Вы писали:


B>>Здравствуйте, defrag, Вы писали:


D>>>Здравствуйте, byterus, Вы писали:


B>>>>Здравствуйте, defrag, Вы писали:


B>>>>Используйте локальные переменные для вычисления размеров, а когда закончите расчеты установите все параметры сразу методом TForm.SetBounds.


D>>>А это лучше делать в обработчике OnCanResize или перехватиь WM_SIZING?


B>>В идеале нужно перекрыть метод SetBounds. Если обрабатывать OnResize то боюсь что можно нарваться на бесконечный цикл.


D>Не OnResize, а OnCanResize, он по своей сути похож на перехват WM_SIZING.


Не суть, самый верный способ корректировки размеров это работать с SetBounds. Посмотрите исходники, можно анализировать флаг ScalingFlags, чтобы узнать что изменилось.
MySQL stored procedure debugging
Re: Пропорциональный ресайз форм
От: Аноним  
Дата: 03.12.04 03:31
Оценка:
Здравствуйте, defrag, Вы писали:

D>О, всезнающий All


D>Нужно чтобы изменение размеров формы происходило пропорционально, точнее чтобы пропорционально изменялось одно из окон на форме, а форма под него подстраивалась



D>
D>procedure TForm1.OnCanResize(Sender: TObject; var NewWidth,
D>  NewHeight: Integer; var Resize: Boolean);
D>var
D>  w, h: longint;
D>begin
D>  if Height <> NewHeight then
D>  begin
D>    h := NewHeight - 210;
D>    w := round(h / ih * iw);
D>    NewWidth := w + 12;
D>    Resize := true;
D>    exit;
D>  end;


D>  if Width <> NewWidth then
D>  begin
D>    w := NewWidth - 12;
D>    h := round(w / iw * ih);
D>    NewHeight := h + 210;
D>    Resize := true;
D>    exit;
D>  end;
D>end;
D>


вообще мне кажеться зря на блоки разбил, ведь что будет если оба размера изменятся

Пусть ты задал Scale = Width/Height, M = 100 — некоторый мультипликатор, тогда


if (fabs((NewWidth-Width)/Scale) > fabs((NewHeight-Height)))
NewHeight = NewWidth/Scale;
else
NewWidth = NewHeight*Scale;

D = ceil((double)M*(double)NewWidth/(double)Width);

NewWidth = Width/((double)M/(double)D);
NewHeight = Height/((double)M/(double)D);
Re[2]: Пропорциональный ресайз форм
От: defrag  
Дата: 03.12.04 09:29
Оценка:
Если изменятся оба, то один из них будет главным
Re[3]: Пропорциональный ресайз форм
От: Аноним  
Дата: 06.12.04 07:54
Оценка:
а главный тот кто первый по коду?!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.