Форум: "Основная";
Текущий архив: 2005.07.25;
Скачать: [xml.tar.bz2];
ВнизИзменение размера формы мышкой Найти похожие ветки
← →
Дмитрий_05 (2005-06-07 20:03) [0]Как измененять размеры формы мышкой, когда у формы нет бордюра?
← →
-=XP=- © (2005-06-07 20:19) [1]Рамка окна для того и предназначена, чтобы можно было изменять размер окна.
Если же хотите отказаться от рамки, обрабатывайте сообщение MouseDown, определяйте, в какой области окна было произведено нажатие, и, в зависимости от этого - выполняйте код:ReleaseCapture;
SendMessage(Form.Handle, WM_SYSCOMMAND, $f00e, 0);
где <Const> - константа, определяющая способ перемещения/изменения размеров окна, например,
$0f12 - перемещение всего окна, как если бы пользователь перетаскивал окно за заголовок.
$f00e - изменение вертикального размера окна сверху, как если бы пользователь навел указатель мыши на верхнюю границу рамки окна и изменял размеры.
Работу по определению "волшебных" констант оставлю на Вас. Должен же быть простор для творчества. :)
← →
-=XP=- © (2005-06-07 20:20) [2]Hint:
SendMessage(Form.Handle, WM_SYSCOMMAND, $f00e, 0);
читать какSendMessage(Form.Handle, WM_SYSCOMMAND, <Const>, 0);
← →
Дмитрий_05 (2005-06-07 20:35) [3]а изменение по горизонтали какая константа??? А еще вот что, если сделать так: по краям положить Image, и при клике и перемещении курсора по нему изменять размер окна. Или эти границы лучше еще как-то задавать?
← →
Юрий Зотов © (2005-06-07 20:54) [4]Подбирать недокументриванные констаньы в диапазоне 0..65535, конечно, можно, но есть опасение что это занятие займет некоторую часть жизни.
К счастью, есть и документированный способ - обрабатывать WM_NCHITEST и возвращать нужные значения. Детали см. в справке по WM_NCHITEST.
← →
-=XP=- © (2005-06-07 21:23) [5]Подбирать недокументриванные констаньы в диапазоне 0..65535
Они там рядом - в диапазоне от $f000 до $f02f, если мне не изменяет память. Давно это было. А Дмитрий пусть старается - рутина тоже полезна иногда. ;)
Или эти границы лучше еще как-то задавать?
Практически все события, связанные с указателем мыши, сопровождаются координатами X и Y.
const
BorderWidth = 5; // Это "мнимая" ширина Вашей границы
(X < BorderWidth) - Левая граница
(X > Form.Width - BorderWidth) - Правая граница
(Y > BorderWidth) - Верхняя граница
(Y < Form.Height - BorderWidth) - Нижняя граница
До углов, надеюсь, сами додумаетесь?
← →
Юрий Зотов © (2005-06-07 21:26) [6]Все же я бы не рекомендовал пользоваться недокументированными способами. Тем более, когда есть нормальный. И когда этот нормальный способ ничуть не сложнее. Скорее, даже проще.
:о)
← →
Дмитрий_05 (2005-06-07 22:25) [7]Мне это понятно... вот как сделать саму ту облать, при наведении на которую будет изменяться размер, а еще курсор мышки будет меняться на две стрелочки побокам...
← →
Abessalom (2005-06-07 22:52) [8]constructor TForm1.Create(AOwner: TComponent);
begin
inherited;
BorderStyle := bsNone;
BorderWidth := 2;
end;
procedure TForm1.WMNCHitTest(var Message: TWMNCHitTest);
var
P: TPoint;
R: TRect;
B: Integer;
begin
inherited;
with Message do
if Result = HTCLIENT then
Result := HTCAPTION
else begin
P := Point(XPos, YPos);
R := BoundsRect;
if PtInRect(R, P) then begin
B := BorderWidth;
InflateRect(R, -B, -B);
if not PtInRect(R, P) then begin
if P.X < R.Left then
Result := HTLEFT
else if P.X > R.Right then
Result := HTRIGHT;
if P.Y < R.Top then
if Result = HTLEFT then
Result := HTTOPLEFT
else if Result = HTRIGHT then
Result := HTTOPRIGHT
else
Result := HTTOP
else if P.Y > R.Bottom then
if Result = HTLEFT then
Result := HTBOTTOMLEFT
else if Result = HTRIGHT then
Result := HTBOTTOMRIGHT
else
Result := HTBOTTOM;
end;
end;
end;
end;
← →
Abessalom (2005-06-07 23:08) [9]
> if Result = HTCLIENT then
> Result := HTCAPTION
Ну это, если честно, лишнее;) Осталось из оригинала
← →
Юрий Зотов © (2005-06-08 00:43) [10]> Дмитрий_05 (07.06.05 22:25) [7]
Повторить ответ? Хорошо, повторяю - обрабатывайте WM_NCHITTEST. Будут Вам и стрелочки, и вообще полное счастье будет.
← →
Дмитрий_05 (2005-06-08 17:14) [11]Abessalom Спасибо! Работает! А как сделать чтобы окно было с минимальной высотой и шириной? т.е. чтобы меньше этих значений уже не делалось окно...
← →
-=XP=- © (2005-06-08 17:17) [12]Form.Constraints.MinHeight := 100;
Form.Constraints.MinWidth := 100;
← →
Дмитрий_05 (2005-06-08 17:19) [13]Спасибо огромное!
← →
Дмитрий_05 (2005-06-09 14:23) [14]А можео сделать так: при изменении размера окна, сначала отрисовывать прямоугольник, какая будет форма, а потом уже изменить у самой формы размеры... например как в WinAmp это сделано...
← →
REA (2005-06-09 14:30) [15]>P := Point(XPos, YPos);
>R := BoundsRect;
>if PtInRect(R, P) then begin
а P может быть не в Bounds, раз сообщение послано форме?
← →
Дмитрий_05 (2005-06-09 14:51) [16]есть ли какие-то стандартные средства или надо самому ее отрисовывать?
← →
Дмитрий_05 (2005-06-09 14:51) [17]есть ли какие-то стандартные средства или надо самому ее отрисовывать?
← →
-=XP=- © (2005-06-09 15:05) [18]Я думаю, "надо самому ее отрисовывать". На десктопе.
DC := GetDC(HWND_DESKTOP);
← →
Дмитрий_05 (2005-06-09 21:16) [19]Что то у меня не очень получается это, что у меня не так? Пробую пока с левой стороной так сделать. Делаю так:
var
oldPos: TPoint;
WRect: TRect;
...
procedure TForm1.WMNCHitTest(var Message: TWMNCHitTest);
var
P: TPoint;
R: TRect;
B: Integer;
dx, dy: integer;
begin
inherited;
with Message do
if Result = HTCLIENT then
Result := HTCAPTION
else begin
P := Point(XPos, YPos);
R := BoundsRect;
if PtInRect(R, P) then begin
B := BorderWidth;
InflateRect(R, -B, -B);
if not PtInRect(R, P) then begin
if P.X < R.Left then
begin
oldPos := Mouse.CursorPos;
GetWindowRect(Handle, WRect);
DrawFocusRect(GetDC(0), WRect);
dx := Mouse.CursorPos.X - oldPos.X;
dy := Mouse.CursorPos.Y - oldPos.Y;
if (WRect.Right - WRect.Left + dx > MinWidth) and (WRect.Right + dx < Screen.Width) then WRect.Right := WRect.Right + dx;
if (WRect.Bottom - WRect.Top + dy > MinHeight) and (WRect.Bottom + dy < Screen.Height) then WRect.Bottom := WRect.Bottom + dy;
oldPos := Mouse.CursorPos;
DrawFocusRect(GetDC(0), WRect);
BoundsRect := WRect;
Result := HTLEFT;
end
else if P.X > R.Right then
Result := HTRIGHT;
if P.Y < R.Top then
if Result = HTLEFT then
Result := HTTOPLEFT
else if Result = HTRIGHT then
Result := HTTOPRIGHT
else
Result := HTTOP
else if P.Y > R.Bottom then
if Result = HTLEFT then
Result := HTBOTTOMLEFT
else if Result = HTRIGHT then
Result := HTBOTTOMRIGHT
else
Result := HTBOTTOM;
end;
end;
end;
end;
Не рисуется...:-( Наверно HTLEFT все "съедает". Что делать?
← →
Дмитрий_05 (2005-06-09 22:27) [20]Может в обработчике WMNCHitTest нельзя никак сделать?
← →
Дмитрий_05 (2005-06-10 11:21) [21]Может надо WM_GETMINMAXINFO какнибудь обрабатывать?
← →
P.N.P. © (2005-06-10 11:49) [22]>Дмитрий_05
См. -=XP=- © (07.06.05 20:19) [1]
А константы я подскажу :)
$F008 //Правый нижний угол
$F005 //Правый верхний угол
$F004 //Левый верхний угол
$F007 //Левый нижний угол
$F003 //Верхняя сторона
$F006 //Нижняя сторона
$F002 //Правая сторона
$F001 //Левая сторона
$F00B //Что-то совсем интересное :)
$F00C //Тоже оригинально :)
← →
Дмитрий_05 (2005-06-10 13:36) [23]Вы немного не поняли вопрос... Я имел ввиду вот как: При изменении размеров окна без заголовка сначала отрисовывается рамка будущих размеров. У меня скинообразная форма, т.е. на форме Image... Если обрабатывать MouseDown и MoseMove формы они работают на "невидимом" бодюре формы?
← →
-=XP=- © (2005-06-10 13:42) [24]на форме Image
Не используйте Image. Рисуйте скин в Form.OnPaint().
← →
Дмитрий_05 (2005-06-13 23:35) [25]У меня на форме рисуется несколько изображений... А еще при изменении размеров формы, некоторые из них расстягиваются(Stretcth:=true)... В OnPaint я думаю будет сложновато все это сделать...
← →
Дмитрий_05 (2005-06-23 02:18) [26]Или всетаки лучше будет какнибудь в OnPaint сделать?
← →
-=XP=- © (2005-06-23 10:26) [27]Хотите пользоваться в DesignTime Images - поместите их на форму, вставьте изображения, установите прочие опции (например, растяжение) и установите для них свойство Visible в FALSE.
type
TSomeForm = class(TForm)
private
procedure WMEraseBkGnd(var a_Msg: TMessage); message WM_ERASEBKGND;
end;
procedure TSomeForm.WMEraseBkGnd(var a_Msg: TMessage);
var
BMP: TBitmap;
begin
BMP := TBitmap.Create;
try
BMP.Width := Width;
BMP.Height := Height;
BMP.Canvas.Brush.Color := Color;
BMP.Canvas.FillRect(ClientRect);
BMP.Canvas.StretchDraw(Image1.BoundsRect, Image1.Picture.Graphic);
BMP.Canvas.StretchDraw(Image2.BoundsRect, Image2.Picture.Graphic);
{...}
Canvas.Draw(0, 0, BMP);
finally
FreeAndNil(BMP);
end;
a_Msg.Result := 1;
end;
Как-то так...
← →
Дмитрий_05 (2005-06-23 22:39) [28]еще один вопросик, а зачем мы обрабатываем сообщение WM_ERASEBKGND? Может в Form.Create это прорисовывать?
← →
Дмитрий_05 (2005-06-24 19:21) [29]А еще когда я делаю двойную буферизацию, окно почему-то становится все черное...
← →
Дмитрий_05 (2005-06-24 23:15) [30]Я использовал код, что привел -=XP=-. При таком коде, при двойной буферизации, окно становится черным... А когда начнешь изменять размеры формы черный фон исчезает и появляются те изображения которые мы прорисовываем... А если не использовать двойную буферизацию(что я думаю не желательно), черного фона нету...
← →
-=XP=- © (2005-06-25 00:25) [31]еще один вопросик, а зачем мы обрабатываем сообщение WM_ERASEBKGND? Может в Form.Create это прорисовывать
Form.Create отрабатывает один раз - при создании формы. Что потом делать будете? Разберитесь с тем, как вообще происходит отрисовка окон.
А еще когда я делаю двойную буферизацию, окно почему-то становится все черное<...> А если не использовать двойную буферизацию(что я думаю не желательно), черного фона нету...
Осталось только выяснить, для чего в примере BMP?
← →
Ищущий ответа (2005-06-25 08:29) [32]
procedure FormWithoutCaption(Form:TForm);
var
FSizeCaption: Integer;
begin
with Form do
begin
FSizeCaption := GetSystemMetrics(SM_CYCAPTION);
SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_Style) and not WS_Caption);
Height:=Height - FSizeCaption;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FormWithoutCaption(Form1);
end;
← →
-=XP=- © (2005-06-25 10:26) [33]Ищущий ответа (25.06.05 08:29) [32]
"у формы нет бордюра"?
← →
Дмитрий_05 (2005-06-25 17:25) [34]а... когда я пробовал был... А он на это влияет? Мне бы чтобы с бордюром и без... Что-то наподобие MediaPleer-a
← →
Дмитрий_05 (2005-06-25 21:49) [35]Ищущий ответа а это для чего код? Чтобы черного окна небыло или для чего? Как мне избавиться от черного окна в двойной буферизации?
← →
-=XP=- © (2005-06-25 23:47) [36]Как мне избавиться от черного окна в двойной буферизации
Зачем Вам DoubleBuffered?
← →
Дмитрий_05 (2005-06-27 17:06) [37]Чтобы при перетаскивании формы мелькала меньше...:-) А еще я тут что заметил... При прорисовке в Form.Canvas почему-то мелькает все сильно очень, при томже перетаскивании и изменении размера формы... Сделал я как показал XP Мне всетаки больше нравится с Image. Хотя хотелось бы всетаки прорисовывать в Form.Canvas-е...
← →
Дмитрий_05 (2005-06-29 16:14) [38]С чем это связано это мелькание? Я что-то никак не пойму... может другое какойенибудь сообщение обрабатывать? Или как-то по другому что-то делать?
← →
-=XP=- © (2005-06-29 16:53) [39]Связано с поочередной (Z-order) прорисовкой разных контролов.
Код давайте сюда.
← →
Дмитрий_05 (2005-06-29 17:40) [40]У меня форма расстягивается, так вот чтобы она пропорционально расстягивалась, я вот как сделал: по углам прорисовываю изображения, которые не будут изменяться в размере с изменением размера окна, а между ними расстягивать изображения... Причем вот как: верхнее и нижнее по горизонтали, а левое и правое по вертикали... Переменные R, R_2, R_3, R_4: TRect; используются для подчета положения, где прорисовывать изображения в зависимости с размерами формы... И еще, я использую файлы bmp, имеет значение использовать jpg? Вот код - мелькающий...
type
TForm1 = class(TForm)
private
procedure WMEraseBkGnd(var Msg: TMessage); message WM_ERASEBKGND;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.WMEraseBkGnd(var Msg: TMessage);
var
R, R_2, R_3, R_4: TRect;
BMPMain, BMPTest: TBitmap;
begin
BMPMain := TBitmap.Create;
BMPTest := TBitmap.Create;
try
BMPMain.Width := Form1.Width;
BMPMain.Height := Form1.Height;
BMPMain.Canvas.Brush.Color := Form1.Color;
BMPMain.Canvas.FillRect(ClientRect);
BMPTest.LoadFromFile("LeftTop.bmp");
R.Left:=BMPTest.Width;
R.Top:=0;
R_2.Left:=0;
R_2.Top:=BMPTest.Height;
BMPMain.Canvas.Draw(0, 0, BMPTest);
BMPTest.LoadFromFile("RightTop.bmp");
R.Right:=Form1.ClientWidth-BMPTest.Width;
R_3.Top:=BMPTest.Height;
BMPMain.Canvas.Draw(Form1.ClientWidth-BMPTest.Width, 0, BMPTest);
BMPTest.LoadFromFile("Top.bmp");
R.Bottom:=BMPTest.Height;
BMPMain.Canvas.StretchDraw(R, BMPTest);
BMPTest.LoadFromFile("LeftBottom.bmp");
R_2.Bottom:=Form1.ClientHeight-BMPTest.Height;
R_4.Left:=BMPTest.Width;
BMPMain.Canvas.Draw(0, Form1.ClientHeight-BMPTest.Height, BMPTest);
BMPTest.LoadFromFile("Left.bmp");
R_2.Right:=BMPTest.Width;
BMPMain.Canvas.StretchDraw(R_2, BMPTest);
BMPTest.LoadFromFile("RightBottom.bmp");
R_3.Bottom:=Form1.ClientHeight-BMPTest.Height;
R_4.Right:=Form1.ClientWidth-BMPTest.Width;
BMPMain.Canvas.Draw(Form1.ClientWidth-BMPTest.Width, Form1.ClientHeight-BMPTest.Height, BMPTest);
BMPTest.LoadFromFile("Right.bmp");
R_3.Left:=Form1.ClientWidth-BMPTest.Width;
R_3.Right:=Form1.ClientWidth;
BMPMain.Canvas.StretchDraw(R_3, BMPTest);
BMPTest.LoadFromFile("Bottom.bmp");
R_4.Top:=Form1.ClientHeight-BMPTest.Height;
R_4.Bottom:=Form1.ClientHeight;
BMPMain.Canvas.StretchDraw(R_4, BMPTest);
Form1.Canvas.Draw(0, 0, BMPMain);
finally
FreeAndNil(BMPTest);
FreeAndNil(BMPMain);
end;
Msg.Result := 1;
end;
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2005.07.25;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.013 c