Attribute VB_Name = "Sample6"
Option Explicit

'Win32 API
Private Declare Function CallWindowProc Lib "user32" _
    Alias "CallWindowProcA" _
   (ByVal lpPrevWndFunc As Long, _
    ByVal hwnd As Long, _
    ByVal uMsg As Long, _
    ByVal wParam As Long, _
    ByVal lParam As Long) As Long
    
Public Declare Sub CopyMemory Lib "kernel32" _
    Alias "RtlMoveMemory" _
   (Destination As Any, _
    Source As Any, _
    ByVal Length As Long)
    
Private Declare Function GetModuleHandle Lib "kernel32" _
    Alias "GetModuleHandleA" _
   (ByVal ApplicationFileName As String) As Integer
   
Private Declare Function FindResource Lib "kernel32" _
    Alias "FindResourceA" _
   (ByVal hInstance As Long, _
    ByVal lpName As String, _
    ByVal lpType As String) As Long
   
Private Declare Function LoadResource Lib "kernel32" _
   (ByVal hInstance As Long, _
    ByVal hResInfo As Long) As Long
   
Private Declare Function LockResource Lib "kernel32" _
   (ByVal hResData As Long) As Long
   
Private Declare Function SizeofResource Lib "kernel32" _
    (ByVal hInstance As Long, _
    ByVal hResInfo As Long) As Long
    
Private Declare Function CreateFile Lib "kernel32" _
    Alias "CreateFileA" _
   (ByVal lpFileName As String, _
    ByVal dwDesiredAccess As Long, _
    ByVal dwShareMode As Long, _
    ByVal lpSecurityAttributes As Long, _
    ByVal dwCreationDisposition As Long, _
    ByVal dwFlagsAndAttributes As Long, _
    ByVal hTemplateFile As Long) As Long
    
Private Declare Function CreateFileMapping Lib "kernel32" _
    Alias "CreateFileMappingA" _
   (ByVal hfile As Long, _
    ByVal lpFileMappingAttributes As Long, _
    ByVal flProtect As Long, _
    ByVal dwMaximumSizeHigh As Long, _
    ByVal dwMaximumSizeLow As Long, _
    ByVal lpName As String) As Long
    
Private Declare Function MapViewOfFile Lib "kernel32" _
   (ByVal hFileMappingObject As Long, _
    ByVal dwDesiredAccess As Long, _
    ByVal dwFileOffsetHigh As Long, _
    ByVal dwFileOffsetLow As Long, _
    ByVal dwNumberOfBytesToMap As Long) As Long

Private Declare Function UnmapViewOfFile Lib "kernel32" _
   (ByVal lpBaseAddress As Long) As Long
    
Private Declare Function GetFileSize Lib "kernel32" _
   (ByVal hfile As Long, lpFileSizeHigh As Long) As Long
   
Private Declare Function CloseHandle Lib "kernel32" _
   (ByVal hfile As Long) As Long
    
Private Declare Function lstrlen Lib "kernel32" _
    Alias "lstrlenA" _
    (ByVal lpString As Any) As Long

Private Declare Function lstrcpy Lib "kernel32" _
    Alias "lstrcpyA" _
    (ByVal lpString1 As Any, _
    ByVal lpString2 As Any) As Long
  
Private Declare Function lstrcmpi Lib "kernel32" Alias "lstrcmpiA" _
    (ByVal lpString1 As Long, _
     ByVal lpString2 As String) As Long
    
' IStream helpers

Private Declare Function FPC_IStream_AddRef Lib "f_in_box.dll" _
    (ByVal pStream As Long) As Long
    
Private Declare Function FPC_IStream_Release Lib "f_in_box.dll" _
    (ByVal pStream As Long) As Long
    
    'ByVal pData As Long, _

Private Declare Function FPC_IStream_Write Lib "f_in_box.dll" _
    (ByVal pStream As Long, _
    pData As Any, _
    ByVal nSize As Long, _
    ByRef nWritten As Long) As Long
    
'Struct NMHDR
Public Type NMHDR
   hWndFrom As Long
   idfrom   As Long
   code     As Long
End Type
    
'Win32 constants
Private Const WM_NOTIFY As Long = &H4E
Private Const WM_USER As Long = &H400

Const INVALID_HANDLE_VALUE As Long = -1
Const GENERIC_READ As Long = &H80000000
Const FILE_SHARE_READ As Long = &H1
Const PAGE_READONLY As Long = &H2
Const OPEN_EXISTING As Long = &H3
Const FILE_MAP_READ As Long = &H4

'FlashPlayerControl constants
Private Const FPCM_FIRST As Long = WM_USER + &H1000
Private Const FPCN_FIRST As Long = (FPCM_FIRST - 1)
Private Const FPCN_ONPROGRESS As Long = (FPCN_FIRST - 256)
Private Const FPCN_FSCOMMAND As Long = (FPCN_FIRST - 257)
Private Const FPCN_ONREADYSTATECHANGE As Long = (FPCN_FIRST - 255)
Private Const FPCN_LOADEXTERNALRESOURCE As Long = (FPCN_FIRST - 2)

'Struct SFPCOnProgressInfoStruct
Private Type SFPCOnProgressInfoStruct
    hdr As NMHDR
    percentDone As Long
End Type

'Struct SFPCFSCommandInfoStruct
Private Type SFPCFSCommandInfoStruct
    hdr As NMHDR
    command As Long ' LPCSTR
    args As Long ' LPCSTR
End Type

'Struct SFPCOnReadyStateChangeInfoStruct
Private Type SFPCOnReadyStateChangeInfoStruct
    hdr As NMHDR
    newState As Long
End Type

'Struct SFPCLoadExternalResource
Private Type SFPCLoadExternalResource
    hdr As NMHDR
    lpszRelativePath As Long 'LPCSTR
    lpStream As Long 'LPSTREAM
End Type

Public Function MainFormWindowProc(ByVal hwnd As Long, _
                    ByVal uMsg As Long, _
                    ByVal wParam As Long, _
                    ByVal lParam As Long) As Long
    If uMsg = WM_NOTIFY Then
        Dim nm As NMHDR
        Call CopyMemory(nm, ByVal lParam, Len(nm))
        
        If nm.hWndFrom = MainForm.FlashPlayerControlVal Then
            Select Case nm.code
                Case FPCN_ONPROGRESS
                    Dim FPCOnProgressInfoStruct As SFPCOnProgressInfoStruct
                    Call CopyMemory(FPCOnProgressInfoStruct, ByVal lParam, Len(FPCOnProgressInfoStruct))
                    Debug.Print "FPCN_ONPROGRESS: percentDone(" & Format(FPCOnProgressInfoStruct.percentDone) & ")"
                    Exit Function
                Case FPCN_FSCOMMAND
                    Dim FPCFSCommandInfoStruct As SFPCFSCommandInfoStruct
                    Call CopyMemory(FPCFSCommandInfoStruct, ByVal lParam, Len(FPCFSCommandInfoStruct))
                    Debug.Print "FPCN_FSCOMMAND: command(" & GetStringFromLongPtr(FPCFSCommandInfoStruct.command) & ")" _
                    & "args(" & GetStringFromLongPtr(FPCFSCommandInfoStruct.args) & ")"
                    Exit Function
                Case FPCN_ONREADYSTATECHANGE
                    Dim FPCOnReadyStateChangeInfoStruct As SFPCOnReadyStateChangeInfoStruct
                    Call CopyMemory(FPCOnReadyStateChangeInfoStruct, ByVal lParam, Len(FPCOnReadyStateChangeInfoStruct))
                    Debug.Print "FPCN_ONREADYSTATECHANGE: newState(" & Format(FPCOnReadyStateChangeInfoStruct.newState) & ")"
                    Exit Function
                Case FPCN_LOADEXTERNALRESOURCE
                    Dim FPCLoadExternalResource As SFPCLoadExternalResource
                    Call CopyMemory(FPCLoadExternalResource, ByVal lParam, Len(FPCLoadExternalResource))

                    Dim lpResourceData As Long
                    Dim dwResourceSize As Long
                    Dim dwWrittenBytes As Long
                    
                    Dim pStream As Long
                    pStream = FPCLoadExternalResource.lpStream

                    If lstrcmpi(FPCLoadExternalResource.lpszRelativePath, "images/embedded_image1.jpg") = 0 Then
                        LoadResourceHelper "IMAGE1", "IMAGE", lpResourceData, dwResourceSize
                        FPC_IStream_Write pStream, ByVal lpResourceData, dwResourceSize, dwWrittenBytes
                    ElseIf lstrcmpi(FPCLoadExternalResource.lpszRelativePath, "images/embedded_image2.jpg") = 0 Then
                        LoadResourceHelper "IMAGE2", "IMAGE", lpResourceData, dwResourceSize
                        FPC_IStream_Write pStream, ByVal lpResourceData, dwResourceSize, dwWrittenBytes
                    ElseIf lstrcmpi(FPCLoadExternalResource.lpszRelativePath, "images/embedded_image3.jpg") = 0 Then
                        LoadResourceHelper "IMAGE3", "IMAGE", lpResourceData, dwResourceSize
                        FPC_IStream_Write pStream, ByVal lpResourceData, dwResourceSize, dwWrittenBytes
                    ElseIf lstrcmpi(FPCLoadExternalResource.lpszRelativePath, "images/embedded_image4.jpg") = 0 Then
                        LoadResourceHelper "IMAGE4", "IMAGE", lpResourceData, dwResourceSize
                        FPC_IStream_Write pStream, ByVal lpResourceData, dwResourceSize, dwWrittenBytes
                    ElseIf lstrcmpi(FPCLoadExternalResource.lpszRelativePath, "images/embedded_image5.jpg") = 0 Then
                        LoadResourceHelper "IMAGE5", "IMAGE", lpResourceData, dwResourceSize
                        FPC_IStream_Write pStream, ByVal lpResourceData, dwResourceSize, dwWrittenBytes
                    ElseIf lstrcmpi(FPCLoadExternalResource.lpszRelativePath, "external_image.jpg") = 0 Then
                        MainForm.CommonDialog.DefaultExt = "jpg"
                        MainForm.CommonDialog.Filter = "JPEG (*.jpg, *.jpeg)|*.jpg;*.jpeg|All Files (*.*)|*.*||"
                        MainForm.CommonDialog.ShowOpen
                        If (Len(MainForm.CommonDialog.FileName) > 0) Then
                            Dim hfile As Long
                            hfile = CreateFile(MainForm.CommonDialog.FileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)

                            If Not hfile = INVALID_HANDLE_VALUE Then
                                Dim hFileMapping As Long
                                hFileMapping = CreateFileMapping(hfile, 0, PAGE_READONLY, 0, 0, vbNullString)
                                
                                If Not hFileMapping = INVALID_HANDLE_VALUE Then
                                    lpResourceData = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0)
                                    dwResourceSize = GetFileSize(hfile, 0)
                                    FPC_IStream_Write pStream, ByVal lpResourceData, dwResourceSize, dwWrittenBytes
                                    UnmapViewOfFile lpResourceData
                                    CloseHandle hFileMapping
                                End If
                                CloseHandle hfile
                            End If
                        End If
                    ElseIf lstrcmpi(FPCLoadExternalResource.lpszRelativePath, "embedded_movie.swf") = 0 Then
                        LoadResourceHelper "MOVIE1", "SWF", lpResourceData, dwResourceSize
                        FPC_IStream_Write pStream, ByVal lpResourceData, dwResourceSize, dwWrittenBytes
                    End If
                    Exit Function
            End Select
        End If
        
    End If
    MainFormWindowProc = CallWindowProc(MainForm.PrevWindowProcVal, hwnd, uMsg, wParam, lParam)
End Function

Private Sub LoadResourceHelper(ByVal lpszName As String, ByVal lpszType As String, lpData As Long, dwSize As Long)
    Dim hModule As Long
    Dim hResInfo As Long
    Dim hResData As Long
    
    hModule = GetModuleHandle(vbNullString)
    hResInfo = FindResource(hModule, lpszName, lpszType)
    hResData = LoadResource(hModule, hResInfo)
    lpData = LockResource(hResData)
    dwSize = SizeofResource(hModule, hResInfo)
End Sub

Private Function GetStringFromLongPtr(ByVal pStr As Long) As String
    GetStringFromLongPtr = String$(lstrlen(ByVal pStr), 0)
    Call lstrcpy(ByVal GetStringFromLongPtr, ByVal pStr)
End Function

