Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-11-2022
aposi aposi is offline
Miembro
 
Registrado: dic 2006
Posts: 146
Poder: 18
aposi Va por buen camino
Has mirado si Formaprincipal esta creado y te retorna la ruta de gif?
Responder Con Cita
  #2  
Antiguo 18-11-2022
Avatar de pgranados
pgranados pgranados is offline
Miembro
 
Registrado: sep 2022
Ubicación: México
Posts: 264
Poder: 2
pgranados Va por buen camino
Cita:
Empezado por aposi Ver Mensaje
Has mirado si Formaprincipal esta creado y te retorna la ruta de gif?
Sí, de hecho si se muestra en la forma y todo, pero se visualiza como si fuera un JPG o PNG, sin movimiento, pero al terminar la función del clic y mostrar el mensaje de procedimiento terminado, empieza la animación del gif por así decirlo.
Responder Con Cita
  #3  
Antiguo 18-11-2022
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.044
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
¿Qué componente usas para el gif?
Responder Con Cita
  #4  
Antiguo 18-11-2022
Avatar de pgranados
pgranados pgranados is offline
Miembro
 
Registrado: sep 2022
Ubicación: México
Posts: 264
Poder: 2
pgranados Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
¿Qué componente usas para el gif?
TImage, saludos.
Responder Con Cita
  #5  
Antiguo 18-11-2022
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.044
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Prueba:
Código Delphi [-]
(Image1.Picture.Graphic as TGifImage).AnimationSpeed:= 1000;
Application.ProcessMessages;
¿Y cuánto dura la tarea que se procesa? a ver si es que dura tan poco que no da tiempo a mostrar el gif.
Yo suelo usar TRxGIFAnimator de las RXlib.
Responder Con Cita
  #6  
Antiguo 18-11-2022
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Quizás tengas que usar un thread separado para mostrar tu gif animado. Si se está ejecutando una tarea el control del programa no pasa al gif hasta que termine. Es por eso que debes usar un hilo separado.

Saludos
Responder Con Cita
  #7  
Antiguo 18-11-2022
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Ya hace unos años que escribí una clase para visualizar un GIF en cualquier ventana, sin componentes y usando un thread. Usa GDI plus , puede cargar el gif desde un archivo o desde un recurso del ejecutable y la diseñé precisamente para independizar el movimiento del gif a las tareas de la aplicación. La publiqué aquí: New GifViewer, versión GDI+ polivalente


Posteriormente hice algún cambio el la versión para C++ para incorporarla a una aplicación precisamente mostrando un "gif de espera" mientras realizaba una tarea. Nunca publiqué los últimos cambios y acabo de adaptarlo a la versión delphi tras la lectura de este hilo. Supongo que puede servir como respuesta, así que publico la última versión de la clase.


Código Delphi [-]
unit _GifViewer;

//------------------------------------------------------------------------------
// GifViewer V 3.2
// escafandra 2018 - 2022
// Clase para representar un gif estático o animado sobre cualquier ventana.
// Usa GDI+
//
// V 3.0:
//   Se añade la carga de GIF desde Resources incrustados como RT_RCDATA
//   Se añade la posibilidad de centrar la imagen
//------------------------------------------------------------------------------


interface

uses Windows, Messages, ActiveX;

//function SetWindowLongPtr(hWnd: HWND; nIndex: Integer; dwNewLong: Pointer): Pointer; stdcall external 'user32';
function GdiplusStartup(var GdiToken: DWORD; Startup, Output: PBYTE): DWORD; stdcall external 'gdiplus';
function GdipLoadImageFromFile(lpFileName: PWideChar; var hImage: THANDLE): DWORD; stdcall external 'gdiplus';
function GdipLoadImageFromStream(pStream: IStream; var hImage: THANDLE): DWORD; stdcall external 'gdiplus';
function GdipDrawImageRectI(hGraphics, hImage: THANDLE; Left, Top, Width, Height: Integer): DWORD; stdcall external 'gdiplus';
function GdipCreateFromHDC(DC: HDC; var hGraphics: THANDLE): DWORD; stdcall external 'gdiplus';
function GdipImageSelectActiveFrame(hImage: THANDLE; DimensionID: PGUID; frameIndex: Integer): DWORD; stdcall external 'gdiplus';
function GdipImageGetFrameDimensionsList(hImage: THANDLE; dimensionIDs: PGUID; Count: Integer): DWORD; stdcall external 'gdiplus';
function GdipGetPropertyItemSize(hImage: THANDLE; dwPropId: Integer; var Size: UINT): Integer; stdcall external 'gdiplus';
function GdipGetPropertyItem(hImage: THANDLE; dwPropID, Size: Integer; lpBuffer: Pointer): DWORD; stdcall external 'gdiplus';
function GdipImageGetFrameCount(hImage: THANDLE; lpDimensionID: PGUID; out Count: UINT): DWORD; stdcall external 'gdiplus';
function GdipGetImageWidth(hImage: THANDLE; var Width: UINT): DWORD; stdcall external 'gdiplus';
function GdipGetImageHeight(hImage: THANDLE; var Height: UINT): DWORD; stdcall external 'gdiplus';
function GdipDeleteGraphics(hGraphics: THANDLE): DWORD; stdcall external 'gdiplus';
function GdipDisposeImage(hImage: THANDLE): DWORD; stdcall external 'gdiplus';
procedure GdiplusShutdown(GdiToken: DWORD); stdcall external 'gdiplus';

function SHCreateMemStream(pInit: PBYTE; cbInit: DWORD): Pointer; stdcall external 'shlwapi';

type
TGifViewer = class
  private
    Wnd: HWND;
    OldWndProc: Pointer;
    OldUserData: DWORD;
    gdiplusToken: DWORD;
    hThread: THANDLE;
    hGdipImage: THANDLE;
    Width:  integer;
    Height: integer;
    Frames: UINT;
    function WndProc(Handle: HWND; Msg: DWORD; WParam: DWORD; LParam: DWORD): DWORD; stdcall;

  public
    Center:   boolean;
    Left:     integer;
    Top:      integer;
    function  GifView(Handle: HWND; FileName: PWCHAR; VCenter: boolean = false): boolean;
    function  GifViewFromResource(Handle: HWND; ID_GIF: PWCHAR; VCenter: boolean = false): boolean;
    function  SetHandle(Handle: THANDLE): boolean;
    function  LoadFile(FileName: PWCHAR): boolean;
    function  LoadFromResource(ID_GIF: PWCHAR): boolean;
    function  GetWidth:  integer;
    function  GetHeight: integer;
    function  GetFrames: UINT;
    function  Start: boolean;
    procedure Finish;

    constructor Create;
    destructor Destroy; override;
end;
PGifViewer = ^TGifViewer;

TPropertyItem = record
  id:        ULONG;
  length: ULONG;
  _type:  WORD;
  value:  Pointer;
end;
PPropertyItem = ^TPropertyItem;

const
  PropertyTagFrameDelay = $5100;
var
  GDI:    DWORD = 0;
  hEvent: THandle = 0;


implementation

function RePaintWindow(Wnd: HWND): boolean;
var
  Rect: TRect;
begin
  GetClientRect(Wnd, Rect);
  Result:= RedrawWindow(Wnd, @Rect, 0, RDW_INVALIDATE or RDW_ERASE or RDW_UPDATENOW or RDW_ALLCHILDREN);
end;

function ThGif(GV: TGifViewer): DWORD; stdcall;
var
  Wait:     PIntegerArray;
  Pi:       PPropertyItem;
  DC:       HDC;
  EvResult: DWORD;
  hGdipGraphics: THANDLE;
  nBytes, Frames, Index: UINT;
  FrameDimensionTime: TGUID;
  Left, Top: integer;
  CR: TRect;
begin
  Left:= GV.Left;
  Top:= GV.Top;

  // Esperamos a que se pinte una ventana WM_PAINT
  if hEvent <> 0 then EvResult:= WaitForSingleObject(hEvent, INFINITE);

  if (GV.hGdipImage <> 0) and (GV.Wnd <> 0) AND (EvResult = WAIT_OBJECT_0) then
  begin
    GdipGetPropertyItemSize(GV.hGdipImage, PropertyTagFrameDelay, nBytes);
    Pi:= Pointer(LocalAlloc(LMEM_FIXED, nBytes));
    GdipGetPropertyItem(GV.hGdipImage, PropertyTagFrameDelay, nBytes, Pi);
    GdipImageGetFrameDimensionsList(GV.hGdipImage, @FrameDimensionTime, 1);
    GdipImageGetFrameCount(GV.hGdipImage, @FrameDimensionTime, Frames);

    Index:= 0;
    Wait:= PIntegerArray(Pi.value);
    if Pi._type = sizeof(DWORD) then
    repeat
      if GV.Center then
      begin
        GetClientRect(GV.Wnd, CR);
        Left:= (CR.right  - GV.Width) div 2;
        Top:= (CR.bottom - GV.Height) div 2;
      end;
      DC:= GetDC(GV.Wnd);
      GdipCreateFromHDC(DC, hGdipGraphics);
      GdipImageSelectActiveFrame(GV.hGdipImage, @FrameDimensionTime, Index);
      GdipDrawImageRectI(hGdipGraphics, GV.hGdipImage, Left, Top, GV.Width, GV.Height);
      GdipDeleteGraphics(hGdipGraphics);
      ReleaseDC(GV.Wnd, DC);
      Sleep(Wait[Index] * 10);
      Index:= (Index + 1) mod Frames;
    until (GV.Wnd = 0) or (GV.hGdipImage = 0);
  end;
  LocalFree(HLOCAL(Pi));
  Result:= 0;
end;

function DefWndProc(Handle: HWND; Msg: DWORD; WParam: DWORD; LParam: DWORD): DWORD; stdcall;
var
  pGifViewer: TGifViewer;
begin
//  if (Msg = WM_PAINT) and (hEvent <> 0) then SetEvent(hEvent);  // Pemitimos que arranque el Thread

  pGifViewer:= TGifViewer(GetWindowLong(Handle, GWL_USERDATA));
  if pGifViewer <> nil then
  begin
    // Pemitimos que arranque el Thread si la ventana va a ser visible
    if ((Msg = WM_PAINT) or (Msg = WM_SHOWWINDOW)) and (hEvent <> 0) then
      SetEvent(hEvent);
    Result:= pGifViewer.WndProc(Handle, Msg, WParam, LParam)
  end
  else
    Result:= DefWindowProc(Handle, Msg, WParam, LParam);
end;

function TGifViewer.WndProc(Handle: HWND; Msg: DWORD; WParam: DWORD; LParam: DWORD): DWORD; stdcall;
var
  R: TRect;
begin
  R.Left:= Left; R.Top:= Top; R.Right:= Left+Width; R.Bottom:= Top+Height;
  if (Msg = WM_PAINT) and (hGdipImage <> 0) then
    ValidateRect(Wnd, @R)
  else if (Msg = WM_SIZE) and (hGdipImage <> 0) and Center then
  begin
    InvalidateRect(Wnd, @R, true);
    CallWindowProc(OldWndProc, Wnd, WM_PAINT, 0, 0);
  end;
  Result:= CallWindowProc(OldWndProc, Handle, Msg, WParam, LParam);
end;

function TGifViewer.SetHandle(Handle: THANDLE): boolean;
begin
  Result:= false;
  if(Pointer(GetWindowLong(Handle, GWL_WNDPROC)) <> @DefWndProc) then
  begin
    SuspendThread(hThread);
    if (Wnd <> 0) then
    begin
      SetWindowLong(Wnd, GWL_USERDATA, OldUserData);
      SetWindowLong(Wnd, GWL_WNDPROC, LongInt(OldWndProc));
      RePaintWindow(Wnd);
      Wnd:= 0;
    end;

    if (Handle <> 0) and IsWindow(Handle) then
    begin
      Wnd:= Handle;
      OldUserData:= SetWindowLong(Wnd, GWL_USERDATA, LongInt(self));
      OldWndProc:= Pointer(SetWindowLong(Wnd, GWL_WNDPROC, LongInt(@DefWndProc)));
      RePaintWindow(Wnd);
    end;
    Result:= true;
    ResumeThread(hThread);
  end;
end;

function TGifViewer.LoadFile(FileName: PWCHAR): boolean;
var
  FrameDimensionTime: TGUID;
begin
  Finish;
  if GdipLoadImageFromFile(FileName, hGdipImage) = 0 then
  begin
    GdipGetImageWidth(hGdipImage, UINT(Width));
    GdipGetImageHeight(hGdipImage, UINT(Height));
    GdipImageGetFrameDimensionsList(hGdipImage, @FrameDimensionTime, 1);
    GdipImageGetFrameCount(hGdipImage, @FrameDimensionTime, UINT(Frames));
  end
  else hGdipImage:= 0;

  Result:= hGdipImage <> 0;
end;

function TGifViewer.LoadFromResource(ID_GIF: PWCHAR): boolean;
const
  RT_RCDATAW: PWCHAR = MakeIntResourceW(10);
var
  FrameDimensionTime: TGUID;
  Res: HRSRC;
  ResSize: DWORD;
  ResData: HGLOBAL;
  Stream: IStream;
begin
  Finish;
  Res:= FindResourceW(0, ID_GIF, RT_RCDATAW);
  if Res <> 0 then
  begin
    ResSize:= SizeofResource(0, Res);
    ResData:= LoadResource(0, Res);
    Stream:= IStream(SHCreateMemStream(PBYTE(LockResource(ResData)), ResSize));
    if GdipLoadImageFromStream(Stream, hGdipImage) = 0 then
    begin
         GdipGetImageWidth(hGdipImage, UINT(Width));
      GdipGetImageHeight(hGdipImage, UINT(Height));
        GdipImageGetFrameCount(hGdipImage, @FrameDimensionTime, UINT(Frames));
    end
    else hGdipImage:= 0;
    Stream._Release;
  end;
  Result:= hGdipImage <> 0;
end;

function TGifViewer.GifView(Handle: HWND; FileName: PWCHAR; VCenter: boolean): boolean;
begin
  Finish;
  LoadFile(FileName);
  SetHandle(Handle);
  Center:= VCenter;
  Result:= Start;
end;

function TGifViewer.GifViewFromResource(Handle: HWND; ID_GIF: PWCHAR; VCenter: boolean): boolean;
begin
  Finish;
  LoadFromResource(ID_GIF);
  SetHandle(Handle);
  Center:= VCenter;
  Result:= Start;
end;

procedure TGifViewer.Finish;
begin
  SetEvent(hEvent); // Si el thread estaba esperando, se le abre el semáforo
  if hGdipImage <> 0 then
  begin
    GdipDisposeImage(hGdipImage);
    hGdipImage:= 0;
    WaitForSingleObject(hThread, INFINITE); // El thread podrá terminar
    CloseHandle(hThread);
    hThread:= 0;
  end;
  Left:= 0;
  Top:= 0;
  RePaintWindow(Wnd);
end;

function TGifViewer.Start(): boolean;
begin
  if (Wnd <> 0) and (hGdipImage <> 0) and (hThread = 0) then
    hThread:= CreateThread(nil, 0, @ThGif, self, 0, PDWORD(0)^);
  Result:= hThread <> 0;
end;

function TGifViewer.GetWidth: integer;
begin
  Result:= Width;
end;

function TGifViewer.GetHeight: integer;
begin
  Result:= Height;
end;

function TGifViewer.GetFrames: UINT;
begin
  Result:= Frames;
end;

constructor TGifViewer.Create;
var
  GdiPlusStartupInput: array[0..2] of int64;
begin
  FillChar(GdiPlusStartupInput, sizeof(GdiPlusStartupInput), 0);
  GdiPlusStartupInput[0]:= 1;
  if GdiplusStartup(gdiplusToken, @GdiPlusStartupInput, nil) = 0 then inc(GDI);
  if hEvent = 0 then hEvent:= CreateEvent(nil, true, false, nil);
end;

destructor TGifViewer.Destroy;
begin
  dec(GDI);
  Finish;
  CloseHandle(hEvent);
  SetHandle(0);
  if GDI = 0 then GdiplusShutdown(gdiplusToken);
  inherited Destroy;
end;

end.


Forma de uso desde un archivo:
Código Delphi [-]
var
  GV: TGifViewer;
begin
  GV:= TGifViewer.Create;
  GV.GifView(Panel1.Handle, PWCHAR(WideString(OpenDialog1.FileName)));
end;


Desde un recurso:
Código Delphi [-]
  GV.GifViewFromResource(Panel1.Handle, 'ID_WAIT', true);


Saludos.

Última edición por escafandra fecha: 18-11-2022 a las 23:48:36.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Mensaje de Espera mientras ejecuta algo mantraxer21 Varios 3 12-05-2015 12:13:31
Mensaje/Ventana de espera mientras se ejecuta un proceso Adrian Murua PHP 1 07-03-2012 17:51:23
Ventana de Espera totote Varios 6 20-05-2008 14:30:47
Crear mensaje de espera juanmdq Varios 2 23-04-2008 14:01:14
Evento que no espera Juditia OOP 2 14-10-2004 16:43:23


La franja horaria es GMT +2. Ahora son las 18:49:27.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi