Плавающая панель
Плавающая панель Кто-нибудь пробовал создать форму, подобную "отстегивающимся" панелькам (FreeDoc)? Я попробовал и вот что получилось... Код требует использования некоторых функций WinAPI. Описание всех WinAPI функций доступны при нажатии F1 (электронная справка)... Ну а теперь попробуем это создать (весь код занимает около 100 строчек)... Ход работы: Стартуйте новый проект, задайте свойству borderstyle формы значение bsNone, добавьте панель, установите у нее свойство borderstyle равным значению bsSingle, добавьте другую панель с любым заголовком, добавьте кнопку с подсказкой 'переключатель панели заголовка', вырежьте из данного совера код и вставьте его в модуль, создайте обработчики трех событий панелей (MouseDown, MouseMove, MouseUp) и один обработчик кнопки (Click). Надеюсь, что ничего не забыл... ;-) Быстрее сделать это в Delphi, чем написать здесь... ;-)
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
Button1: TButton;
procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
OldX,
OldY,
OldLeft,
Old: Integer;
ScreenDC: HDC;
MoveRect: TRect;
Moving: Boolean;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
begin
SetCapture(Panel1.Handle);
ScreenDC := GetDC(0);
OldX := X;
OldY := Y;
OldLeft := X;
Old := Y;
MoveRect := BoundsRect;
DrawFocusRect(ScreenDC, MoveRect);
Moving := True;
end;
end;
procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if Moving then
begin
DrawFocusRect(ScreenDC, MoveRect);
OldX := X;
OldY := Y;
MoveRect := Rect(Left + OldX - OldLeft, + OldY - Old,
Left + Width + OldX - OldLeft, + Height + OldY - Old);
DrawFocusRect(ScreenDC, MoveRect);
end;
end;
procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
begin
ReleaseCapture;
DrawFocusRect(ScreenDC, MoveRect);
Left := Left + X - OldLeft;
:= + Y - Old;
ReleaseDC(0, ScreenDC);
Moving := False;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
TitleHeight,
BorderWidth,
BorderHeight: Integer;
begin
TitleHeight := GetSystemMetrics(SM_CYCAPTION);
BorderWidth := GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXFRAME) -
1;
BorderHeight := GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYFRAME) -
2;
if BorderStyle = bsNone then
begin
BorderStyle := bsSizeable;
:= - TitleHeight - BorderHeight;
Height := Height + TitleHeight + 2 * BorderHeight;
Left := Left - BorderWidth;
Width := Width + 2 * BorderWidth;
end
else
begin
BorderStyle := bsNone;
:= + TitleHeight + BorderHeight;
Height := Height - TitleHeight - 2 * BorderHeight;
Left := Left + BorderWidth;
Width := Width - 2 * BorderWidth;
end;
end;
end.
Коментарии
У меня есть один коментарий отностительно вышеприведенного кода: данная реализация сложней, чем она должна была быть. Все, что вы должны сделать - это обработать системное сообщение wm_NCHitTest. Я приведу здесь код, который я создал для Borland Tech Info, и который выполняет ту же функцию:
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
procedure WMNCHitTest(var M: TWMNCHitTest); message wm_NCHitTest;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.WMNCHitTest(var M: TWMNCHitTest);
begin
inherited; { вызвали наследованный дескриптор сообщения, }
if M.Result = htClient then { кликнув в области окна? }
M.Result := htCaption; { если так, то мы заставили Windows думать, }
{ что это область заголовка. }
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Close;
end;
end.
http://delphiworld.narod.ru/
DelphiWorld 6.0
Так называемая "плавающая панель" используется обычно для панелей инструментов.
Текст в модуле с основной формой:
begin
Form2.Show;
end;
Текст в модуле с "плавающей" панелью:
procedure CreateParams(var Params: TCreateParams); override;
...
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited;
with Params do
begin
Style := Style or WS_OVERLAPPED;
WndParent := Form1.Handle;
end;
end;
http://delphiworld.narod.ru/ DelphiWorld 6.0
Отправить комментарий