⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄

📁 Delphi技巧
💻
字号:
具有交互功能的AVI文件
(AVI File with Hot Spots)
微软公司供稿

摘要
AVI热点编辑器(AVIHED.EXE)和与之相伴的动态链接库(DLLs)AVIHVWR.DLL和AVIHAPP.DLL一起,提供给你为音频-视频交互(AVI)文件指定热点的能力,正如你可以通过分段的超级绘图热点编辑器(SHED.EXE)为设备无关位图(DIB)文件指定热点一样。这个AVI热点工具包可以与Microsoft_ Multimedia Viewer或通过应用正确的DLL与一个独立的应用程序配合使用。
AVI热点编辑器允许你在你的AVI文件中绘制热点并在热点信息文件中保存它们,该文件是当你在AVI热点DLL中调用函数hspPlayAVI时指定的。

AVI热点工具包允许你做的工作:

? 为每一个热点指定起始帧和终止帧,譬如,两个热点可以覆盖一重叠区域,只要它们的起始帧和终止帧不重叠。
? 在选择了一个热点后,可执行任何浏览器命令或向你的独立调用的应用程序发送消息;另外,当一个热点被选中,你可以继续或终止播放或跳转到同一AVI文件的其它地方。
AVI热点编辑器
你可以应用AVI热点编辑器为你的音频-视频交互文件生成并编辑热点。多个热点可以覆盖重叠的区域只要它们的起始帧和终止帧不重叠。对于每一个热点,你可以指定一命令字符串,一个热点标识号,和(可选的)起始帧与终止帧。
应用热点编辑器
加载热点编辑器后,选择文件打开菜单项以打开一个AVI文件。你将被提示打开热点(.INI)文件。如果对于该AVI文件你是第一次生成热点文件,选择取消,因为你不需要打开一个.INI文件。
一旦AVI文件被加载,你就可以开始在该文件中绘制热点了。为了实现此工作,单击鼠标左键,按住并绘制你需要的热点。要指定热点的属性,在已创建的矩形中双击。要调整某一热点的位置,将鼠标光标放在该矩形中间,单击鼠标按纽,在按住按纽的同时移动矩形。要改变热点的尺寸,单击并拖拽热点的一个边界即可。你可以删除一个热点,通过单击矩形框的内部并按下删除键,或者在热点菜单中选择删除指定热点的选项。
当一个热点被选中,它的矩形坐标将显示在选中热点信息窗中。
热点属性
在热点属性对话框中,你可以指定下述信息:
? 一个命令字符串,是当选中热点(例如,你可能指定sndPlaySound(‘hello.wav’.1))后,在浏览器中运行的命令。
? 一个热点标识号(例如,热点1)。
? 热点边界框,即,它的矩形坐标。
? 热点的活动帧(以便可以在不同的帧中为覆盖的矩形区域指定多于一个的热点)。
? 热点选择选项,当热点被选中时它可以改变AVI文件的方式,如继续播放,终止播放,或跳转到同一AVI文件的其它指定帧。
保存热点文件
一旦你为特定的AVI文件绘制了热点,请确认你已指定了一个热点标识号,并且如果合适的话,对每一个热点均有一个命令字符串。然后,从文件菜单中选取保存并键入文件名。如果你还没有为每一个热点选择一个标识号,你将收到一个错误信息。
其它特性
工具包允许你为每一个热点指定不同的活动帧,以便你可以选择只看当前在编辑器中显示的帧的活动热点(从热点菜单中选择“只显示当前帧中的热点”选项),或者选择AVI文件中的全部热点,与正在显示的帧无关。
热点信息文件格式
AVI热点编辑器应用WritePrivateProfileString来编写热点信息文件,因而文件中所有的条目均有正规.INI文件格式。该.INI文件必须包含一个[设置]部分,一个[热点]部分,和至少一个热点的信息。每一个热点在它的热点标识号下保存。
[设置]部分有如下的格式:
[Configuration]
Version=1.00
Editor=AVIHED
当前的版本号(Version)是1.00。编辑器(Editor)条目通常是AVIHED。

[热点]部分有如下格式:HotspotID=1。热点的标识号可以是指定值为=1的任何名称,例如:
[Hotspots]
Ears=1
Eyes=1
Door=1
Window=1

对于[热点]区的每一个条目,一定有一个相应的热点条目,例如:
[Door]
Rect = 247, 17, 281, 71
Command = sndPlaySound (‘n.wav’,1)
BeginFrame = 0
EndFrame = 101
OnClick = 1018
ToFrame = 0

