Если вы используете приведённый здесь код, ваша кнопка ПУСК будет извиваться как в экстазе. На форму предварительно нужно вынести Image, Timer и две кнопки: CopyPuskBtn и AnimateBtn. Последняя должна быть неактивна изначально. Timer - отключен, его свойство Interval должно быть установлено в оптимальное значение - испытывайте.
unit Unit1;
interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, ShellAPI, ExtCtrls, StdCtrls;
const
MAX_BUFFER = 6;
type
TForm1 = class(TForm)
CopyPuskBtn: TButton;
Timer1: TTimer;
AnimateBtn: TButton;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure CopyPuskBtnClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure AnimateBtnClick(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private{ Private declarations }
HW: HWND;
DC: HDC;
R: TRect;
FNumber: integer;
Buffer: array [1 .. MAX_BUFFER] of TBitmap;
TrayIcon: TNotifyIconData;
procedure CreateFrames;
procedure DestroyFrames;
procedure BuildFrames;
procedure NotifyIcon(var Msg : TMessage); message WM_USER + 100;
procedure OnMinimizeEvt(Sender : TObject);
public{ Public declarations }end;
var
Form1: TForm1;
implementationuses
Math;
{$R *.DFM}// Создаём буфер для спрайтовprocedure TForm1.CreateFrames;
var
i: integer;
beginfor i := 1 to MAX_BUFFER dobegin
Buffer[i] := TBitmap.Create;
with Buffer[i] dobegin
Height := R.Bottom - R.Top;
Width := R.Right - R.Left;
Canvas.Brush.Color := clBtnFace;
Canvas.Pen.Color := clBtnFace;
Canvas.Rectangle(0, 0, Buffer[i].Width, Buffer[i].Height);
end;
end;
end;
procedure TForm1.DestroyFrames;
var
i: integer;
beginfor i := 1 to MAX_BUFFER do
Buffer[i].Destroy;
end;
// Подготавливает сегменты/спрайты для анимацииprocedure TForm1.BuildFrames;
var
i, j, k, H, W: integer;
Y: double;
begin
H := R.Bottom - R.Top;
W := R.Right - R.Left;
Image1.Width := W;
Image1.Height := H;
for i := 1 to MAX_BUFFER-1 do//Буфер [MAX_BUFFER] используется для хранения оригинального битмапаfor j := 1 to W dofor k := 1 to H dobegin
Y := 2 * Sin((j * 360 / W) * (pi / 180) - 20 * i);
Buffer[i].Canvas.Pixels[j, k - Round(Y)] := Buffer[6].Canvas.Pixels[j, k];
end;
end;
procedure TForm1.OnMinimizeEvt(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
HW := FindWindowEx(FindWindow('Shell_TrayWnd', nil), 0, 'Button', nil);
GetWindowRect(HW, R);
DC := GetWindowDC(HW);
CreateFrames;
FNumber := 1;
TrayIcon.cbSize := SizeOf(TrayIcon);
TrayIcon.Wnd := Form1.Handle;
TrayIcon.uID := 100;
TrayIcon.uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP;
TrayIcon.uCallbackMessage := WM_USER + 100;
TrayIcon.hIcon := Application.Icon.Handle;
Shell_NotifyIcon(NIM_ADD, @TrayIcon);
Application.OnMinimize := OnMinimizeEvt;
end;
procedure TForm1.NotifyIcon(var Msg : TMessage);
begincase Msg.LParam of
WM_LBUTTONDBLCLK:
begin
ShowWindow(Application.Handle, SW_SHOW);
Application.Restore;
end;
end;
end;
procedure TForm1.CopyPuskBtnClick(Sender: TObject);
begin//Получаем изображение оригинальной кнопки, чтобы потом использовать его//когда анимация завершится
BitBlt(Buffer[MAX_BUFFER].Canvas.Handle, 0, 0, R.Right - R.Left, R.Bottom - R.Top, DC, 0, 0, SRCCOPY);
BuildFrames;
Image1.Canvas.Draw(0, 0, Buffer[MAX_BUFFER]);
AnimateBtn.Enabled := true;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Timer1.Enabled := false;
BitBlt(DC, 0, 0, R.Right - R.Left, R.Bottom - R.Top, Buffer[MAX_BUFFER].Canvas.Handle, 0, 0, SRCCOPY);
ReleaseDC(HW, DC);
DestroyFrames; // не забудьте сделать это !!!
Shell_NotifyIcon(NIM_DELETE, @TrayIcon);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
BitBlt(DC, 0, 0, R.Right - R.Left, R.Bottom - R.Top, Buffer[FNumber].Canvas.Handle, 0, 0, SRCCOPY);
Inc(FNumber);
if FNumber > MAX_BUFFER - 1 then
FNumber := 1;
end;
procedure TForm1.AnimateBtnClick(Sender: TObject);
begin
Timer1.Enabled := not Timer1.Enabled;
ifnot Timer1.Enabled thenbegin
BitBlt(DC, 0, 0, R.Right - R.Left, R.Bottom - R.Top, Buffer[MAX_BUFFER].Canvas.Handle, 0, 0, SRCCOPY);
AnimateBtn.Caption := '&Animate';
CopyPuskBtn.Enabled := true;
endelsebegin
AnimateBtn.Caption := '&Stop';
CopyPuskBtn.Enabled := false;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caNone;
PostMessage(Form1.Handle, WM_DESTROY, 0, 0);
Application.Terminate;
end;
end.
Программный код на Delphi для анимированной кнопки, которая анимируется как вращается. Вот разбивка кода:
Форма имеет несколько компонентов: CopyPuskBtn, Timer1, AnimateBtn и Image1. Кнопка CopyPuskBtn используется для запуска анимации, а AnimateBtn - для остановки или продолжения анимации.
Когда пользователь кликнет на CopyPuskBtn, код создает буфер битмапов (Buffer) и инициализирует их оригинальным изображением. Затем он строит кадры анимации, рисуя каждый кадр на отдельном битмапе. Результатирующая анимация отображается на компоненте Image1.
Таймер Timer1 используется для анимации кнопки. Он вызывает процедуру Timer1Timer, которая рисует следующий кадр анимации на кнопке.
Кнопка AnimateBtn используется для остановки или продолжения анимации. Когда кликнется, она переключает состояние таймера (Timer1.Enabled) и изменяет его надпись соответственно.
Код также включает компонент NotifyIcon, отображающий иконку в системном трейе. Пользователь может кликнуть на иконку, чтобы покажать или скрыть форму.
Некоторые предложения по улучшению кода:
Вместо использования отдельного битмапа для каждого кадра, можно использовать одиночный битмап и обновлять его пиксел за пикселем.
Можно добавить более анимаций, модифицируя процедуру BuildFrames.
Можно улучшить производительность анимации, оптимизируя код рисования или используя более эффективный метод обновления изображения кнопки.
Можно добавить дополнительные функции в форму, такие как возможность пользователю изменять скорость или направление анимации.
В комментарии автора о том, что "ваша кнопка будет крутиться как сумасшедшая", я думаю, что он имеет в виду, что кнопка будет казаться вращающейся или поворачивающейся при запуске анимации.
Анимированная кнопка ПУСК: код на Delphi для создания интерактивной анимации кнопки.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.