Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.11.30;
Скачать: CL | DM;

Вниз

как работать с TSplitter у которого Align := alNone ?   Найти похожие ветки 

 
Ruzzz ©   (2008-10-13 21:54) [0]

Нужно изменять размер компонента, у которого также Align := alNone
Подскажите как быть?

Цель такова, есть TMemo, его нужно расположить на форме по центру как по вертикали, так и по горизонтали, но нужно иметь возможность изменять размеры этого Memo. Делаю два коэф. которые указывают размеры МЕМО в процентах от размера Form1.ClientWidth и Form1.ClientHeight, и изменяю размер МЕМО в FormResize, также в FormResize "подгоняю" сплитеры к краям МЕМО.

Проблема в том что не могу сдвинуть сплитеры с места :(


 
Ruzzz ©   (2008-10-13 21:57) [1]

Фраза "нужно иметь возможность изменять размеры этого Memo" - значить изменять эти коеф-ты, а изменять их я хочу с помощью сплитеров, думаю так будет красивее, чем создавать диалог настроек


 
Юрий Зотов ©   (2008-10-13 22:12) [2]

Киньте на форму 4 панели (с alTop, alBottom, alkLeft и alRight) и 4 сплиттера (с таким же выравниванием), а потом TMemo с alClient.

В FormResize устанавливайте размеры панелей. Сплиттеры никуда подгонять не надо, они сами подгонятся.

Только непонятно - если Memo всегда должен быть по центру, то зачем вообще нужны сплиттеры? Сплиттеры позволяют юзеру менять размеры контролов мышкой, но если он начнет эти размеры менять, то нарушится центровка Memo - а этого ведь не должно быть?


 
Сергей М. ©   (2008-10-13 22:12) [3]

Нафих тебе сдались сплиттеры - ума не приложу ..

На форме, кроме собственно мемо, есть еще какие-либо контролы, размер и положение которых зависит от размера и положения мемо ?


 
Ruzzz ©   (2008-10-13 22:19) [4]

нет, на форме только Мемо и все, про 4 панели думал, но решил пока поискать более "изящное" решение. Планирую сдеалать два сплитера, по вертикали и па горизонтали соотв.. Узер двигает сплитер, и Мемо меняет свой размер (уменьшается/увеличивается) но остается по центру, т.е. противоположная сторона также будет синхронно изменяться. Вот из за этого и не хочу 4 панели, ибо прийдется корректировать размер противоположной панели, поюсь что все мигать начнет.

Щас пробую с TShape.

Когда то делал так что при нажатии и удерживании кнопки мыши, контрал передвигался, но тогда я делал компонент. наверное это мне сейчас и нужно. Может что еще подскажете? Заранее спасибо!!!


 
KilkennyCat ©   (2008-10-13 22:48) [5]


> Когда то делал так что при нажатии и удерживании кнопки
> мыши,

ReleaseCapture;
perform(WM_SysCommand, $F012, 0);


 
Ruzzz ©   (2008-10-14 00:29) [6]

Спасибо! Но этот способ также как и:

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;

не совсем подходит, так как зависит от системных настроек "Показывать окно при перемещении" и получить координаты компонента можна получить только когда пользователь отпустит кнопку мыши.

Я решил использовать что-то типа как в у форм область в правом нижнем углу, для изменения размеров Мемо


 
KilkennyCat ©   (2008-10-14 00:58) [7]


> получить координаты компонента можна получить только когда
> пользователь отпустит кнопку мыши.

неправда.

> как в у форм область в правом нижнем углу,

для этого F012 изменяется на другое значение. Не помню какое, вычислял экспериментально.


 
Германн ©   (2008-10-14 01:03) [8]

Раньше помню часто спрашивали как в рантайме передвигать контролы и как менять их размеры. Сейчас пошли продвинутые вопросы :)


 
{RASkov} ©   (2008-10-14 01:17) [9]

> Не помню какое

$F008


 
Ruzzz ©   (2008-10-14 01:36) [10]

спасибо! ) сделал 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); // $F012
 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;


результата нет :( какие сообщения мыши или резайза ловить? и в каком окне(ну может родителя)?


 
Ruzzz ©   (2008-10-14 02:36) [11]

KilkennyCat, пока что пришел только к тому чтобы использовать таймер :), это по поводу:

> получить координаты компонента можна получить только когда
> пользователь отпустит кнопку мыши.

неправда.

-

подскажите как?


 
KilkennyCat ©   (2008-10-14 08:12) [12]

ну, например, не зацикливаться на панели. не только она знает про мышь.


 
KilkennyCat ©   (2008-10-14 08:18) [13]

