Option Explicit
Private Const RDW_ERASE = &H4
Private Const RDW_FRAME = &H400
Private Const RDW_INTERNALPAINT = &H2
Private Const RDW_INVALIDATE = &H1
Private Const RDW_ERASENOW = &H200
Private Const RDW_ALLCHILDREN = &H80
Private Const WM_USER = &H400
Private Const EM_GETOLEINTERFACE = WM_USER + 60
Private Const EM_POSFROMCHAR = (WM_USER + 38)
Private Const WM_LBUTTONDBLCLK = &H203
Private Declare Function InvalidateRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT, ByVal bErase As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Sub ZeroMemory Lib "KERNEL32" Alias "RtlZeroMemory" (dest As Any, ByVal numBytes As Long)
Private Declare Function RedrawWindow Lib "user32" (ByVal hwnd As Long, lprcUpdate As Any, ByVal hrgnUpdate As Long, ByVal fuRedraw As Long) As Long
Private Declare Function IIDFromString Lib "ole32" (ByVal lpszIID As Long, iid As Any) As Long
Private Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long
Private Declare Function CoCreateGuid Lib "ole32.dll" (lpGUID As Any) As Long
Private Declare Function StringFromGUID2 Lib "ole32" (lpGUID As Any, ByVal lpStr As String, ByVal lSize As Long) As Long
Const ProgID_Flash = "ShockwaveFlash.ShockwaveFlash.1"
Dim mIRichEditOle As IRichEditOle
'实现这个函数的目的是为了产生不重复的字串,为controls.add服务
Private Function GetGuidID() As String
Dim pGuid(16) As Byte
Dim s As String
s = String(255, " ")
CoCreateGuid pGuid(0)
StringFromGUID2 pGuid(0), s, 255
s = Trim(s)
s = StrConv(s, vbFromUnicode)
s = Replace(s, "{", "")
s = Replace(s, "}", "")
s = Replace(s, "-", "")
GetGuidID = s
End Function
Private Sub Command1_Click()
RichTextBoxInsertFlash RichTextBox1.hwnd, "e:\MC\11.SWF"
End Sub
'在richtextbox的当前光标处插入flash,flash的movie为mFile
Private Sub RichTextBoxInsertFlash(ByVal mHwnd As Long, ByVal mFile As String)
Dim mILockBytes As ILockBytes
Dim mIStorage As IStorage
Dim mIOleClientSite As IOleClientSite
Dim mIOleObject As IOleObject
Dim mReObject As REOBJECT
Dim mUUID As UUID
'创建Global Heap,实例化mILockBytes
Set mILockBytes = CreateILockBytesOnHGlobal(0&, True)
If ObjPtr(mILockBytes) = 0 Then
MsgBox "Error to create Global Heap"
Exit Sub
End If
'创建storage,实例化mIStorage
Set mIStorage = StgCreateDocfileOnILockBytes(mILockBytes, STGM_SHARE_EXCLUSIVE _
Or STGM_CREATE Or STGM_READWRITE, 0)
If ObjPtr(mIStorage) = 0 Then
MsgBox "Error to create storage"
Exit Sub
End If
'向richtextbox发送EM_GETOLEINTERFACE消息获得IRichEditOle接口,实例化mIRichEditOle
SendMessage mHwnd, EM_GETOLEINTERFACE, 0, mIRichEditOle
If ObjPtr(mIRichEditOle) = 0 Then
MsgBox "Error to get IRichEditOle"
Exit Sub
End If
'调用GetClientSite函数,实例化mIOleClientSite
Set mIOleClientSite = mIRichEditOle.GetClientSite
If ObjPtr(mIOleClientSite) = 0 Then
MsgBox "Error to get ClientSite"
Exit Sub
End If
'动态添加flash控件,用于解决插入多个影片的问题
Dim mFlash As ShockwaveFlashObjectsCtl.ShockwaveFlash
Set mFlash = Controls.Add(ProgID_Flash, "mc" + GetGuidID)
mFlash.Movie = mFile
'查询IOleObject接口
Set mIOleObject = mFlash.Object
OleSetContainedObject mIOleObject, True
mIOleObject.GetUserClassID mUUID
'填充mReObject
With mReObject
.cbStruct = LenB(mReObject)
.clsid = mUUID
.cp = REO_CP_SELECTION
.DVASPECT = DVASPECT_CONTENT
.dwFlags = REO_BELOWBASELINE ' Or REO_RESIZABLE
.sizel.cx = 0
.sizel.cy = 0
.dwUser = 0
Set .poleobj = mIOleObject
Set .polesite = mIOleClientSite
Set .pStg = mIStorage
End With
'在richtextbox的当前光标处插入flash
mIRichEditOle.InsertObject mReObject
' '释放资源
ZeroMemory mReObject, LenB(mReObject)
ZeroMemory mUUID, LenB(mUUID)
Set mIOleClientSite = Nothing
Set mIStorage = Nothing
Set mILockBytes = Nothing
Set mIOleObject = Nothing
End Sub
Private Sub UpdateObjects()
Dim i As Long, RE As REOBJECT
If ObjPtr(mIRichEditOle) = 0 Then Exit Sub
i = mIRichEditOle.GetObjectCount
Dim PT As olelib.Point
Dim k As Long, mSIZE As SIZE, RT As RECT
For k = 0 To i - 1
RE.cbStruct = LenB(RE)
mIRichEditOle.GetObject k, RE, REO_GETOBJ_ALL_INTERFACES
SendMessage RichTextBox1.hwnd, EM_POSFROMCHAR, VarPtr(PT), ByVal RE.cp
mSIZE = RE.sizel
With RT
.Left = PT.x
.Top = PT.y
.Right = mSIZE.cx * 192 / 5080 + PT.x
.Bottom = PT.y + mSIZE.cy * 192 / 5080
End With
InvalidateRect Me.RichTextBox1.hwnd, RT, False
Next
End Sub
Private Sub Form_Load()
Timer1.Interval = 80 '数值越小,闪烁的越厉害
Timer1.Enabled = True
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Dim obj As Object
For Each obj In Me.Controls
If TypeName(obj) = "shockwaveflash" And Left(obj.Name, 2) = "mc" Then
Controls.Remove obj
End If
Next
Set mIRichEditOle = Nothing
RichTextBox1.TextRTF = "" '关键代码,释放richtextbox占用的资源,否则程序不能正确退出
End Sub
Private Sub Form_Resize()
RichTextBox1.Move 0, 0, Me.ScaleWidth
End Sub