Aqua-Soft Forums: Genie Effect Library - Aqua-Soft Forums

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Genie Effect Library Rate Topic: -----

#1 User is offline   vigil Icon

  • Group: Member
  • Posts: 17
  • Joined: 02-November 08

Posted 03 June 2009 - 08:09 AM

Hi, I'm trying to use RKLauncher RKGenieEffectDX DLLibrary
I found out that it has the following exports
- EffectCreate
- EffectDestroy
- EffectGetDisplayName
- EffectNextStep

But I have no idea about the parameters they need.

I'd like to use it to animate the minimization to the normal taskbar buttons.

It would be good if someone could also improve vhanla's genie effect posted here
http://www.aqua-soft.org/forum/index.php?s...st&p=526090
as a DLL would be perfect, so anyone could use at any dock/docklet
0

#2 User is offline   vhanla Icon

  • Group: Member
  • Posts: 48
  • Joined: 15-June 08

Posted 03 June 2009 - 06:13 PM

Actually that was a sample, and since I'm not good at graphics manipulation, it is very slow...
BTW: I also need to know how to use RKLauncher's RKGenieEffectDX plugin if it's possible.

However, I have written it to use it as a library :P
Source Code and Sample included
http://codigobit.net.../geniefxlib.rar
Messy code, hope you understand
It only works from top to bottom minimization's animation

Some questions:
- I am using a form with a transparent color and painting on its canvas. Is it faster if I use a layered window with alpha image instead?
- I'm using StretchBlt to draw line by line, is it faster to use scanlines, or gdiplus lockbits? I suppose yes, but I don't know how to do that, I mean a faster scanline stretch algorithm.

BTW: I also included a tasks dock binary (based on Matonga's mirror dock sample) as an example, to give and idea.
0

#3 User is offline   vigil Icon

  • Group: Member
  • Posts: 17
  • Joined: 02-November 08

Posted 04 June 2009 - 06:35 AM

Thanks my friend, I tested and works.
But it is slow and sometimes while animating, it draws incorrectly.
Maybe is because you're using the constant value STEP = 18 as a skip to
accelerate the slow animation, but with STEP=1 it works great, but too slow.

I'm not good at graphics too, you know it, so I hope you can improve it.

BTW: It would be good to add directions to minimize to.
And of course the restore animation too.

Regards!
0

#4 User is offline   matonga Icon

  • Group: Developers
  • Posts: 1,286
  • Joined: 04-September 06

Posted 04 June 2009 - 05:51 PM

Mmm... interesting, let's take a look at this code...

The only thing I dunno is to render texture contents onto a layered window (WPF would do for Vista, but I'm aiming for something XP compatible ;) )


@vigil & vhanla:

The fastest way to do gfx is with hardware acceleration (either 2d or 3d). Of course one can write an MMX / SIMD / SSEx / whatever optimized routine, but video board acceleration is usually much faster.

I can't promise anything because of lack of time, but I'll try and see if I can contribute with something.

Posted Image

Edit

Ok, made some changes...

Added my unitLayeredWindow.pas:

unit unitLayeredWindow;

interface

uses Windows, SysUtils, Forms, Graphics;

procedure LWSetupForm (form : TForm);
procedure LWSetImage (form : TForm; bmp : TBitmap);

//-----------------------------------------

const
  WS_EX_LAYERED = $80000;
  LWA_COLORKEY = 1;
  LWA_ALPHA = 2;
  ULW_COLORKEY = 1;
  ULW_ALPHA = 2;
  ULW_OPAQUE = 4;
  AC_SRC_ALPHA = 1;

function SetLayeredWindowAttributes (hwnd : HWND; crKey : COLORREF; bAlpha : BYTE; dwFlags : DWORD) : BOOL; stdcall;
function UpdateLayeredWindow (hwnd : HWND; dstHDC : HDC; ppDst : PPoint; ASize : PSize; srcHDC : HDC; pptSrc : PPoint; crKey : COLORREF; var bf : _BLENDFUNCTION; dwFlag : DWORD) : BOOL; stdcall;

function SetLayeredWindowAttributes; external 'user32.dll' name 'SetLayeredWindowAttributes';
function UpdateLayeredWindow; external 'user32.dll' name 'UpdateLayeredWindow';


implementation

var
  buffer : TBitmap;

procedure Preprocesar (bmp : TBitmap);
var
  x, y : Integer;
  p : PByteArray;
begin
  If bmp.PixelFormat <> pf32bit Then
	Exit;
  For y := 0 To bmp.Height-1 do
  begin
	p := bmp.Scanline[y];
	For x := 0 To bmp.Width-1 do
	begin
	  p[x*4  ] := (Integer(p[x*4  ]) * p[x*4+3]) div 255;
	  p[x*4+1] := (Integer(p[x*4+1]) * p[x*4+3]) div 255;
	  p[x*4+2] := (Integer(p[x*4+2]) * p[x*4+3]) div 255;
	end;
  end;
end;

procedure LWSetupForm (form : TForm);
begin
  form.BorderStyle := bsNone;
  SetWindowLong (form.Handle, GWL_EXSTYLE, GetWindowLong (form.Handle, GWL_EXSTYLE) Or WS_EX_LAYERED);
end;

procedure LWSetImage (form : TForm; bmp : TBitmap);
var
  y : Integer;
  bf : TBlendFunction;
  spt, dpt : TPoint;
  sz : TSize;
begin
  If bmp.PixelFormat <> pf32bit Then
	Exit;

  buffer.PixelFormat := pf32bit;
  buffer.Width := bmp.Width;
  buffer.Height := bmp.Height;

  For y := 0 To bmp.Height-1 do
	Move (bmp.Scanline[y]^, buffer.Scanline[y]^, bmp.Width*4);

  Preprocesar (buffer);

  bf.BlendOp := AC_SRC_OVER;
  bf.BlendFlags := 0;
  bf.SourceConstantAlpha := $FF;
  bf.AlphaFormat := AC_SRC_ALPHA;

  spt.x := 0;
  spt.y := 0;
  sz.cx := buffer.Width;
  sz.cy := buffer.Height;
  dpt.x := form.Left;
  dpt.y := form.Top;

  UpdateLayeredWindow (form.Handle, form.Canvas.Handle, @dpt, @sz, buffer.Canvas.Handle, @spt, 0, bf, ULW_ALPHA);
end;


initialization
  buffer := TBitmap.Create;
finalization
  buffer.Destroy;
end.



Added window clipping to minimal regions for faster animations, and use layered window with per pixel alpha instead of key color (much smoother because of that too):

(GenieFXsrc.pas)

{
GenieFXLib v0.1
Author: vhanla
This is a Genie Effect animation library sample
}
unit GenieFXsrc;

interface

uses
  Windows, Messages, SysUtils, {Variants, }Classes, Graphics, Controls, Forms,
  Dialogs, WindowsEx, Math, unitLayeredWindow;

type
  pgrap=^TBitmap;
  TForm1 = class(TForm)
	procedure FormCreate(Sender: TObject);
	procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
	{ Private declarations }
  public
	{ Public declarations }
   procedure GenieFX(pbmp: pgrap;sl,sr,st,sb,el,er,et,eb:integer);
  end;

  type
  (*
  TRGB32 = packed record
	B,G,R,A:byte;
  end;
  *)
  TRGB32 = Cardinal;
  TRGB32Array=packed array[0..MaxInt div sizeof(TRGB32)-1] of TRGB32;
  PRGB32Array = ^TRGB32Array;

var
  Form1: TForm1;

implementation

{$R *.dfm}


{-$DEFINE USE_STRETCHBLT}

// maybe faster than StretchBlt
procedure LineBlit (src, dst : PRGB32Array; src_scanline_width, dst_scanline_width, dst_x, dst_width : Integer);
var
	src_p, src_i, x : Integer;
begin
	If dst_width = 0 Then Exit;
	src_p := 0;
	src_i := 256 * src_scanline_width div dst_width;
	// frustrum culling
	If dst_x + dst_width <= 0 Then Exit;
	If dst_x >= dst_scanline_width Then Exit;
	// clipping
	If dst_x + dst_width >= dst_scanline_width Then
		dst_width := dst_scanline_width - dst_x;
	If dst_x < 0 Then
	begin
		inc (src_p, src_i * (-dst_x));
		dst_x := 0;
	end;
	// blitting
	For x := 0 To dst_width-1 do
	begin
		dst[dst_x + x] := src[src_p div 256] Or $FF000000;
		inc (src_p, src_i);
	end;
end;

procedure FillRGB32 (var dst; count : Cardinal); stdcall; assembler;
asm
	push edi
	push eax
	push ecx
	mov edi, dst
	mov ecx, count
	//mov eax, $FF00FF
	sub eax, eax

	rep stosd
	pop ecx
	pop eax
	pop edi
end; 


{
sl : start left
sr: start right
st: start top
sb: start bottom
el: end left
er: end right
et: end top
eb: end bottom
pgrap: pointer to bitmap

all relative to screen size
}

procedure TForm1.GenieFX(pbmp: pgrap;sl,sr,st,sb,el,er,et,eb:integer);
var
  i,j,w1,w2,h: integer;
  m1,m2:integer;
  l,r:array [0..5000]of integer;
  x,y,ya,y1,y2:real;
  bmp,bmpout,buffer:tbitmap;
const
  //STEP = 24; //to control speed
  STEP = 1;
  (*
		BAAAAD WAY TO CONTROL SPEED!!! SHOULD SPECIFY DURATION IN SECONDS, INSTEAD
		Regards,
		~ Matonga
  *)
var
	al, at, ar, ab : Integer;
begin
	//
	al := Min (sl, el);
	at := Min (st, et);
	ar := Max (sr, er);
	ab := Max (sb, eb);
	//SetWindowPos (Handle, 0, al, at, ar-al, ab-at, SWP_NOZORDER Or SWP_NOACTIVATE);
	Left := al;
	Top := at;
	Width := ar-al;
	Height := ab-at;
	dec (sl, al); dec (st, at); dec (sr, al); dec (sb, at);
	dec (el, al); dec (et, at); dec (er, al); dec (eb, at);
	//

  y1:=0.047425873;//1-1/(1+exp(-3));
  y2:=0.952574126;//1-1/(1+exp(3));
  h:=(et-st);//total height
  w1:=round(abs(sl-el));   //left width
  w2:=round(abs(sr-er));   //right width
  bmp:=tbitmap.Create;
  bmp.Height:=h;
  bmp.Width:=w1;
  bmp.Canvas.StretchDraw(rect(0,0,w1,h),pbmp^);//image1.Picture.Graphic);

  bmpout:=tbitmap.Create;
  bmpout.Height:=sr-sl;
  bmpout.Width:=w1;
  bmpout.Canvas.StretchDraw(rect(0,0,w1,sr-sl),pbmp^);//image1.Picture.Graphic);

  buffer:=tbitmap.Create;
  //buffer.Height:=canvas.ClipRect.Bottom-canvas.ClipRect.Top;
  //buffer.Width:=canvas.ClipRect.Right-canvas.ClipRect.Left;
  buffer.Height := ab - at;
  buffer.Width := ar - al;
  //buffer.Canvas.Brush.Color:=clFuchsia;
  //buffer.Canvas.FillRect(buffer.Canvas.ClipRect);

  // Force all bitmaps to 32 bits
  pbmp^.PixelFormat := pf32bit;
  bmp.PixelFormat := pf32bit;
  buffer.PixelFormat := pf32bit;
  bmpout.PixelFormat := pf32bit;

  //Animamos el encogido
  m1:=sl;
  m2:=sr;
  while (abs(m1-el)>STEP) or (abs(m2-er)>STEP) do
  begin
	//limpiamos el buffer
	{$IFDEF USE_STRETCHBLT}
	buffer.Canvas.FillRect(buffer.Canvas.ClipRect);
	{$ELSE}
	For i := 0 To buffer.Height-1 do
		FillRGB32 (buffer.Scanline[i]^, buffer.Width);
	{$ENDIF}

	for i:=0 to pbmp^.Height-1 do
	begin
	  x:=i*6/h-3;//pbmp^.Height-3;
	  y:=1-1/(1+exp(x));
	  ya:=(y-y1)/(y2-y1);
	  if m1<el then
		l[i]:=sl+round(ya*round(abs(m1-sl)))
	  else
		l[i]:=sl-round(ya*round(abs(m1-sl)));
	  if m2<er then
		r[i]:=sr+round(ya*round(abs(m2-sr)))
	  else
		r[i]:=sr-round(ya*round(abs(m2-sr)));
	  //dibujamos linea por linea
	  {$IFDEF USE_STRETCHBLT}
	  StretchBlt(buffer.Canvas.Handle,
		l[i],
		st+i,
		r[i]-l[i],1,
		pbmp^.Canvas.Handle,0,i,pbmp^.Width,1,SRCCOPY);
	  {$ELSE}
	  If (st+i >= 0) And (st+i < buffer.Height) And
		 (i >= 0) And (i < pbmp^.Height) Then
		LineBlit (pbmp^.Scanline[i], buffer.Scanline[st+i], pbmp^.Width, buffer.Width, l[i], r[i]-l[i]);
	  {$ENDIF}
	end;
	//canvas.CopyRect(clientrect,buffer.Canvas,clientrect);
	LWSetImage (self, buffer);
	Sleep (1);
	//reducimos el tamanio
	if abs(m1-el)>STEP then
	begin
	  if m1>el then m1:=m1-STEP;
	  if m1<el then m1:=m1+STEP;
	end
	else
	begin
	  if m1>el then m1:=m1-1;
	  if m1<el then m1:=m1+1;
	end;

	if abs(m2-er)>STEP then
	begin
	  if m2>er then m2:=m2-STEP;
	  if m2<er then m2:=m2+STEP;
	end
	else
	begin
	  if m2>er then m2:=m2-1;
	  if m2<er then m2:=m2+1;
	end;
  end;
  {primero recolectamos la forma en un array}
  for i:=0 to h-1 do
  begin
	x:=i*6/h-3;
	y:=1-1/(1+exp(x));
	ya:=(y-y1)/(y2-y1);
	if sl<el then
	  l[h-i]:=el-round(ya*w1)
	else
	  l[h-i]:=el+round(ya*w1);
	if sr<er then
	  r[h-i]:=er-round(ya*w2)
	else
	  r[h-i]:=er+round(ya*w2);
  end;

  {ahora dibujamos frames de bajada}
  j:=h-1;
  while j>=0 do
  begin
	j:=j-STEP;
	//limpiamos el buffer
	{$IFDEF USE_STRETCHBLT}
	buffer.Canvas.FillRect(buffer.Canvas.ClipRect);
	{$ELSE}
	For i := 0 To buffer.Height-1 do
		FillRGB32 (buffer.Scanline[i]^, buffer.Width);
	{$ENDIF}
	//dibujamos linea por linea
	for i:=0 to j-1 do
	begin
	  {$IFDEF USE_STRETCHBLT}
	  StretchBlt(buffer.Canvas.Handle,
		l[i+h-j],st+i+h-j,r[i+h-j]-l[i+h-j],1,
		bmp.Canvas.Handle,0,i,bmp.Width,1,SRCCOPY);
	  {$ELSE}
		If (st+i+h-j >= 0) And (st+i+h-j < buffer.Height) And
			(i >= 0) And (i < bmp.Height) Then
			LineBlit (bmp.Scanline[i], buffer.Scanline[st+i+h-j], bmp.Width, buffer.Width, l[i+h-j], r[i+h-j]-l[i+h-j]);
	  {$ENDIF}
	end;
	//canvas.CopyRect(clientrect,buffer.Canvas,clientrect);
	LWSetImage (self, buffer);
	Sleep (1);
  end;
  bmpout.free;
  buffer.Free;
  bmp.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
	(*
  DoubleBuffered:=True;
  //Application.ShowMainForm:=false;
  ShowWindow(Handle, SW_HIDE);
  SetWindowLong(Handle, GWL_EXSTYLE, getWindowLong(Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
  ShowWindow(Handle, SW_SHOW);
  BorderStyle:=bsNone;
  //WindowState:=wsMaximized;
  Height:=screen.Height;
  Width:=screen.Width;
  SetWindowLong(handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) Or WS_EX_LAYERED);
  SetLayeredWindowAttributes(Handle,$0ff00ff, 0, ULW_COLORKEY);
  SetWindowLong(Handle, GWL_STYLE, GetWindowLong(handle, GWL_STYLE) And Not WS_BORDER);
  *)
  SetWindowLong(Handle, GWL_EXSTYLE, (getWindowLong(Handle, GWL_EXSTYLE) And Not WS_EX_APPWINDOW) or WS_EX_TOOLWINDOW);
  LWSetupForm (self);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:=caFree;
end;

end.



Made a change in .dpr, I dunno if it's important:

(GenieFXLib.dpr)

library GenieFXLib;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes,
  GenieFXsrc in 'GenieFXsrc.pas' {Form1},
  WindowsEx in 'WindowsEx.pas',
  Windows;

{$R *.res}
procedure GenieFX(pbmp: pgrap;sl,sr,st,sb,el,er,et,eb:integer);stdcall;
begin
Form1:=TForm1.Create(nil);
//Form1.show;
ShowWindow (Form1.Handle, SW_SHOW);
Form1.GenieFX(pbmp,sl,sr,st,sb,el,er,et,eb);
Form1.Close;
end;

exports
  GenieFX;
begin
end.



The library still needs a lot of improvement, but at least it runs smooth now. :)

Posted Image

Edit

BTW I forgot to mention in last post:

Please don't pass a TBitmap!!! Even Delphi 5 is incompatible with that (I had to recompile both the .dll and the .exe demo to make them work together).

Use a pointer to bytes instead, or at least an HBITMAP handle (can get TBitmap.Handle, can then use pbmp := TBitmap.Create; pbmp.Handle := the_handle; ..... do all stuff ..... pbmp.ReleaseHandle; pbmp.Destroy; )

Posted Image

Edit

Didn't like the animation, so rewrote it from scratch. Plus now it uses duration (in milliseconds) instead of steps. ;)

GenieFXSrc.pas:

{
GenieFXLib v0.1
Author: vhanla
This is a Genie Effect animation library sample
}
unit GenieFXsrc;

interface

uses
  Windows, Messages, SysUtils, {Variants, }Classes, Graphics, Controls, Forms,
  Dialogs, WindowsEx, Math, unitLayeredWindow;

type
  pgrap=^TBitmap;
  TForm1 = class(TForm)
	procedure FormCreate(Sender: TObject);
	procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
	{ Private declarations }
  public
	{ Public declarations }
   procedure GenieFX(pbmp: pgrap;sl,sr,st,sb,el,er,et,eb:integer);
  end;

  type
  (*
  TRGB32 = packed record
	B,G,R,A:byte;
  end;
  *)
  TRGB32 = Cardinal;
  TRGB32Array=packed array[0..MaxInt div sizeof(TRGB32)-1] of TRGB32;
  PRGB32Array = ^TRGB32Array;

var
  Form1: TForm1;

implementation

{$R *.dfm}


{-$DEFINE USE_STRETCHBLT}

// maybe faster than StretchBlt
(*
procedure ABlit (src, dst : Pointer; count, src_ini, src_inc : Cardinal); stdcall; assembler;
asm
	push eax
	push ebx
	push ecx
	push edx
	push esi
	push edi

	mov esi, src
	mov edi, dst
	mov ecx, count
	mov edx, src_ini

	@loop:
	mov ebx, edx
	mov eax, [esi]
	add edx, src_inc
	or  eax, $FF000000
	shr ebx, 8
	add esi, 4
	shl ebx, 2
	mov [edi+ebx], eax
	inc edi
	dec ecx
	jnz @loop

	pop edi
	pop esi
	pop edx
	pop ecx
	pop ebx
	pop eax
end;
*)

procedure LineBlit (src, dst : PRGB32Array; src_scanline_width, dst_scanline_width, dst_x, dst_width : Integer);
var
	src_p, src_i, x : Integer;
begin
	If dst_width = 0 Then Exit;
	src_p := 0;
	src_i := 256 * src_scanline_width div dst_width;
	// frustrum culling
	If dst_x + dst_width <= 0 Then Exit;
	If dst_x >= dst_scanline_width Then Exit;
	// clipping
	If dst_x + dst_width >= dst_scanline_width Then
		dst_width := dst_scanline_width - dst_x;
	If dst_x < 0 Then
	begin
		inc (src_p, src_i * (-dst_x));
		dst_x := 0;
	end;
	// blitting
	For x := 0 To dst_width-1 do
	begin
		dst[dst_x + x] := src[src_p div 256] Or $FF000000;
		inc (src_p, src_i);
	end;
	//ABlit (src[0], dst[dst_x], dst_width, src_p, src_i);
	//ABlit (src, dst, dst_width, 0, 256);
end;

procedure FillRGB32 (var dst; count : Cardinal); stdcall; assembler;
asm
	push edi
	push eax
	push ecx
	mov edi, dst
	mov ecx, count
	//mov eax, $FF00FF
	sub eax, eax

	rep stosd
	pop ecx
	pop eax
	pop edi
end; 


{
sl : start left
sr: start right
st: start top
sb: start bottom
el: end left
er: end right
et: end top
eb: end bottom
pgrap: pointer to bitmap

all relative to screen size
}

procedure TForm1.GenieFX(pbmp: pgrap;sl,sr,st,sb,el,er,et,eb:integer);
var
  i,j,w1,w2,h: integer;
  m1,m2:integer;
  l,r:array [0..5000]of integer;
  x,y,ya,y1,y2:real;
  bmp,bmpout,buffer:tbitmap;

  bl, br : array[0..5000] of Integer;   // bordes

const
  //STEP = 24; //to control speed
  //STEP = 1;
  DURATION = 1000;  // animation duration in milliseconds
  (*
		BAAAAD WAY TO CONTROL SPEED!!! SHOULD SPECIFY DURATION IN SECONDS, INSTEAD
		Regards,
		~ Matonga
  *)
var
	al, at, ar, ab : Integer;
	sk, ek : Double;
	tick_s, tick_t : Cardinal;
	t : Double;
	y_ofs : Integer;
var
	cbl, cbr : Integer;
begin
	//
	al := Min (sl, el);
	at := Min (st, et);
	ar := Max (sr, er);
	ab := Max (sb, eb);
	//SetWindowPos (Handle, 0, al, at, ar-al, ab-at, SWP_NOZORDER Or SWP_NOACTIVATE);
	Left := al;
	Top := at;
	Width := ar-al;
	Height := ab-at;
	dec (sl, al); dec (st, at); dec (sr, al); dec (sb, at);
	dec (el, al); dec (et, at); dec (er, al); dec (eb, at);
	//

  y1:=0.047425873;//1-1/(1+exp(-3));
  y2:=0.952574126;//1-1/(1+exp(3));
  h:=(et-st);//total height
  w1:=round(abs(sl-el));   //left width
  w2:=round(abs(sr-er));   //right width
  bmp:=tbitmap.Create;
  bmp.Height:=h;
  bmp.Width:=w1;
  bmp.Canvas.StretchDraw(rect(0,0,w1,h),pbmp^);//image1.Picture.Graphic);

  bmpout:=tbitmap.Create;
  bmpout.Height:=sr-sl;
  bmpout.Width:=w1;
  bmpout.Canvas.StretchDraw(rect(0,0,w1,sr-sl),pbmp^);//image1.Picture.Graphic);

  buffer:=tbitmap.Create;
  //buffer.Height:=canvas.ClipRect.Bottom-canvas.ClipRect.Top;
  //buffer.Width:=canvas.ClipRect.Right-canvas.ClipRect.Left;
  buffer.Height := ab - at;
  buffer.Width := ar - al;
  //buffer.Canvas.Brush.Color:=clFuchsia;
  //buffer.Canvas.FillRect(buffer.Canvas.ClipRect);

  // Force all bitmaps to 32 bits
  pbmp^.PixelFormat := pf32bit;
  bmp.PixelFormat := pf32bit;
  buffer.PixelFormat := pf32bit;
  bmpout.PixelFormat := pf32bit;

  // Bordes... de otra manera. ~Matonga
  For i := st To et do
  begin
	sk := -Cos((et - i) / (et - st) * PI)*0.5+0.5;
	ek := 1.0 - sk;

	bl[i] := Round(sl * sk + el * ek);
	br[i] := Round(sr * sk + er * ek);
  end;

  //Animamos el encogido
  (*
  m1:=sl;
  m2:=sr;
  while (abs(m1-el)>STEP) or (abs(m2-er)>STEP) do
  begin
	//limpiamos el buffer
	{$IFDEF USE_STRETCHBLT}
	buffer.Canvas.FillRect(buffer.Canvas.ClipRect);
	{$ELSE}
	For i := 0 To buffer.Height-1 do
		FillRGB32 (buffer.Scanline[i]^, buffer.Width);
	{$ENDIF}

	for i:=0 to pbmp^.Height-1 do
	begin
	  x:=i*6/h-3;//pbmp^.Height-3;
	  y:=1-1/(1+exp(x));
	  ya:=(y-y1)/(y2-y1);
	  if m1<el then
		l[i]:=sl+round(ya*round(abs(m1-sl)))
	  else
		l[i]:=sl-round(ya*round(abs(m1-sl)));
	  if m2<er then
		r[i]:=sr+round(ya*round(abs(m2-sr)))
	  else
		r[i]:=sr-round(ya*round(abs(m2-sr)));
	  //dibujamos linea por linea
	  {$IFDEF USE_STRETCHBLT}
	  StretchBlt(buffer.Canvas.Handle,
		l[i],
		st+i,
		r[i]-l[i],1,
		pbmp^.Canvas.Handle,0,i,pbmp^.Width,1,SRCCOPY);
	  {$ELSE}
	  If (st+i >= 0) And (st+i < buffer.Height) And
		 (i >= 0) And (i < pbmp^.Height) Then
		LineBlit (pbmp^.Scanline[i], buffer.Scanline[st+i], pbmp^.Width, buffer.Width, l[i], r[i]-l[i]);
	  {$ENDIF}
	end;
	//canvas.CopyRect(clientrect,buffer.Canvas,clientrect);
	LWSetImage (self, buffer);
	Application.ProcessMessages;
	//reducimos el tamanio
	if abs(m1-el)>STEP then
	begin
	  if m1>el then m1:=m1-STEP;
	  if m1<el then m1:=m1+STEP;
	end
	else
	begin
	  if m1>el then m1:=m1-1;
	  if m1<el then m1:=m1+1;
	end;

	if abs(m2-er)>STEP then
	begin
	  if m2>er then m2:=m2-STEP;
	  if m2<er then m2:=m2+STEP;
	end
	else
	begin
	  if m2>er then m2:=m2-1;
	  if m2<er then m2:=m2+1;
	end;
  end;
  {primero recolectamos la forma en un array}
  for i:=0 to h-1 do
  begin
	x:=i*6/h-3;
	y:=1-1/(1+exp(x));
	ya:=(y-y1)/(y2-y1);
	if sl<el then
	  l[h-i]:=el-round(ya*w1)
	else
	  l[h-i]:=el+round(ya*w1);
	if sr<er then
	  r[h-i]:=er-round(ya*w2)
	else
	  r[h-i]:=er+round(ya*w2);
  end;
  *)

  tick_s := GetTickCount;
  tick_t := DURATION div 4;
  While True do
  begin
	t := (GetTickCount - tick_s) / tick_t;
	If t > 1.0 Then Break;
	For i := 0 To buffer.Height-1 do
		FillRGB32 (buffer.Scanline[i]^, buffer.Width);
	sk := Cos(t * PI)*0.5+0.5;
	ek := 1.0 - sk;
	For j := 0 To pbmp^.Height-1 do
	begin
		cbl := Round(sl * sk + bl[j+st] * ek);
		cbr := Round(sr * sk + br[j+st] * ek);
		If (st+j >= 0) And (st+j < buffer.Height) Then
		begin
			LineBlit (pbmp^.Scanline[j], buffer.Scanline[st+j], pbmp^.Width, buffer.Width, cbl, cbr-cbl);
		end;
	end;
	LWSetImage (self, buffer);
  end;

  {ahora dibujamos frames de bajada}
  (*
  j:=h-1;
  while j>=0 do
  begin
	j:=j-STEP;
	//limpiamos el buffer
	{$IFDEF USE_STRETCHBLT}
	buffer.Canvas.FillRect(buffer.Canvas.ClipRect);
	{$ELSE}
	For i := 0 To buffer.Height-1 do
		FillRGB32 (buffer.Scanline[i]^, buffer.Width);
	{$ENDIF}
	//dibujamos linea por linea
	for i:=0 to j-1 do
	begin
	  {$IFDEF USE_STRETCHBLT}
	  StretchBlt(buffer.Canvas.Handle,
		l[i+h-j],st+i+h-j,r[i+h-j]-l[i+h-j],1,
		bmp.Canvas.Handle,0,i,bmp.Width,1,SRCCOPY);
	  {$ELSE}
		If (st+i+h-j >= 0) And (st+i+h-j < buffer.Height) And
			(i >= 0) And (i < bmp.Height) Then
			LineBlit (bmp.Scanline[i], buffer.Scanline[st+i+h-j], bmp.Width, buffer.Width, l[i+h-j], r[i+h-j]-l[i+h-j]);
	  {$ENDIF}
	end;
	//canvas.CopyRect(clientrect,buffer.Canvas,clientrect);
	LWSetImage (self, buffer);
	Application.ProcessMessages;
  end;
  *)

  inc (tick_s, tick_t);
  tick_t := DURATION *3 div 4;
  While True do
  begin
	t := (GetTickCount - tick_s) / tick_t;
	If t > 1.0 Then Break;
	For i := 0 To buffer.Height-1 do
		FillRGB32 (buffer.Scanline[i]^, buffer.Width);
	y_ofs := st + Round((et-st)*t);
	For j := 0 To pbmp^.Height-1 do
		If (y_ofs+j >= st) And (y_ofs+j < et) And
		   (y_ofs+j >= 0) And (y_ofs+j < buffer.Height) Then
		begin
			LineBlit (pbmp^.Scanline[j], buffer.Scanline[y_ofs+j], pbmp^.Width, buffer.Width, bl[y_ofs+j], br[y_ofs+j]-bl[y_ofs+j]);
		end;
	LWSetImage (self, buffer);
  end;

  bmpout.free;
  buffer.Free;
  bmp.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
	(*
  DoubleBuffered:=True;
  //Application.ShowMainForm:=false;
  ShowWindow(Handle, SW_HIDE);
  SetWindowLong(Handle, GWL_EXSTYLE, getWindowLong(Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
  ShowWindow(Handle, SW_SHOW);
  BorderStyle:=bsNone;
  //WindowState:=wsMaximized;
  Height:=screen.Height;
  Width:=screen.Width;
  SetWindowLong(handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) Or WS_EX_LAYERED);
  SetLayeredWindowAttributes(Handle,$0ff00ff, 0, ULW_COLORKEY);
  SetWindowLong(Handle, GWL_STYLE, GetWindowLong(handle, GWL_STYLE) And Not WS_BORDER);
  *)
  SetWindowLong(Handle, GWL_EXSTYLE, (getWindowLong(Handle, GWL_EXSTYLE) And Not WS_EX_APPWINDOW) or WS_EX_TOOLWINDOW);
  LWSetupForm (self);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action:=caFree;
end;

end.


Posted Image

Edit

ABlit routine was not working, but now I found mistake, here is corrected version:

procedure ABlit (src, dst : Pointer; count, src_ini, src_inc : Cardinal); stdcall; assembler;
asm
	push eax
	push ebx
	push ecx
	push edx
	push esi
	push edi

	mov esi, src
	mov edi, dst
	mov ecx, count
	mov edx, src_ini

	@loop:
	mov ebx, edx
	shr ebx, 8
	add edx, src_inc
	mov eax, [esi+ebx*4]
	or  eax, $FF000000
	mov [edi], eax
	dec ecx
	lea edi, [edi+4]
	jnz @loop

	pop edi
	pop esi
	pop edx
	pop ecx
	pop ebx
	pop eax
end;

procedure LineBlit (src, dst : PRGB32Array; src_scanline_width, dst_scanline_width, dst_x, dst_width : Integer);
var
	src_p, src_i{, x} : Integer;
begin
	If dst_width = 0 Then Exit;
	src_p := 0;
	src_i := 256 * src_scanline_width div dst_width;
	// frustrum culling
	If dst_x + dst_width <= 0 Then Exit;
	If dst_x >= dst_scanline_width Then Exit;
	// clipping
	If dst_x + dst_width >= dst_scanline_width Then
		dst_width := dst_scanline_width - dst_x;
	If dst_x < 0 Then
	begin
		inc (src_p, src_i * (-dst_x));
		dst_x := 0;
	end;
	// blitting
	(*For x := 0 To dst_width-1 do
	begin
		dst[dst_x + x] := src[src_p div 256] Or $FF000000;
		inc (src_p, src_i);
	end;*)
	ABlit (src, Pointer(Integer(dst)+dst_x*4), dst_width, src_p, src_i);
	//ABlit (src, dst, dst_width, 0, 256);
end;


I think it can be made even faster, somehow...

Posted Image

Edit

Ok, maybe faster: (should do a benchmark)

procedure ABlit (src, dst : Pointer; count, src_ini, src_inc : Cardinal); stdcall; assembler;
asm
	push eax
	push ebx
	push ecx
	push edx
	push esi
	push edi

	mov esi, src
	mov edi, dst
	mov ecx, count

	mov edx, src_inc
	ror edx, 16
	mov src_inc, edx

	mov edx, src_ini
	ror edx, 16

	sub ebx, ebx

	@loop:
	mov bx, dx
	add edx, src_inc
	mov eax, [esi+ebx*4]
	adc edx, 0
	or  eax, $FF000000
	mov [edi], eax
	dec ecx
	lea edi, [edi+4]
	jnz @loop

	pop edi
	pop esi
	pop edx
	pop ecx
	pop ebx
	pop eax
end;

procedure LineBlit (src, dst : PRGB32Array; src_scanline_width, dst_scanline_width, dst_x, dst_width : Integer);
var
	src_p, src_i : Integer;
begin
	If dst_width = 0 Then Exit;
	src_p := 0;
	src_i := 65536 * src_scanline_width div dst_width;
	// frustrum culling
	If dst_x + dst_width <= 0 Then Exit;
	If dst_x >= dst_scanline_width Then Exit;
	// clipping
	If dst_x + dst_width >= dst_scanline_width Then
		dst_width := dst_scanline_width - dst_x;
	If dst_x < 0 Then
	begin
		inc (src_p, src_i * (-dst_x));
		dst_x := 0;
	end;
	// blitting
	ABlit (src, Pointer(Integer(dst)+dst_x*4), dst_width, src_p, src_i);
end;


Posted Image

Edit

Ok, made a lot of code cleanup and uploaded at File2Go:

http://www.file2go.net/view/7d6b30cdea

Edit

Forgot to mention: the version I uploaded to File2Go uses HBITMAP instead of ^TBitmap. This is *a lot* more compatible with other programming languages and other versions of Delphi.
0

#5 User is offline   vhanla Icon

  • Group: Member
  • Posts: 48
  • Joined: 15-June 08

Posted 04 June 2009 - 10:48 PM

Wow! Matonga, this is awesome, it's even faster than RKGenieEffectDX animation.

I've seen some crashes, I suppose it is due to starting bottom is greater than ending bottom, a minor problem.

Some ideas:
- It can have a different ending, for example, animate as a sand clock for fill a docklet
- warp animation at ending
- the limit is your imagination.
___________________________________________________
BTW: Here goes the Dock sample that uses this library, it is just a mess code, I do this for fun

Source Code included, so anyone can improve, port to other languages, etc...
Attached File  XDock.zip (596.8K)
Number of downloads: 39
0

#6 User is offline   vigil Icon

  • Group: Member
  • Posts: 17
  • Joined: 02-November 08

Posted 05 June 2009 - 03:07 AM

Thank you for sharing such amazing source codes, both of you.
I've seen Stardock's WindowFX has many other animations, maybe that library could have a bunch of different animations...
Though I'm not good at programming, but just some ideas.

BTW Systray doesn't work correctly on Vista 64bits, but on my XP pc works great. Hey vhanla, you could add that to that dock.
0

#7 User is offline   vhanla Icon

  • Group: Member
  • Posts: 48
  • Joined: 15-June 08

Posted 05 June 2009 - 03:16 AM

View Postvigil, on Jun 4th 2009, 10:07 PM, said:

Thank you for sharing such amazing source codes, both of you.


Actually the latest Library (geniefx) was completely rewritten by Matonga, so the author becomes him, I gave an idea, tried to make it, but very slow.

View Postvigil, on Jun 4th 2009, 10:07 PM, said:

BTW Systray doesn't work correctly on Vista 64bits, but on my XP pc works great. Hey vhanla, you could add that to that dock.


That's from my XWD Systray Docklet, I can't test on Vista 64bit, because I don't have it (OS and Hardware).
0

#8 User is offline   matonga Icon

  • Group: Developers
  • Posts: 1,286
  • Joined: 04-September 06

Posted 05 June 2009 - 12:26 PM

Ok, now it works when picture's bottom border is below the top border of destination (for e.g. Button1 in demo program, if you move it above the picture's bottom border). What does it do? the picture moves upwards while it's bottom border shrinks, it moves up to making bottom border coincide with button's top border (destination top border). This is exactly what Mac OS X does too.

I'll post changes here, because I want to add the other three directions too. :) And BTW it seems I ignored sb at all, so original picture's height is used at all times :P sorry.
0

#9 User is offline   Ghostwalker Icon

  • Group: Member
  • Posts: 1,990
  • Joined: 05-March 03

Posted 05 June 2009 - 04:37 PM

Man you guys this is cool,vHanla works with dual monitors also. Looked cool having the genie effect pull the window from one monitor to the dock on the other monitor.
0

#10 User is offline   vhanla Icon

  • Group: Member
  • Posts: 48
  • Joined: 15-June 08

Posted 05 June 2009 - 05:01 PM

Some other projects about genie effect
this is with Qt4
http://labs.trolltec...12/15/genie-fx/
and this other one with Flex
http://www.madeinflex.com/2008/01/29/efect...o-genie-effect/ (this one in spanish)

Maybe they're of someone's interest

BTW: I took code from the first one :P :P

EDIT

I don't know how you're dealing with the other directions.
I was trying to do the following:
1st make a copy of the bitmap but rotated 90º degrees and change coordinates of sl,sr,st,sb,el,er,et,eb
to match the rotation
2nd proceed normally and rotate back the modified buffer to show with LWSetImage
Maybe there is a better approach

procedure RoR(
		 src,dst: pointer;
		 step,
		 count,
		 starting:cardinal);stdcall;assembler;
asm
   pushad
   mov ecx, count
   mov edi, dst
   mov esi, src
   mov ebx, step
   dec ebx
   sub ebx, starting
   add ebx, ebx
   add ebx, ebx
   xor edx, edx  
   @lll:
   mov eax,[esi+edx]
   mov [edi+ebx],eax
   add ebx, step
   add ebx, step
   add ebx, step
   add ebx, step
   dec ecx
   add edx, 4
   cmp ecx,0
   jnz @lll
   popad
end;

procedure RoL(
		 src,dst: pointer;
		 step,
		 count,
		 starting:cardinal);stdcall;assembler;
asm
   pushad
   mov ecx, count
   mov edi, dst
   mov esi, src
   mov ebx, starting
   add ebx, ebx
   add ebx, ebx
   xor edx, edx 
   @lll:
   mov eax,[esi+edx]
   mov [edi+ebx],eax
   add ebx, step
   add ebx, step
   add ebx, step
   add ebx, step
   dec ecx
   add edx, 4
   cmp ecx,0
   jnz @lll
   popad
end;

procedure CopyBuffer(dst, src: pointer; count:cardinal);stdcall;assembler;
asm
   pushad
   cld
   mov ecx, count
   mov esi, src
   mov edi, dst
   rep movsd
   popad
end;


{
sl : start left
sr: start right
st: start top
sb: start bottom
el: end left
er: end right
et: end top
eb: end bottom
pgrap: pointer to bitmap

all relative to screen size
}

procedure TForm1.GenieFX(pbmp: pgrap;sl,sr,st,sb,el,er,et,eb:integer);
const
  DURATION = 1000;  // animation duration in milliseconds
var
  i, j : Integer;
  buffer,bmp, dmp:tbitmap;
  bl, br : array[0..5000] of Integer;   // bordes
	al, at, ar, ab : Integer;
	sk, ek : Double;
	tick_s, tick_t : Cardinal;
	t : Double;
	y_ofs : Integer;
	cbl, cbr : Integer;
  buf: pbyte;
begin
  //bmp is the manipulation buffer
  bmp:=tbitmap.create;
  bmp.PixelFormat:=pf32bit;
  dmp:=tbitmap.create;
  dmp.PixelFormat:=pf32bit;
  buffer:=tbitmap.Create;

  if (et>sb) then
  begin

	al := Min (sl, el);
	at := Min (st, et);
	ar := Max (sr, er);
	ab := Max (sb, eb);
	Left := al;
	Top := at;
	Width := ar-al;
	Height := ab-at;

	dec (sl, al); dec (st, at); dec (sr, al); dec (sb, at);
	dec (el, al); dec (et, at); dec (er, al); dec (eb, at);

	bmp.Height:=sb-st;
	bmp.Width:=sr-sl;

	bmp.Canvas.Draw(0,0,pbmp^);
	buffer.Height := ab - at;
	buffer.Width := ar - al;

	// Force all bitmaps to 32 bits
	pbmp^.PixelFormat := pf32bit;
	buffer.PixelFormat := pf32bit;

	// Bordes... de otra manera. ~Matonga
	For i := st To et do
	begin
	  sk := -Cos((et - i) / (et - st) * PI)*0.5+0.5;
	  ek := 1.0 - sk;

	  bl[i] := Round(sl * sk + el * ek);
	  br[i] := Round(sr * sk + er * ek);
	end;

	//Animamos el encogido

	tick_s := GetTickCount;
	tick_t := DURATION div 4;
	While True do
	begin
	  t := (GetTickCount - tick_s) / tick_t;
	  If t > 1.0 Then Break;
	  For i := 0 To buffer.Height-1 do
		FillRGB32 (buffer.Scanline[i]^, buffer.Width);
	  sk := Cos(t * PI)*0.5+0.5;
	  ek := 1.0 - sk;
	  For j := 0 To bmp.Height-1 do
	  begin
		cbl := Round(sl * sk + bl[j+st] * ek);
		cbr := Round(sr * sk + br[j+st] * ek);
		If (st+j >= 0) And (st+j < buffer.Height) Then
		begin
			LineBlit (bmp.Scanline[j], buffer.Scanline[st+j], bmp.Width, buffer.Width, cbl, cbr-cbl);
		end;
	  end;
	  LWSetImage (self, buffer);
	end;

	{ahora dibujamos frames de bajada}

	inc (tick_s, tick_t);
	tick_t := DURATION *3 div 4;
	While True do
	begin
	  t := (GetTickCount - tick_s) / tick_t;
	  If t > 1.0 Then Break;
	  For i := 0 To buffer.Height-1 do
		FillRGB32 (buffer.Scanline[i]^, buffer.Width);
	  y_ofs := st + Round((et-st)*t);
	  For j := 0 To bmp.Height-1 do
		If (y_ofs+j >= st) And (y_ofs+j < et) And
		   (y_ofs+j >= 0) And (y_ofs+j < buffer.Height) Then
		begin
			LineBlit (bmp.Scanline[j], buffer.Scanline[y_ofs+j], bmp.Width, buffer.Width, bl[y_ofs+j], br[y_ofs+j]-bl[y_ofs+j]);
		end;
	  LWSetImage (self, buffer);
	end;
	
  end
/////////////////////////////// LEFT ////////////////////////////////////////////
  else if (er<sl)
  and (et<sb) then
  begin //animate to left
	//so we need to make it relative to the rotation
	Left := el;
	i:=eb;
	eb:=screen.Width-el;
	el:=et;
	et:=screen.Width-er;
	er:=i;
	i:=sb;
	sb:=screen.Width-sl;
	sl:=st;
	st:=screen.Width-sr;
	sr:=i;
	
	al := Min (sl, el);
	at := Min (st, et);
	ar := Max (sr, er);
	ab := Max (sb, eb);
	
	Top := al;
	Width := ab-at;
	Height := ar-al;
	
	dec (sl, al); dec (st, at); dec (sr, al); dec (sb, at);
	dec (el, al); dec (et, at); dec (er, al); dec (eb, at);
	
	bmp.Height:=sb-st;
	bmp.Width:=sr-sl;

	buffer.Height := ab - at;
	buffer.Width := ar - al;
	// Force all bitmaps to 32 bits
	pbmp^.PixelFormat := pf32bit;
	buffer.PixelFormat := pf32bit;

	dmp.Height:=buffer.Width;
	dmp.Width:=buffer.Height;

	GetMem(buf,dmp.width*dmp.Height*4);
	// rotamos la imagen /rotate image
	for i:=0 to pbmp^.Height-1 do
	  RoL(pbmp^.ScanLine[i],buf,pbmp^.Height,pbmp^.Width,i);
	for i:=0 to bmp.Height-1 do
	  CopyBuffer(bmp.scanline[i],pointer(integer(buf)+i*bmp.Width*4),bmp.width);

	// Bordes... de otra manera. ~Matonga
	For i := st To et do
	begin
	  sk := -Cos((et - i) / (et - st) * PI)*0.5+0.5;
	  ek := 1.0 - sk;

	  bl[i] := Round(sl * sk + el * ek);
	  br[i] := Round(sr * sk + er * ek);
	end;

	//Animamos el encogido

	tick_s := GetTickCount;
	tick_t := DURATION div 4;
	While True do
	begin
	  t := (GetTickCount - tick_s) / tick_t;
	  If t > 1.0 Then Break;
	  For i := 0 To buffer.Height-1 do
		FillRGB32 (buffer.Scanline[i]^, buffer.Width);
	  sk := Cos(t * PI)*0.5+0.5;
	  ek := 1.0 - sk;
	  For j := 0 To bmp.Height-1 do
	  begin
		cbl := Round(sl * sk + bl[j+st] * ek);
		cbr := Round(sr * sk + br[j+st] * ek);
		If (st+j >= 0) And (st+j < buffer.Height) Then
		begin
			LineBlit (bmp.Scanline[j], buffer.Scanline[st+j], bmp.Width, buffer.Width, cbl, cbr-cbl);
		end;
	  end;
	  // rotamos la imagen
	  for i:=0 to buffer.Height-1 do
		RoR(buffer.ScanLine[i],buf,buffer.Height,buffer.Width,i);
	  for i:=0 to dmp.Height-1 do
		CopyBuffer(dmp.scanline[i],pointer(integer(buf)+i*dmp.Width*4),dmp.width);

	  LWSetImage (self, dmp);
	end;

	{ahora dibujamos frames de bajada}

	inc (tick_s, tick_t);
	tick_t := DURATION *3 div 4;
	While True do
	begin
	  t := (GetTickCount - tick_s) / tick_t;
	  If t > 1.0 Then Break;
	  For i := 0 To buffer.Height-1 do
		FillRGB32 (buffer.Scanline[i]^, buffer.Width);
	  y_ofs := st + Round((et-st)*t);
	  For j := 0 To bmp.Height-1 do
		If (y_ofs+j >= st) And (y_ofs+j < et) And
		   (y_ofs+j >= 0) And (y_ofs+j < buffer.Height) Then
		begin
			LineBlit (bmp.Scanline[j], buffer.Scanline[y_ofs+j], bmp.Width, buffer.Width, bl[y_ofs+j], br[y_ofs+j]-bl[y_ofs+j]);
		end;
	  // rotamos la imagen
	  for i:=0 to buffer.Height-1 do
		RoR(buffer.ScanLine[i],buf,buffer.Height,buffer.Width,i);
	  for i:=0 to dmp.Height-1 do
		CopyBuffer(dmp.scanline[i],pointer(integer(buf)+i*dmp.Width*4),dmp.width);

	  LWSetImage (self, dmp);
	end;
	
	freemem(buf);

  end
  else if (el>sr) and
	(et<sb) then
  begin 
	// animate to right
  end
  else if eb<st then
  begin 
	//animate to top
  end
  else
  begin
	//??
  end;
  bmp.free;
  dmp.free;
  buffer.Free;

end;

Attached File  geniefxlibLeft_Bottom.zip (408.01K)
Number of downloads: 21

BTW: How can it be possible to animate many at the same time?
Like this video shows http://is.gd/WhrF

EDIT
Ha ha ha, I didn't notice the picture mirrored, to fix that, after RoL call
it should be
CopyBuffer(bmp.scanline[bmp.Height-1-i],pointer(integer(buf)+i*bmp.Width*4),bmp.width);


EDIT
(Back home after a bored day at the university) I forgot to upload this four side animation approach I did this morning
Attached File  geniefxlib3.zip (410.14K)
Number of downloads: 40

This post has been edited by vhanla: 11 June 2009 - 01:03 AM

0

#11 User is offline   vhanla Icon

  • Group: Member
  • Posts: 48
  • Joined: 15-June 08

Posted 24 June 2009 - 04:37 PM

Hi, I did a minmax hook to apply GenieFXLib and it works.

However, there are some applications I like, that restores and minimizes some applications, for example, WinExposé (it does that to minimized windows) among others.
And when this happens the hook does what it is meant to do (in this case, it interferes).

1:
I guess those windows are with alpha set to 0 and restored, so I need to find out that in order to not apply the effect, and some other Layered windows, because some of them have their rect different and since PrintWindow returns blank I think a bitblt screenshot must be done.

2:
In GenieFXLib I'm trying to replace the original window by hiding it and showing the effect window, but I've seen it occurs a little blink, I guess I have to first put the replacement over it and hide the original after that. But I couldn't do that and what I tried to do is to change the alpha (not minimize because my hook triggers again) to 0 of the window for example after the shrinking animation (before the minimization animation) and it doesn't work. I found that after modifying the width of the effect window on geniefx procedure, changing another window's alpha value doesn't work. I don't know why.

Edit
This was tested on XP only. http://codigobit.net...load/TaskFX.zip

This post has been edited by vhanla: 27 June 2009 - 02:29 AM

0

#12 User is offline   matonga Icon

  • Group: Developers
  • Posts: 1,286
  • Joined: 04-September 06

Posted 30 June 2009 - 06:13 PM

Wow, the TaskFX thing looks great!

For TaskFX and WinExpose to work together, I think you can do a pretty nasty hack:

- Find the PID for any process called WinExpose.exe
- Find a window whose class is TForm1, belonging to such PID.
- Check if such window has X position = 0. If this is the case, then don't apply the effect.

However it would be much better for both TaskFX & WinExpose (and other FX apps too) to use a common library for such stuff. Someone at Aqua-Soft will finally have to write it, maybe based on Compiz-Fusion architecture or whatever.

To avoid the flicker, you should print the window (PrintWindow) then create & show the effect window above the original window, with the contents of the original window pre-rendered into it, then hide the original window (all in this exact order). Of course this means you can't just use the .dll as it was written and you'll have to modify it (at least adding a callback in the animation procedure, it would suffice with just that).

I'm not sure if the above paragraph is barely understandable for english speakers, please forgive me I'm just out from job. I'll review all this... later.
0

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic