Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
3-1118498889
Koala
2005-06-11 18:08
2005.07.25
Помогите с запросом... FB 1.5


3-1118315755
stelius
2005-06-09 15:15
2005.07.25
SQL запрос без раздела WHERE


14-1120483185
ПЛОВ
2005-07-04 17:19
2005.07.25
Что делать ума не приложу!


3-1118313248
salexn
2005-06-09 14:34
2005.07.25
Как определить овновляемый запрос или нет


3-1118421086
ctudent
2005-06-10 20:31
2005.07.25
Построение отчётов используя Midas.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский