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

Вниз

Изменение размера формы мышкой   Найти похожие ветки 

 
Дмитрий_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;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.025 c
14-1120193284
pavel_guzhanov
2005-07-01 08:48
2005.07.25
DVD видеокамера


4-1117050645
Holms
2005-05-25 23:50
2005.07.25
ZwQueryObject + Delphi


3-1118412881
Lex_!
2005-06-10 18:14
2005.07.25
Отображение вычисляемого поля в DBGrid


14-1119841484
Skier
2005-06-27 07:04
2005.07.25
В Крым на машине...


8-1111692690
Sky
2005-03-24 22:31
2005.07.25
Как в делфи реализовать фильтрацию звука по частотам