Atlanta Custom Software Development 

 
   Search        Code/Page
 

User Login
Email

Password

 

Forgot the Password?
Services
» Web Development
» Maintenance
» Data Integration/BI
» Information Management
Programming
  Database
Automation
OS/Networking
Graphics
Links
Tools
» Regular Expr Tester
» Free Tools


MCI (Media Control Interface) provides a high-level interface to play multimedia files (or "device elements" as defined in MCI). By default, MCI WAVE/AVI drivers (MCIAVI and MCIWAVE) use mmioOpen to open a file stored on a disk. If the file name contains a "+" character, mmioOpen will look for a custom procedure as identified by the three-character file extension to handle the reading and writing of a file. This technique can be applied to allow MCI to play WAVE/AVI files that are already loaded into memory.

The following steps demonstrate this approach. We use "MEY" as the file extension in this example:

1. Install a custom MMIO procedure as follows:

Click here to copy the following block
Call mmioInstallIOProc(MEY, AddressOf IOProc, MMIO_INSTALLPROC + MMIO_GLOBALPROC)

Where MEY = mmioFOURCC('M', 'E', 'Y', ' ') which is a constant value &H2059454D.

2. Use the MCI open command except to add a plus sign (+) at the end of a file name. For instance, open test.MEY+ type waveaudio (or avivideo) alias test. Because there is a "+" character in the file name, mmioOpen will not open any files. Instead, the custom mmio procedure is identified. Subsequently, all the I/O messages are routed to that procedure.

3.Then, we can use usual MCI command. For instance: play test, close test

4. When done with this custom mmio procedure, we should remove it by
mmioInstallIOProc(MEY, ByVal 0&, MMIO_REMOVEPROC)

Where MEY=&H2059454D '//Const value of mmioFOURCC('M', 'E', 'Y', ' ')

Step-By-Step Example

- Create a standard exe project
- Add one module
- Add one command button and one picturebox control on the form1
- Add the following code to form1
Note : Alter resource file path, resource id and resource type name if its different than specified in this demo. I have included a test.exe file which contains AVI resource so you can use it for de
Form1.frm

Click here to copy the following block
Option Explicit
Private Sub Command1_Click()
  Dim hRsrc As Long
  Dim hGlobal As Long
  Dim lpString As String
  Dim strCmd As String, ret As Long
  Dim nbuf As Long

  '//Identifier for the AVI in the resource file from the resource.h
  '//file of the resource dll, which must be preceded by '#'.
  lpString = "#101"  '                    <<<<

  '//Loads the resource
  '//Change the filename argument in the next line to the path and
  '//filename of your resource dll file.
  hInst = LoadLibrary(App.Path & "\test.exe")  '  <<<<
  hRsrc = FindResource(hInst, lpString, "AVI")
  hGlobal = LoadResource(hInst, hRsrc)
  lpData = LockResource(hGlobal)
  fileSize = SizeofResource(hInst, hRsrc)

  Call mmioInstallIOProc(MEY, AddressOf IOProc, MMIO_INSTALLPROC + MMIO_GLOBALPROC)
  nbuf = 256
  
  '//Close all opened MCI device for this app before running any new avi
  Call mciSendString("Close all", 0&, 0&, 0&)
  
  '//Play the AVI file
  strCmd = "open test.MEY+ type avivideo alias test parent " & Picture1.hWnd & " Style child"
  ret = mciSendString(strCmd, 0&, 0&, 0&)
  If ret > 0 Then ShowMCIError (ret)
  
  strCmd = "play test repeat"
  ret = mciSendString(strCmd, 0&, 0&, 0&)
  If ret > 0 Then ShowMCIError (ret)
  
  Call mmioInstallIOProc(MEY, vbNull, MMIO_REMOVEPROC)
  FreeLibrary hInst
End Sub

Private Sub Form_Load()
  Command1.Caption = "Play AVI from Memory"
End Sub

- Add the following code to module1

Module1.bas

Click here to copy the following block
Option Explicit
Public lpData As Long
Public fileSize As Long
Public hInst As Long

Public Const MMIO_INSTALLPROC = &H10000  'mmioInstallIOProc:install
'MMIOProc

Public Const MMIO_GLOBALPROC = &H10000000  'mmioInstallIOProc: install
'globally

Public Const MMIO_READ = &H0
Public Const MMIOM_CLOSE = 4
Public Const MMIOM_OPEN = 3
Public Const MMIOM_READ = MMIO_READ
Public Const MMIO_REMOVEPROC = &H20000
Public Const MMIOM_SEEK = 2
Public Const SEEK_CUR = 1
Public Const SEEK_END = 2
Public Const SEEK_SET = 0
Public Const MEY = &H2059454D  'This is the value of "MEY " run
'through FOURCC

'Create a user defined variable for the API function calls
Public Type MMIOINFO
  dwFlags As Long
  fccIOProc As Long
  pIOProc As Long
  wErrorRet As Long
  htask As Long
  cchBuffer As Long
  pchBuffer As String
  pchNext As String
  pchEndRead As String
  pchEndWrite As String
  lBufOffset As Long
  lDiskOffset As Long
  adwInfo(4) As Long
  dwReserved1 As Long
  dwReserved2 As Long
  hmmio As Long