кроме того, раз контрол перерисовывается, то перерисовывалке его размеры известны.


 
{RASkov} ©   (2008-10-14 13:14) [14]

Вот попробуй вариант решения задачи:
DFM
object 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


PAS
unit 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 { Private declarations }
   OldX, OldY: Integer; PMDown: TPosMouseRect;
 public { Public declarations }
 end;

var Form1: TForm1;

implementation

{$R *.dfm}

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);
   //pmR: Sorry...
   //pmD: Sorry...
   //pmRD: Sorry...
   //pmLD: Sorry...
  end;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
 Panel1.Left:=(ClientWidth-Panel1.Width) div 2;
 Panel1.Top:=(ClientHeight-Panel1.Height) div 2;
end;

end.


Вот только четыре строчки придумай сам.... у меня математика болит :( Голова ломается....
Собсно там нужно придумать одну, а остальные аналогично...
Если придет ко мне озорение я и их напишу тебе, но....)
:о)


 
{RASkov} ©   (2008-10-14 13:17) [15]

Есть и глюки, но это не конечный вариант, а направление... :)


 
{RASkov} ©   (2008-10-14 13:43) [16]

Хотя, я думаю и этого варианта будет достаточно... Нужно только закомментировать изменение курсора в "неполучившихся" местах и делов.... :)
Т.е. изменение размеров мемо можно производить по верхней, левой стороне и за верхний-левый угол.... Думаю достаточно...
У меня как-то инвертированно получилось с другими, вот например с правой:
pmR: SetBounds(Left + NewX, Top, Width - NewX*2, Height); - не красиво :(
В общем... можно и подумать, но сейчас времени нет....
Так же и после расчета NewX, NewY можно вставить:
if (NewX>=Panel1.Width-20) or (NewY>=Panel1.Height-20) then Exit; //20 это минимальный размер
но тоже криво работает.... пишу на коленке.... некогда больно тестить и думать, но думаю натолкну на мысли...
:)


 
{RASkov} ©   (2008-10-15 21:07) [17]

Пришло ко мне никому не нужное озарение....
   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....
Эх.... пригодилось бы только кому :(
:о)


 
Ruzzz ©   (2008-10-16 03:47) [18]

спасиб {RASkov}, но я немного не то хочу ) наверное я просто не правильно выразил свои мысли

если не боитесь вирусов :) то можете попробовать запустить то что у меня получилось http://upload.com.ua/link/900494914


 
Ruzzz ©   (2008-10-16 03:51) [19]

ну вирусов конечно же нет, программу решил написать по мотивам блокнота DarkRoom


 
Германн ©   (2008-10-16 03:54) [20]


> Ruzzz ©   (16.10.08 03:47) [18]
>
> спасиб {RASkov}, но я немного не то хочу ) наверное я просто
> не правильно выразил свои мысли
>
> если не боитесь вирусов :) то можете попробовать запустить
> то что у меня получилось http://upload.com.ua/link/900494914
>

И что этот запуск даст?


 
{RASkov} ©   (2008-10-16 09:37) [21]

> [18] Ruzzz ©   (16.10.08 03:47)

Ясно) Получилось вроде бесспорно лучше чем у меня, но и у меня вроде тоже самое, даже больше.... у меня за любую точку можно менять, а у тебя только за черный квадрат.... Но вот ограничения я не стал делать.... Хотя это(квадрат) может быть задумкой, но я так и не понял для чего вообще нужен этот черный квадрат в блокноте? :) Имхо.... это просто какойто каприз :)


 
Ruzzz ©   (2008-10-16 20:24) [22]

да, это действитльно больше каприз :) это своего рода попытка программирования интерфейса ) ну и что-то типа блокнота DarkRoom.


 
GrayFace ©   (2008-10-16 22:07) [23]

Вопрос, ответ на который - WM_NCMOUSEMOVE - все еще актуален? :)



Страницы: 1 вся ветка

Текущий архив: 2008.11.30;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.013 c
11-1195733927
Юрий_К
2007-11-22 15:18
2008.11.30
Про TrayIcon


15-1222603997
No_Dead(work)
2008-09-28 16:13
2008.11.30
Разыскиваются


15-1222253957
Delperec
2008-09-24 14:59
2008.11.30
Как проверить принадлежность точки кругу?..


2-1224529956
cruiser
2008-10-20 23:12
2008.11.30
String и повторяющиеся элементы


15-1222717128
Антон
2008-09-29 23:38
2008.11.30
Время до завершения при копировании файлов