我帮你贴出吧!
/*******************************************************************************
*
* FUNCTION : FMPCallbackProc()
*
* DESCRIPTION : FMP callback function.
*
* PARAMETERS : bMsg - callback message
* hMPEGStream - handle to MPEG stream
* dwValue - value passed to callback
*
* RETURN : 0 - success
* FMPE_DOS - error encountered
*
* COMMENTS : NONE
*
*******************************************************************************/
WORD CALLBACK FMPCallbackProc( BYTE bMsg, BYTE hMPEGStream, DWORD dwValue )
{
int i;
struct TBuf *Buf;
Buf= (struct TBuf *)FMPGet( hMPEGStream, FMPI_STM_USER);
switch( bMsg )
{
// first message received - make all your allocations here
case FMPM_BUF_CREATE:
//DWORD dwIndex;
Buf = (struct TBuf *)GlobalAllocPtr( GMEM_FIXED, sizeof( struct TBuf ) );
if( !Buf )
{
MessageBox(NULL,"Error while allocating TBuf",
"FMPBuf1::FMPCallbackProc()",
MB_ICONASTERISK | MB_OK );
return( FMPE_DOS );
}
memset( Buf, '/0', sizeof( struct TBuf ) );
// Value is the parameter passed when opening the file( ie. filename )
Buf->hFile = CreateFile(((FMP_OPEN_STRUCT *)dwValue)->lpFileName, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, 0 );
// if we cannot open the file, return an error
// NOTE: the FMPM_BUF_CLOSE is not called when an error occurs
// during the creation
if( Buf->hFile == INVALID_HANDLE_VALUE )
{
MessageBox( NULL,
"Error While Opening File",
"FMPBuf1::FMPCallbackProc()",
MB_ICONASTERISK | MB_OK );
GlobalFreePtr( Buf );
return( FMPE_DOS );
}
for( i = 0;
i < MAX_BUF_NUMBER;
i++ )
{
Buf->Buffer = (char *)GlobalAllocPtr( GMEM_FIXED, MAX_BUF_SIZE + 2 );
}
Buf->wIndex = 0;
Buf->dwSize = 0;
// store the structure address in the USER field
FMPSet(hMPEGStream,FMPI_STM_USER, (DWORD)Buf );
// trigger at 3/4 of the buffer to fill the next buffer
FMPSet(hMPEGStream, FMPI_BUF_POS, (DWORD)((float)MAX_BUF_SIZE * (float).75));
break;
// message received when closing the stream - delete buffers
case FMPM_BUF_CLOSE:
// close the file
CloseHandle( Buf->hFile );
// free all application buffers
for( i = 0;
i < MAX_BUF_NUMBER;
i++ )
{
GlobalFreePtr( Buf->Buffer );
}
GlobalFreePtr( Buf );
break;
// message received when a seek is required - seek to the position
// in Value (specified in bytes)
case FMPM_BUF_SEEK:
SetFilePointer( Buf->hFile, (LONG)dwValue, 0, FILE_begin
);
break;
// message received when a buffer has reached its signal position -
// prepare here the next buffer
case FMPM_BUF_POS:
ReadFile( Buf->hFile, Buf->Buffer[Buf->wIndex], MAX_BUF_SIZE,
&Buf->dwSize, NULL );
break;
// message received when a buffer has been completely read - switch to
// the next prepared buffer
case FMPM_BUF_EMPTY:
FMPSet(hMPEGStream, FMPI_BUF_SIZE, Buf->dwSize );
FMPSet(hMPEGStream, FMPI_BUF_ADDRESS, (DWORD)(Buf->Buffer[Buf->wIndex]));
//FMPSet( ghMPEGStream, FMPI_BUF_HANDLE, (DWORD)Buf->BufferIndex[Buf->wIndex] );
Buf->wIndex++;
Buf->wIndex %= MAX_BUF_NUMBER;
break;
case FMPM_ERROR:
break;
}
return( 0 );
}
以上是FMP的回调数,以下是它的调用:
void
FMPBuf1_OnCommand( HWND hWnd, int iID, HWND hWndCtl, UINT uiCodeNotify )
{
switch( iID )
case IDM_OPEN:
{
FMP_OPEN_STRUCT FMPOpenStruct;
// stop and close any currently opened MPEG stream
if( ghMPEGStream )
{
FMPStop( ghMPEGStream );
FMPClose( ghMPEGStream );
ghMPEGStream = 0;
}
// select MPEG stream to open
if( !GetOpenFileName( (LPOPENFILENAME)&gOpenFileName ) )
{
return;
}
// open selected MPEG stream
memset( &FMPOpenStruct, '/0', sizeof( FMP_OPEN_STRUCT ) );
FMPOpenStruct.lpFileName = gOpenFileName.lpstrFile;
FMPOpenStruct.dwCallBack = (DWORD)FMPCallbackProc;//请注意这里,这就是它的调用所在
ghMPEGStream = (BYTE)FMPOpen( FMPF_BUFFERS, (DWORD)&FMPOpenStruct );
if( !ghMPEGStream )
{
MessageBox( hWnd, "File open error", "FMPBuf1 ERROR",
MB_ICONASTERISK | MB_OK );
}
// set video keying mode
FMPSet( ghMPEGStream, FMPI_VID_KEY_MODE, FMPF_KEY_VGA );
// set video keying color
FMPSet( ghMPEGStream, FMPI_VID_KEY_COL, 0L );
// set video destination position
SendMessage( hWnd, WM_MOVE, 0, 0 );
// set video destination size
SendMessage( hWnd, WM_SIZE, 0, 0 );
break;
}
);
}
}