End Type

'Finds the specified resource in an executable file. The function
'returns a resource handle that can be used by other functions used
'to load the resource.
Public Declare Function FindResource Lib "kernel32" Alias "FindResourceA" ( _
    ByVal hInstance As Long, _
    ByVal lpName As String, _
    ByVal lpType As String) As Long

'Returns a global memory handle to a resource in the specified
'module. The resource is only loaded after calling the LockResource
'function to get a pointer to the resource data.
Public Declare Function LoadResource Lib "kernel32" ( _
    ByVal hInstance As Long, _
    ByVal hResInfo As Long) As Long

'Locks the specified resource. The function returns a 32-bit pointer
'to the data for the resource.
Public Declare Function LockResource Lib "kernel32" ( _
    ByVal hResData As Long) As Long

'Loads the specified dll file and maps the address space for the
'current process.
Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" ( _
    ByVal lpLibFileName As String) As Long

'Frees the specified dll file loaded with the LoadLibrary function.
Public Declare Function FreeLibrary Lib "kernel32" _
    (ByVal hLibModule As Long) As Long

'Copies a block of memory from one location to another.
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
    hpvDest As Any, _
    hpvSource As Any, _
    ByVal cbCopy As Long)

'Installs or removes a custom I/O procedure. This function also
'locates an installed I/O procedure, using its corresponding
'four-character code.
Public Declare Function mmioInstallIOProc Lib "winmm" Alias "mmioInstallIOProcA" ( _
    ByVal fccIOProc As Long, _
    ByVal pIOProc As Long, _
    ByVal dwFlags As Long) As Long

'Sends the specified command string to an MCI device.
Public Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" ( _
    ByVal lpstrCommand As String, _
    ByVal lpstrReturnString As Long, _
    ByVal uReturnLength As Long, _
    ByVal hwndCallback As Long) As Long

'Get MCI error description from return code MCISendString
Public Declare Function mciGetErrorString Lib "winmm.dll" Alias "mciGetErrorStringA" ( _
    ByVal ErrorNumber As Long, _
    ByVal ReturnBuffer As String, _
    ByVal ReturnBufferSize As Long) As Long  'BOOL

'Returns the size, in bytes, of the specified resource
Public Declare Function SizeofResource Lib "kernel32" ( _
    ByVal hInstance As Long, _
    ByVal hResInfo As Long) As Long

'Accesses a unique storage system, such as a database or file
'archive. Install or remove this callback function with the
'mmioInstallIOProc function.
Public Function IOProc(ByRef lpMMIOInfo As MMIOINFO, ByVal uMessage As Long, _
  ByVal lParam1 As Long, _
  ByVal lParam2 As Long) As Long

  Static alreadyOpened As Boolean

  Select Case uMessage
    Case MMIOM_OPEN
      If Not alreadyOpened Then
        alreadyOpened = True
        lpMMIOInfo.lDiskOffset = 0
      End If
      IOProc = 0

    Case MMIOM_CLOSE
      IOProc = 0

    Case MMIOM_READ:
      Call CopyMemory(ByVal lParam1, ByVal _
          lpData + lpMMIOInfo.lDiskOffset, lParam2)
      lpMMIOInfo.lDiskOffset = lpMMIOInfo.lDiskOffset + lParam2
      IOProc = lParam2

    Case MMIOM_SEEK

      Select Case lParam2
        Case SEEK_SET
          lpMMIOInfo.lDiskOffset = lParam1

        Case SEEK_CUR
          lpMMIOInfo.lDiskOffset = lpMMIOInfo.lDiskOffset + lParam1
          lpMMIOInfo.lDiskOffset = fileSize - 1 - lParam1

        Case SEEK_END
          lpMMIOInfo.lDiskOffset = fileSize - 1 - lParam1
      End Select

      IOProc = lpMMIOInfo.lDiskOffset

    Case Else
      IOProc = -1  ' Unexpected msgs. For instance, we do not
      ' process MMIOM_WRITE in this sample
  End Select

End Function  ' IOProc

' Get the error that just occured (if one did occur)
Public Function ShowMCIError(Optional ByVal errNum As Long)
  Dim strMsg As String

  errNum = LOWORD(errNum)  '//We only need low word, low word is actual error number
  ' Get the error description based on the error number

  strMsg = String(260, Chr(0))
  If mciGetErrorString(errNum, strMsg, 260) <> 0 Then
    MsgBox Left(strMsg, InStr(strMsg, Chr(0)) - 1), vbCritical, "Error: " & errNum
  Else
    MsgBox "Unknown Error", vbCritical, "Error: " & errNum
  End If
End Function

' Function that extracts the "Low Order" (lower 16bits) of a 32bit number
Private Function LOWORD(ByVal dwValue As Long) As Integer
  LOWORD = Val("&H" & Right("0000" & Hex(dwValue), 4))
End Function


Submitted By : Nayan Patel  (Member Since : 5/26/2004 12:23:06 PM)

Job Description : He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting.
View all (893) submissions by this author  (Birth Date : 7/14/1981 )


Home   |  Comment   |  Contact Us   |  Privacy Policy   |  Terms & Conditions   |  BlogsZappySys

© 2008 BinaryWorld LLC. All rights reserved.