![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
как работать с TSplitter у которого Align := alNone ?
Ruzzz © (2008-10-13 21:54:00)Нужно изменять размер компонента, у которого также Align := alNone
Подскажите как быть?
Цель такова, есть TMemo, его нужно расположить на форме по центру как по вертикали, так и по горизонтали, но нужно иметь возможность изменять размеры этого Memo. Делаю два коэф. которые указывают размеры МЕМО в процентах от размера Form1.ClientWidth и Form1.ClientHeight, и изменяю размер МЕМО в FormResize, также в FormResize "подгоняю" сплитеры к краям МЕМО.
Проблема в том что не могу сдвинуть сплитеры с места :(
GrayFace (2008-10-16 22:07:00) [1]Вопрос, ответ на который - WM_NCMOUSEMOVE - все еще актуален? :)
Ruzzz (2008-10-16 20:24:00) [2]да, это действитльно больше каприз :) это своего рода попытка программирования интерфейса ) ну и что-то типа блокнота DarkRoom.
{RASkov} (2008-10-16 09:37:00) [3]> [18] Ruzzz © (16.10.08 03:47)
Ясно) Получилось вроде бесспорно лучше чем у меня, но и у меня вроде тоже самое, даже больше.... у меня за любую точку можно менять, а у тебя только за черный квадрат.... Но вот ограничения я не стал делать.... Хотя это(квадрат) может быть задумкой, но я так и не понял для чего вообще нужен этот черный квадрат в блокноте? :) Имхо.... это просто какойто каприз :)
Германн (2008-10-16 03:54:00) [4]
> Ruzzz © (16.10.08 03:47) [18]
>
> спасиб {RASkov}, но я немного не то хочу ) наверное я просто
> не правильно выразил свои мысли
>
> если не боитесь вирусов :) то можете попробовать запустить
> то что у меня получилось http://upload.com.ua/link/900494914
>
И что этот запуск даст?
Ruzzz (2008-10-16 03:51:00) [5]ну вирусов конечно же нет, программу решил написать по мотивам блокнота DarkRoom
Ruzzz (2008-10-16 03:47:00) [6]спасиб {RASkov}, но я немного не то хочу ) наверное я просто не правильно выразил свои мысли
если не боитесь вирусов :) то можете попробовать запустить то что у меня получилось http://upload.com.ua/link/900494914
{RASkov} (2008-10-15 21:07:00) [7]Пришло ко мне никому не нужное озарение....
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} (2008-10-14 13:43:00) [8]Хотя, я думаю и этого варианта будет достаточно... Нужно только закомментировать изменение курсора в "неполучившихся" местах и делов.... :)
Т.е. изменение размеров мемо можно производить по верхней, левой стороне и за верхний-левый угол.... Думаю достаточно...
У меня как-то инвертированно получилось с другими, вот например с правой:
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-14 13:17:00) [9]Есть и глюки, но это не конечный вариант, а направление... :)
{RASkov} (2008-10-14 13:14:00) [10]Вот попробуй вариант решения задачи:
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.
Вот только четыре строчки придумай сам.... у меня математика болит :( Голова ломается....
Собсно там нужно придумать одну, а остальные аналогично...
Если придет ко мне озорение я и их напишу тебе, но....)
:о)
KilkennyCat (2008-10-14 08:18:00) [11]кроме того, раз контрол перерисовывается, то перерисовывалке его размеры известны.
KilkennyCat (2008-10-14 08:12:00) [12]ну, например, не зацикливаться на панели. не только она знает про мышь.
Ruzzz (2008-10-14 02:36:00) [13]KilkennyCat, пока что пришел только к тому чтобы использовать таймер :), это по поводу:
> получить координаты компонента можна получить только когда
> пользователь отпустит кнопку мыши.
неправда.
-
подскажите как?
Ruzzz (2008-10-14 01:36:00) [14]спасибо! ) сделал 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;
результата нет :( какие сообщения мыши или резайза ловить? и в каком окне(ну может родителя)?
{RASkov} (2008-10-14 01:17:00) [15]> Не помню какое
$F008
Германн (2008-10-14 01:03:00) [16]Раньше помню часто спрашивали как в рантайме передвигать контролы и как менять их размеры. Сейчас пошли продвинутые вопросы :)
KilkennyCat (2008-10-14 00:58:00) [17]
> получить координаты компонента можна получить только когда
> пользователь отпустит кнопку мыши.
неправда.
> как в у форм область в правом нижнем углу,
для этого F012 изменяется на другое значение. Не помню какое, вычислял экспериментально.
Ruzzz (2008-10-14 00:29:00) [18]Спасибо! Но этот способ также как и:
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-13 22:48:00) [19]
> Когда то делал так что при нажатии и удерживании кнопки
> мыши,
ReleaseCapture;
perform(WM_SysCommand, $F012, 0);
Ruzzz (2008-10-13 22:19:00) [20]нет, на форме только Мемо и все, про 4 панели думал, но решил пока поискать более "изящное" решение. Планирую сдеалать два сплитера, по вертикали и па горизонтали соотв.. Узер двигает сплитер, и Мемо меняет свой размер (уменьшается/увеличивается) но остается по центру, т.е. противоположная сторона также будет синхронно изменяться. Вот из за этого и не хочу 4 панели, ибо прийдется корректировать размер противоположной панели, поюсь что все мигать начнет.
Щас пробую с TShape.
Когда то делал так что при нажатии и удерживании кнопки мыши, контрал передвигался, но тогда я делал компонент. наверное это мне сейчас и нужно. Может что еще подскажете? Заранее спасибо!!!