在这里,
? Rect是热点的位置,依左、上、右、下的格式。
? Command是当热点被选中时执行的命令。
? BeginFrame是热点被激活的第一帧。
? EndFrame是热点被激活的最后一帧。
? OnClick可以是以下三个值之一:ID_CONTINUE, ID_STOP, 或ID_JUMP。这些值定义在RESOURCE.H文件中。
? ToFrame是当OnClick指定为ID_JUMP时跳转到的帧。
有关编程问题
在AVI帧上绘图
我发现在AVI文件上绘图的最有效方法是应用Video for Windows。当你在窗口过程中收到WM_PAINT消息,使用MCI_UPDATE命令来刷新窗口,并通过BeginPaint返回设备相关句柄。当命令返回后(应用MCI_WAIT标志),即可绘制热点矩形(或者任何你所希望绘制的东西)。
编辑器应用MCI_STOP命令代替MCI_PAUSE命令来停止播放AVI文件,因为应用MCI_PAUSE命令将导致热点矩形的绘制错误。即便你使用了带有 MCI_WAIT标记的MCI_PAUSE命令,在MCI_PAUSE返回时,Video for Windows在mciSendCommand(命令)之后完成绘制,它将导致矩形被隐藏。你还可以应用MCI_STEP来分步当前帧,尽管MCI_STOP在一步内可完成这些工作。
如果你希望使用Video for Windows为你创建的窗口来替代你自己的,你将需要子类视频窗口。这可以通过从由MCI_PAUSE命令提供的返回信息得到AVI窗口来实现。在子类进程中,截取WM_PAINT消息然后应用MCI_UPDATE命令调用mciSendCommand。不要调用旧的窗口进程,因为这将引起你绘制的输出结果被隐藏在AVI文件下面。
不幸的是,还没有一个好的方法可以在一个AVI文件播放时在它上面绘制对象。如果以一帧一帧来绘制,将降低AVI文件的显示速度并发生闪烁。
绘制热点
最初,我应用Microsoft _ Windows Software Development Kit(SDK)的SHOWDIB示例中的矩形绘图函数。但是,当我处理采用很淡的颜色或多色的AVI文件时,反转热点矩形不能足够清楚地显示。在选择多色画笔后将PatBlt应用到设备上下文(DC)中将使反转清晰许多。另一种可能方法是,存储当前帧的一个离屏的DC,在Window DC上绘制彩色线,并当线的位置改变时从离屏的DC到窗口应用BitBlt。这可以通过调用mciSendCommand,使Video for Windows将当前帧绘制到离屏的DC中得以实现,但这一过程是耗时的,并且将导致矩形的移动速度降低。
改进建议
? 撤消功能。
? 打印当前热点信息/AVI帧。
? 可视化热点的选择。
? 多文档界面(MDI)以支持同时处理多个AVI文件。
? 通过应用CreatePolygonRgn函数和一系列的点支持多边形。
AVI热点DLLs
有两个AVI热点动态链接库(DLLs):AVIHVWR.DLL,它可以通过在浏览器应用程序的MVP工程文件中指定,以便与浏览器应用程序配合使用;和AVIHAPP.DLL,你可以将它与你的独立应用程序连接。对Visual Basic的支持尚未实现,但有关的建议在本文后面的“改进建议”中有相应的描述。
有关编程问题
多浏览器/应用程序实例应用同一DLL
由于每一DLL只能有一个实例但有多个应用程序或应用程序的实例调用每个DLL,热点DLL与每一调用它的应用程序(实例)的结构相关联。它应用的结构称为MOVIEINFO结构,定义在HOTSPOT.H中。有两种方法可以将信息与窗口连接起来:可以编写你自己的函数来匹配全局数据句柄和窗口句柄,并得到这些连接的清单;或者应用SetProp/GetProp/RemoveProp函数,它允许你为窗口指定16位值(如,全局分配内存的句柄)。DLL输出函数hapPlayAVI调用SetProp,每当子类过程被调用时它将调用GetProp,以获得有关影片的信息,如前次过程调用的地址。最后,当子类进程收到WM_DESTROY信息时,它调用 RemoveProp以将影片信息从窗口中删除。
对Visual Basis的支持
尽管DLL已经可以与Visual Basic结合使用,但遗憾的是,当热点被选中后,它不能将信息返回给Visual Basic应用程序。为了实现应用SendMessage给Visual Basic应用程序发送消息或应用从DLL到应用程序(正如操作非Visual Basic的独立应用程序)的回调函数,你必须将basic VBX功能加入到DLL中或编写单独的VBX,它可以从Visual Basic应用程序输出回调函数或通过将它所在的表单分为子类来截获新的消息(该消息尚未在Visual Basic中执行)。
热点
AVI文件的热点可以从.INI文件中读取并存储在双链接表中。每当用户单击影片窗口(引起WM_LBUTTONDOWN消息的发送),子类函数调用一个函数,该函数为列表中的每一个热点调用PtInRect函数以决定当用户按下鼠标按纽时,鼠标光标指向哪一个热点矩形(如果有的话)。浏览热点列表,在决定点是否在热点矩形内之前, 该函数将检查对于当前显示的帧热点是否有效,即,当前帧是否在热点的起始帧和终止帧之间。

