#include "fivewin.ch"
********** TEST CODE **********
proc main
LOCAL oWnd, oGif
DEFINE DIALOG oWnd TITLE "3D objects"
oGif := GifControl():New(10,10,oWnd,,,"segu0020.gif")
oGif := GifControl():New(10,100,oWnd,100,100,"TEST_GIF")
oGif := GifControl():New(10,200,oWnd,,,"TEST_GIF")
oGif:lUseDoubleBuffer := .T. // necessary for transparent gif
ACTIVATE DIALOG oWnd
*******************************
********* GifControl **********
#define COLOR_BTNFACE 15
#define SRCCOPY 0xCC0020
class GifControl FROM TControl
CLASSDATA lRegistered AS LOGICAL
DATA oImage
DATA hGlobal //used in case of load from resource
DATA aFrameLen
DATA oTimer
DATA nCurrFrame
DATA lUseDoubleBuffer INIT .F.
METHOD New( nRow, nCol, oWnd, nWidth, nHeight, szFileName ) CONSTRUCTOR
METHOD Display() INLINE ::BeginPaint(),::Paint(),::EndPaint(),0
METHOD Paint()
METHOD Initiate( hDlg )
METHOD ChangeFrame()
METHOD Destroy()
endclass
METHOD New( nRow, nCol, oWnd, nWidth, nHeight, szFileName, nClrPane ) class GifControl
::oImage := GDIBmp():New()
if file(szFileName)
::oImage:hBmp := GDIPlusImageFromFile(szFileName)
else
::hGlobal := CopyResourceInGlobal(GetResources(),szFileName, 10)
::oImage:hBmp := GDIPlusImageFromGlobal(::hGlobal)
endif
::aFrameLen := GdiPlusImageGetFrameDimensions(::oImage:hBmp)
DEFAULT nRow := 10, nCol := 10, oWnd := GetWndDefault()
DEFAULT nWidth := ::oImage:GetWidth()-1
DEFAULT nHeight := ::oImage:GetHeight()-1
::oWnd := oWnd
::nId := ::GetNewId()
::nStyle := nOR( WS_CHILD, WS_VISIBLE, WS_TABSTOP )
::nTop := nRow
::nLeft := nCol
::nBottom := ::nTop + nHeight - 1
::nRight := ::nLeft + nWidth
if empty(nClrPane)
::nClrPane := iif(Upper( oWnd:Classname() ) != "TWINDOW",;
GetSysColor( COLOR_BTNFACE ),;
oWnd:nClrPane)
endif
::Register( nOR( CS_VREDRAW, CS_HREDRAW ) )
::oBrush := TBrush():New( , ::nClrPane )
::nCurrFrame := -1
if ! Empty( oWnd:hWnd )
::Create( )
oWnd:AddControl( Self )
::ChangeFrame()
else
oWnd:DefControl( Self )
// In this case?
endif
return Self
METHOD Initiate( hDlg ) class GifControl
::Super:Initiate( hDlg )
::ChangeFrame()
return nil
METHOD Destroy() class GifControl
::Super:Destroy()
if .not. empty(::hGlobal)
GlobalFree(::hGlobal)
::hGlobal:=nil
endif
if .not. empty(::oImage)
::oImage:Destroy()
endif
if .not. empty(::oTimer)
::oTimer:End()
endif
return nil
METHOD Paint() class GifControl
local aRect := GetClientRect( ::hWnd )
local hDCMem, hBmpMem
local hOldBmp
LOCAL g
if ::lUseDoubleBuffer
hDCMem = CreateCompatibleDC( ::hDC )
hBmpMem = CreateCompatibleBitmap( ::hDC, aRect[ 4 ], aRect[ 3 ] )
hOldBmp = SelectObject( hDCMem, hBmpMem )
g := Graphics():New(hDCMem)
FillRect( hDCMem, aRect, ::oBrush:hBrush )
else
g := Graphics():New(::hDC)
endif
g:DrawImage(::oImage,0,0,aRect[ 4 ], aRect[ 3 ] )
g:Destroy()
if ::lUseDoubleBuffer
BitBlt( ::hDC, 0, 0, aRect[4], aRect[3], hDCMem, 0, 0, SRCCOPY )
SelectObject( hDCMem, hOldBmp )
DeleteObject( hBmpMem )
DeleteDC( hDCMem )
endif
return nil
METHOD ChangeFrame() class GifControl
LOCAL cS := Self
::nCurrFrame++
//? ::nCurrFrame
if empty(::aFrameLen)
return nil
endif
if ::nCurrFrame == len(::aFrameLen)
::nCurrFrame := 0
endif
GdiPlusImageSelectActiveFrame(::oImage:hBmp,::nCurrFrame)
if empty(::oTimer)
DEFINE TIMER ::oTimer ;
INTERVAL ::aFrameLen[::nCurrFrame+1] ;
ACTION cS:ChangeFrame() ;
OF Self
else
::oTimer:DeActivate()
endif
::oTimer:nInterval := ::aFrameLen[::nCurrFrame+1]
::oTimer:Activate()
::Refresh(.F.)
return nil
#pragma BEGINDUMP
#include <hbapi.h>
#include <Windows.h>
#include <gdiplus.h>
using namespace Gdiplus;
// Enrico Maria Giordano Escribio - para xHarbour and BCC73
void hb_storvni( int iValue, int iParam, int iIndex )
{
hb_storni( iValue, iParam, iIndex );
}
HB_FUNC( GDIPLUSIMAGEFROMFILE )
{
wchar_t *cFileName = hb_mbtowc( hb_parc(1) );
Image* pImage = Image::FromFile(cFileName);
hb_xfree( cFileName );
hb_retptr(pImage);
}
HB_FUNC( COPYRESOURCEINGLOBAL )
{
HINSTANCE hInst = ( HINSTANCE ) hb_parnl( 1 );
HRSRC hResource = FindResource(hInst, hb_parc(2), MAKEINTRESOURCE( hb_parni( 3 ) ));
if (!hResource) { hb_ret(); return; }
DWORD imageSize = SizeofResource(hInst, hResource);
if (!imageSize) { hb_ret(); return; }
const void* pResourceData = LockResource(LoadResource(hInst, hResource));
if (!pResourceData) { hb_ret(); return; }
HANDLE hBuffer = GlobalAlloc(GMEM_MOVEABLE, imageSize);
if (hBuffer)
{
void* pBuffer = GlobalLock(hBuffer);
if (pBuffer)
{
memcpy(pBuffer, pResourceData, imageSize);
GlobalUnlock(hBuffer);
}
}
#ifndef _WIN64
hb_retnl((long)hBuffer);
#else
hb_parnll((long long)hBuffer);
#endif
}
HB_FUNC( GDIPLUSIMAGEFROMGLOBAL )
{
#ifndef _WIN64
HGLOBAL hBuffer = ( HGLOBAL ) hb_parnl( 1 );
#else
HGLOBAL hBuffer = ( HGLOBAL ) hb_parnll( 1 );
#endif
IStream* pStream = NULL;
Image* pImage = 0;
if (CreateStreamOnHGlobal(hBuffer, TRUE, &pStream) == S_OK)
{
pImage = Image::FromStream(pStream);
pStream->Release();
}
hb_retptr(pImage);
}
HB_FUNC( GDIPLUSIMAGEGETFRAMEDIMENSIONS )
{
Image* pImage = (Image*)hb_parptr(1);
UINT nFrame = pImage->GetFrameDimensionsCount();
GUID g;
if(nFrame == 0)
{
hb_ret();
return;
}
pImage->GetFrameDimensionsList(&g,1);
nFrame = pImage->GetFrameCount(&g);
hb_reta(nFrame);
UINT nSize = pImage->GetPropertyItemSize(PropertyTagFrameDelay);
PropertyItem* pPropertyItem = (PropertyItem*) malloc(nSize);
pImage->GetPropertyItem(PropertyTagFrameDelay, nSize, pPropertyItem);
for(UINT i=0;i<nFrame;i++)
{
hb_storvni( ((UINT*)pPropertyItem[0].value)[i] * 10 , -1, i+1 );
}
free(pPropertyItem);
}
HB_FUNC( GDIPLUSIMAGESELECTACTIVEFRAME )
{
Image* pImage = (Image*)hb_parptr(1);
GUID g = FrameDimensionTime;
pImage->SelectActiveFrame(&g, hb_parni(2));
hb_ret();
}
HB_FUNC( MYDRAW )
{
Graphics g((HDC)hb_parnl(1));
Image* i = (Image*)hb_parptr(2);
g.DrawImage(i,0,0,i->GetWidth(),i->GetHeight());
}
#pragma ENDDUMP
/* // comments
#pragma BEGINDUMP
#include <hbapi.h>
void hb_storvni( int iValue, int iParam, int iIndex )
{
hb_storni( iValue, iParam, iIndex );
}
#pragma ENDDUMP
*/