-
Нужно изменять размер компонента, у которого также Align := alNone Подскажите как быть?
Цель такова, есть TMemo, его нужно расположить на форме по центру как по вертикали, так и по горизонтали, но нужно иметь возможность изменять размеры этого Memo. Делаю два коэф. которые указывают размеры МЕМО в процентах от размера Form1.ClientWidth и Form1.ClientHeight, и изменяю размер МЕМО в FormResize, также в FormResize "подгоняю" сплитеры к краям МЕМО.
Проблема в том что не могу сдвинуть сплитеры с места :(
-
Фраза "нужно иметь возможность изменять размеры этого Memo" - значить изменять эти коеф-ты, а изменять их я хочу с помощью сплитеров, думаю так будет красивее, чем создавать диалог настроек
-
Киньте на форму 4 панели (с alTop, alBottom, alkLeft и alRight) и 4 сплиттера (с таким же выравниванием), а потом TMemo с alClient.
В FormResize устанавливайте размеры панелей. Сплиттеры никуда подгонять не надо, они сами подгонятся.
Только непонятно - если Memo всегда должен быть по центру, то зачем вообще нужны сплиттеры? Сплиттеры позволяют юзеру менять размеры контролов мышкой, но если он начнет эти размеры менять, то нарушится центровка Memo - а этого ведь не должно быть?
-
Нафих тебе сдались сплиттеры - ума не приложу ..
На форме, кроме собственно мемо, есть еще какие-либо контролы, размер и положение которых зависит от размера и положения мемо ?
-
нет, на форме только Мемо и все, про 4 панели думал, но решил пока поискать более "изящное" решение. Планирую сдеалать два сплитера, по вертикали и па горизонтали соотв.. Узер двигает сплитер, и Мемо меняет свой размер (уменьшается/увеличивается) но остается по центру, т.е. противоположная сторона также будет синхронно изменяться. Вот из за этого и не хочу 4 панели, ибо прийдется корректировать размер противоположной панели, поюсь что все мигать начнет.
Щас пробую с TShape.
Когда то делал так что при нажатии и удерживании кнопки мыши, контрал передвигался, но тогда я делал компонент. наверное это мне сейчас и нужно. Может что еще подскажете? Заранее спасибо!!!
-
> Когда то делал так что при нажатии и удерживании кнопки > мыши,
ReleaseCapture; perform(WM_SysCommand, $F012, 0);
-
Спасибо! Но этот способ также как и:
procedure WMNCHITTEST(var Message : TMessage); message WM_NCHITTEST; ... procedure TMoveControl.WMNCHITTEST(var Message: TMessage); begin if not (csDesigning in ComponentState) then begin Message.Result := HTCAPTION; if Assigned(FOnMove) then FOnMove(Self); end else Message.Result := HTCLIENT; end;
не совсем подходит, так как зависит от системных настроек "Показывать окно при перемещении" и получить координаты компонента можна получить только когда пользователь отпустит кнопку мыши.
Я решил использовать что-то типа как в у форм область в правом нижнем углу, для изменения размеров Мемо
-
> получить координаты компонента можна получить только когда > пользователь отпустит кнопку мыши.
неправда.
> как в у форм область в правом нижнем углу,
для этого F012 изменяется на другое значение. Не помню какое, вычислял экспериментально.
-
Раньше помню часто спрашивали как в рантайме передвигать контролы и как менять их размеры. Сейчас пошли продвинутые вопросы :)
-
> Не помню какое
$F008
-
спасибо! ) сделал TControl(Sender).Perform(WM_SYSCOMMAND, SpinEdit1.Value , 0) - много интересного нашел :) теперь осталось научить получать предполагаемые новые размеры окна до того как будет отпущена кнопка мыши. > > получить координаты компонента можна получить только когда > > > пользователь отпустит кнопку мыши. > > неправда.
KilkennyCat, прошу помощи!!! делаю так: procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
begin
ReleaseCapture;
TControl(Sender).Perform(WM_SYSCOMMAND, $F008 , 0); end;
end;
procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
Caption := IntToStr(x) + ' ' + IntToStr(y);
end;
procedure TForm1.Panel1Resize(Sender: TObject);
begin
Caption := FloatToStr(Panel1.Width) + ' ' + FloatToStr(Panel1.Height);
end; результата нет :( какие сообщения мыши или резайза ловить? и в каком окне(ну может родителя)?
-
KilkennyCat, пока что пришел только к тому чтобы использовать таймер :), это по поводу:
> получить координаты компонента можна получить только когда > пользователь отпустит кнопку мыши.
неправда.
-
подскажите как?
-
ну, например, не зацикливаться на панели. не только она знает про мышь.
-
кроме того, раз контрол перерисовывается, то перерисовывалке его размеры известны.
-
Вот попробуй вариант решения задачи: DFMobject Form1: TForm1
Left = 192
Top = 114
Width = 602
Height = 374
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnResize = FormResize
PixelsPerInch = 96
TextHeight = 13
object Panel1: TPanel
Left = 164
Top = 100
Width = 185
Height = 61
BorderWidth = 2
Caption = 'Panel1'
TabOrder = 0
OnMouseDown = Panel1MouseDown
OnMouseMove = Panel1MouseMove
object Memo1: TMemo
Left = 3
Top = 3
Width = 179
Height = 55
Align = alClient
Lines.Strings = (
'Memo1')
TabOrder = 0
end
end
end PASunit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;
type
TPosMouseRect = (pmNone, pmRect, pmLU, pmU, pmRU, pmR, pmRD, pmD, pmLD, pmL);
TForm1 = class(TForm)
Panel1: TPanel;
Memo1: TMemo;
procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure FormResize(Sender: TObject);
private
OldX, OldY: Integer; PMDown: TPosMouseRect;
public
end;
var Form1: TForm1;
implementation
function GetPosMouseInRect(Rct: TRect; MP: TPoint; AVal: Integer): TPosMouseRect;
function XLeft: Boolean; begin Result:=MP.X<Rct.Left+AVal; end;
function XRight: Boolean; begin Result:=MP.X>Rct.Right-Rct.Left-AVal; end;
function XCentr: Boolean; begin Result:=(MP.X>=Rct.Left+AVal) and (MP.X<=Rct.Right-Rct.Left-AVal) end;
function YTop: Boolean; begin Result:=MP.Y<Rct.Top+AVal; end;
function YBottom: Boolean; begin Result:=MP.Y>Rct.Bottom-Rct.Top-AVal end;
function YCenter: Boolean; begin Result:=(MP.Y>=Rct.Top+AVal) and (MP.Y<=Rct.Bottom-Rct.Top-AVal) end;
begin
Result:=pmNone;
if not PtInRect(Rct, MP) then Exit;
if XLeft and YTop then Result:=pmLU else
if XLeft and YCenter then Result:=pmL else
if XLeft and YBottom then Result:=pmLD else
if XCentr and YTop then Result:=pmU else
if XRight and YTop then Result:=pmRU else
if XRight and YCenter then Result:=pmR else
if XRight and YBottom then Result:=pmRD else
if XCentr and YBottom then Result:=pmD else
Result:=pmRect;
end;
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
OldX:=X; OldY:=Y; PMDown:=GetPosMouseInRect(Panel1.ClientRect, Point(X, Y), 4);
end;
procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var NewX, NewY: Integer;
begin
case GetPosMouseInRect(Panel1.ClientRect, Point(X, Y), 4) of
pmRect, pmNone: Panel1.Cursor:=crDefault;
pmU, pmD: Panel1.Cursor:=crSizeNS;
pmLU, pmRD: Panel1.Cursor:=crSizeNWSE;
pmLD, pmRU: Panel1.Cursor:=crSizeNESW;
pmL, pmR: Panel1.Cursor:=crSizeWE;
end;
if not (ssLeft in Shift) then Exit;
NewX:=X-OldX;
NewY:=Y-OldY;
with (Sender as TControl) do
case PMDown of
pmRect: SetBounds(Left + NewX, Top + NewY, Width, Height); pmL: SetBounds(Left + NewX, Top, Width+-NewX*2, Height);
pmLU: SetBounds(Left + NewX, Top + NewY, Width+-NewX*2, Height+-NewY*2);
pmU: SetBounds(Left, Top + NewY, Width, Height+-NewY*2);
end;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
Panel1.Left:=(ClientWidth-Panel1.Width) div 2;
Panel1.Top:=(ClientHeight-Panel1.Height) div 2;
end;
end. Вот только четыре строчки придумай сам.... у меня математика болит :( Голова ломается.... Собсно там нужно придумать одну, а остальные аналогично... Если придет ко мне озорение я и их напишу тебе, но....) :о)
-
Есть и глюки, но это не конечный вариант, а направление... :)
-
Хотя, я думаю и этого варианта будет достаточно... Нужно только закомментировать изменение курсора в "неполучившихся" местах и делов.... :) Т.е. изменение размеров мемо можно производить по верхней, левой стороне и за верхний-левый угол.... Думаю достаточно... У меня как-то инвертированно получилось с другими, вот например с правой: pmR: SetBounds(Left + NewX, Top, Width - NewX*2, Height); - не красиво :( В общем... можно и подумать, но сейчас времени нет.... Так же и после расчета NewX, NewY можно вставить: if (NewX>=Panel1.Width-20) or (NewY>=Panel1.Height-20) then Exit; но тоже криво работает.... пишу на коленке.... некогда больно тестить и думать, но думаю натолкну на мысли... :)
-
Пришло ко мне никому не нужное озарение.... pmR: begin
SetBounds(Left - StepX, Top, Width + StepX*2, Height);
OldX:=X+StepX;
end;
pmD: begin
SetBounds(Left, Top - StepY, Width, Height + StepY*2);
OldY:=Y+StepY;
end;
pmRD: begin
SetBounds(Left - StepX, Top - StepY, Width + StepX*2, Height + StepY*2);
OldX:=X+StepX; OldY:=Y+StepY;
end;
pmLD: begin
SetBounds(Left + StepX, Top - StepY, Width + -StepX*2, Height + StepY*2);
OldY:=Y+StepY;
end;
pmRU: begin
SetBounds(Left - StepX, Top + StepY, Width + StepX*2, Height + -StepY*2);
OldX:=X+StepX;
end;
end; StepX{Y} - Это которые NewX{Y}.... А с ограничениями размеров панели.... слишком много кода уже и так :) В общем я пробывал сделать общую проверку типа: if (Panel1.Width<=20+StepX) or (Panel1.Height<=20+StepY) then Exit; Это не вся проверка, а кусок, но все равно глючно все это..... Эту проверку нужно вставлять в case перед сменой размеров и положения панели(SetBounds) Т.е. на каждый pmXx.... Эх.... пригодилось бы только кому :( :о)
-
спасиб {RASkov}, но я немного не то хочу ) наверное я просто не правильно выразил свои мысли если не боитесь вирусов :) то можете попробовать запустить то что у меня получилось http://upload.com.ua/link/900494914
-
ну вирусов конечно же нет, программу решил написать по мотивам блокнота DarkRoom
-
> Ruzzz © (16.10.08 03:47) [18] > > спасиб {RASkov}, но я немного не то хочу ) наверное я просто > не правильно выразил свои мысли > > если не боитесь вирусов :) то можете попробовать запустить > то что у меня получилось http://upload.com.ua/link/900494914 >
И что этот запуск даст?
-
> [18] Ruzzz © (16.10.08 03:47)
Ясно) Получилось вроде бесспорно лучше чем у меня, но и у меня вроде тоже самое, даже больше.... у меня за любую точку можно менять, а у тебя только за черный квадрат.... Но вот ограничения я не стал делать.... Хотя это(квадрат) может быть задумкой, но я так и не понял для чего вообще нужен этот черный квадрат в блокноте? :) Имхо.... это просто какойто каприз :)
-
да, это действитльно больше каприз :) это своего рода попытка программирования интерфейса ) ну и что-то типа блокнота DarkRoom.
-
Вопрос, ответ на который - WM_NCMOUSEMOVE - все еще актуален? :)
|