对于浏览器DLL(AVIHVWR.DLL),函数调用VwrCommand如下:

VwrCommand (VwrFromHinst (GetWindowWord (hwnd, GWW_HINSTANCE) ),
	NULL, pHotspot->pszCommand, comdoptNONE)

由于浏览器需要将VWR结构指定为VwrCommand的第一个参数,函数通过应用GetWindowWord获得实例句柄;hwnd参数是通过如下的函数调用获得的:

hwnd = GetParent (pMovieInfo -> hwndParent);
	if (!hwnd) hwnd = pMovieInfo-> hwndParent;

这里的pMovieInfo是从子类过程传递到函数的指向MOVIEINFO结构的指针。

对于独立的应用程序DLL(AVIAPP.DLL),DLL执行回调函数作为hspPlayAVI DLL函数的最后一个参数传递。这个回调函数定义在应用程序中,即在.DEF文件中导出函数,然后调用MakeProcInstance并将它的返回值传递给hspPlayAVI函数。当应用程序收到WM_DESTROY消息,它将调用FreeProInstance。另外,应用有WM_USER+××××消息的SendMessage或(作为一个hack)对wParam有一定值的WM_COMMAND也是一种可行的方法。但应用回调函数似乎是最直接和最有效的解决方案。
应用DLLs
浏览器(AVIHVWR.DLL)和独立的应用程序 (AVIAPP.DLL)的DLLs是分开的。
应用浏览器
要在浏览器中应用热点DLL,应在你的浏览器应用程序的.MVP工程文件中的[设置]部分指定如下命令:
RegisterRoutine (“AVIHVWR”,”hspPlayAVI”,”I=USS”)
在你的浏览器.RTF文件中,指定一些文本或位图,然后在隐藏文本中指定如下命令行:
!hspPlayAVI (hwndContext,’AVIFILE.AVI’,’HSPFILE.INI’)
在这里,AVIFILE.AVI是播放的AVI文件的文件名,HSPFILE.INI是包含了AVI文件热点信息的INI文件的文件名。hwndContext是浏览器定义的变量;要获取详尽信息,请查阅浏览器的文档。
应用独立的应用程序
要和独立的应用程序一起应用热点DLL,需将AVIHAPP.LIB加入到你的链接语句中。它包含AVIHAPP.H,其中定义了hspPlayAVI函数的原型。要调用hspPlayAVI函数,你需要输出一个回调函数,使DLL可以调用它以通知你热点已被选中。要应用带有热点的AVI文件,需调用hspPlayAVI函数,以AVI文件的文件名作为第一个参数,以包含热点信息的.INI文件的文件名作为第二个参数,并通过以你的输出回调函数的名称调用的MakeProcAddress返回地址。当你的应用程序窗口收到一个WM_DESTROY消息,它将调用FreeProcAddress.

回调函数必须遵循如下的语法:

BOOL _export hspAVICallback ( HWND hwndParent, HWND hwndMovie, WORD wMessage, FAR * lParam1, LONG FAR * lParam2)
这个回调函数应该处理WM_SIZE和WM_LBUTTONDOWN消息。(注意它们不是作为消息而是作为命令标识符,定义给定的参数将引起何种作用,如果有的话。)如果回调函数成功地处理了一个消息,它将返回TRUE;如果不是,它将返回FALSE。
如果wParam参数是WM_SIZE:回调函数将可以调整在影片被显示前影片播放的窗口尺寸。lParam1是一个指向定义影片尺寸的RECT结构的长指针。
如果wParam参数是WM_LBUTTONDOWN:用户选择了热点。lParam1是一个包含了热点标识号的LPSTR,lParam2是一个包含了热点命令的LPSTR。
AVIHRUN的范例(独立的)
AVIHRUN示例程序演示了如何调用hspPlayAVI,如何执行回调函数,以及如何在回调函数中处理消息。另外,它提供了一个简单的命令语言,它支持如下两个命令:

? sndPlaySound
? ExecProgram (或者 WinExec)

两个命令都和与之相应的浏览器具有相同的语法。
改进建议
AVI热点编辑器和DLLs,为浏览器和独立应用程序中的AVI热点界面,提供了框架结构和基本但可用的功能。对于当前代码的改进建议包括:

? 通过VBX以支持Visual Basic。
? 多命令支持以便,譬如,你可以播放一个.WAV文件并执行一个命令。
? 最好独立于设备、支持指定坐标。
? 扩展AVIHRUN命令语言成为一个丰满的实时应用程序,以便分布AVI和热点文件,增加更多的功能。一些不仅仅调用WinExec(例如,在DLLs中支持外部函数)的扩展模板界面可能是有价值的。
? 应用资源交换文件格式(RIF)将热点信息与AVI文件和由AVIHRUN应用程序可能执行的命令结合起来,对于AVI文件将是一个优秀的扩展。在极少的情况下,可应用一些编译的或二进制文件代替.INI文件存储热点信息。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -