SWF 从 res 文件中取文件播放(在线等,立结) ( 积分: 200 )

  • 主题发起人 主题发起人 newlife2005
  • 开始时间 开始时间
N

newlife2005

Unregistered / Unconfirmed
GUEST, unregistred user!
加了flash控件后可以播硬盘上的swf 文件。
SWF1.Movie :=ExtractFilePath(Application.ExeName)+ 'welcome.swf';
swf1.Play;
现在SWF导入到RES 资源文件中,FLASH控件如何调SWF?
 
加了flash控件后可以播硬盘上的swf 文件。
SWF1.Movie :=ExtractFilePath(Application.ExeName)+ 'welcome.swf';
swf1.Play;
现在SWF导入到RES 资源文件中,FLASH控件如何调SWF?
 
几乎每个Windows应用程序都使用图标、图片、光标等资源。资源是程序的一部分,但是它是不可执行代码。下面我们就详细介绍资源文件在Delphi5中建立和使用方法。

1.把资源放到Exe文件的优点
由于定位资源比在磁盘中定位文件花费时间少,所以应用程序执行会更快。多种资源可以放在一个文件中,减少了图标、图片、光标等文件数量。保存资源文件时不要和工程名相同,因为Delphi创建工程时会自动创建一个和工程名相同的资源文件。并且最好将资源文件保存到和工程文件同一个文件夹中。

2.创建资源文件
首先创建一个.Rc的纯文本文件。格式如下:
资源标识符 + 关键字 + 资源文件名
① 资源标识符:程序中调用资源时的特殊标号;
② 关键字:标识资源文件类型;
Wave: 资源文件是声音文件;
RCDATA: JPEG文件;
AVI: AVI动画;
ICON: 图标文件;
BITMAP: 位图文件;
CURSOR: 光标文件;
资源文件名:资源文件名;
③ 资源文件名:编译的资源文件,比如动画、位图、光标等;
④ 如:MyWav WAVE "FileName.Wav"

使用Borland资源编译器(BRCC32.EXE)转化.Rc文件成.Res文件。在DOS命令行下输入下列命令:
Brcc32 FileName.Rc // Brcc32.Exe在Delphi5/Bin文件下。

3.在工程中引用资源文件
为了存取我们的资源文件,必须告诉Delphi链接我们的资源文件到应用程序中。因此我们可以在源代码中加入一条编译指令完成上述功能。这条指令必须紧跟在窗口指令后,如下形式:
{$R *.DFM} //Delphi自带编译指令
{$R FileName.Res} //新加入的编译资源文件的指令。
不要删除{$R *.DFM}指令,因为这行代码告诉Delphi链接下面的资源到窗口的资源中。

4.调用资源文件
(1)存取资源文件中的位图(Bitmap)
程序中如果想存取资源,你必须调用一些Windows API函数。保存在资源文件中的位图、光标和图标可以通过调用LoadBitmap、LoadCursor和LoadIcon函数存取。
本例举例说明如何存取资源文件中位图并显示在Timage控件中。
procedure TfrMain.btnCanvasPic(Sender: TObject);

Image1.Picture.Bitmap.Handle :=LoadBitmap(hInstance
'资源标识符');
end;


注:如果位图没有装载成功,程序仍旧执行,但是Image将不再显示图片。你可以根据LoadBitmap函数的返回值判断是否装载成功,如果装载成功返回值是非0,如果装载失败返回值是0。

另外一个存取显示位图的方法如下
procedure TfrMain.btnLoadPicClick(Sender: TObject);

begin

Image1.Picture.Bitmap.LoadFromResourceName(hInstance
'资源标识符');

end;


(2)存取资源文件中的光标
Screen.Cursors[]是一个光标数组,使用光标文件我们可以将定制的光标加入到这个属性中。因为默认的光标在数组中索引值是0,所以除非想取代默认光标,最好将定制的光标索引值设为1。
procedure TfrMain.btnUseCursorClick(Sender: TObject);
begin

Screen.Cursors[1] :=LoadCursor(hInstance
'资源标识符');
Image1.Cursor :=1;
end;

(3)存取资源文件中的图标
将图标放在资源文件中,可以实现动态改变应用程序图标。
procedure TfrMain.LoadIconClick(Sender: TObject);
begin

Application.Icon.Handle := LoadIcon(hInstance
'资源标识符');
end;

(4)存取资源文件中的AVI
procedure TfrMain.LoadIconClick(Sender: TObject);
begin

Animate1.ResName :='MyAvi' ;
//资源标识
Animate1.Active :=True ;
End ;
(5)存取资源文件中的JPEG
把jpeg单元加入到Interface的uses单元中。
procedure TForm1.LoadJPGClick(Sender: TObject);
var
Fjpg : TJpegImage ;
FStream :TResourceStream ;
begin

Fjpg :=TJpegImage.Create ;
FStream := TResourceStream.Create (Hinstance
'资源标识符'
RT_RCDATA) ;
FJpg.LoadFromStream (FStream) ;
Image1.Picture.Bitmap.Assign (FJpg);
end;

(6)存取资源文件中的Wave
把MMSystem加入到Interface的uses单元中
procedure TForm1.LoadWaveClick(Sender: TObject);
begin

PlaySound('MyWav'
HInstance
Snd_ASync or Snd_Memory or snd_Resource) ;
end;

5.结束语
位图、光标和图标、AVI动画、JPEG和Wave文件等可以放到资源文件中,上面我们介绍了如何将资源加入到资源文件中,并介绍了在Delphi中动态存取资源文件的方法。Delphi编译工程会自动创建一个和工程名相同的资源文件(如果没有其他的资源,主窗口的图标会放在这个资源文件中)。但是建议最好不要改变这个资源文件。
[全文结束]
 
var
Res: TResourceStream;
begin

Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType));
//第二个参数是资源的名字,第三个参数是资源的类型
Res.SavetoFile(ResNewName);
//保存到一个临时目录下
//与播放硬盘上的一样了
 
参考这个帖子:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1098821

估计你只能在程序运行时,把swf文件从RES资源文件导出,保存,然后再播放。
 
谢谢!
问题是不想用文件播放,是不是现在的flash控件只能从硬盘上播,没法在内存中播?
 
那就自己研究Swf文件格式,自己解析Byte流,并自己画到Canvas,呵呵,说了点儿废话

关注,偶也想知道
 
查了好些资料,没找到从内存流中播的,是不是一定不行?
 
目前来说一定不行.
 
前一段有人声称可以在内存中播放,不过没有公布思想。
 
看来是个难题,等待高手出手....
 
有人做过,便那人不公开。

目前无法。
 
研究一下macromedia的flash播放器吧,它把flash做成播放器后就不是用文件的方式播放了,大概你得找到flash的SDK才行
 
转一个

内存播放Flash。
文章发表:whoo 发表日期:2005-04-02 阅读次数:32
前提:
被要求Flash必须加密,不能在硬盘上留下文件。

起点:
Flash 播放器的属性Movie接受本地文件名 或者 HTTP URL。

首先当然是在网络上寻找解决方案了。找了半天,发现一个国内的,一个国外的。都在出售。
奇怪的是,他们不约而同的都是用了Delphi。
根据了解的人透露,它是利用了Flash一个未公开的属性MovieData, 该属性文档中没有记录,但是从名称可以看出应该是应该是接受数据片的。

其国内的那一版目前还不支持最新的flash播放器。这让人不能不有点担忧。 因此还是尽量照自己的思路来。


思路:
最开始考虑的就是建一个协议(类似于rtsp的样子)来代替http,并把请求转到本地守护进程。
后来又想到还不如直接建立一个简陋的http服务器,直接使用http url , 这样子肯定是可行的,于是就着手写http服务器了。
写了个简单的测试程序,监听了一些http包,发现即使建立个简陋的http服务器,也需要了解一下rfc2612的,考虑到flash不同版本可能识别的响应及其标签,响应头还是蛮复杂的。
看rfc2612的时候突然想到, 建立http服务器是虚拟一个url;如果能够虚拟一个本地文件名,是不是更简单些呢? 照着这个思路,找了个把小时,当然也走了不少的弯路。最终发现可以用管道来处理。

因为管道客户端也是用CreateFile, ReadFile来处理的, 与普通文件一样。这样子就可以用管道名称来代替文件名来欺骗一下flash乐^_^

被欺骗的Flash读文件的时候:CreateFile, ReadFile实际上是读的是管道,只是他自己不知道而已. 而我们可以向管道写入任何内容,这不就达到目的了么?

写了段代码验证了一下,确实可行。 而且还模拟了网络的流环境(每次读10字节,延迟3ms),发现效果不错,正如预料的一样。

下面贴出来的代码来资源是测试程序,比较零乱。如果你仔细看了上面的内容,并且对于提到的属于没什么不解的话,应该就不用看下面的代码了。 附上来仅仅是为了备忘。

代码是一个console程序, vs2003环境。
假设有个样例Flash为Blue.swf。
设定的管道名称为: //./pipe/egbpipe

验证时先运行本程序,并保证blue.swf存在。然后打开flash播放器,用她播放文件"//./pipe/egbpipe"。

代码开始:
-------------
// PipeService.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#define BUFSIZE 1024
#define PIPE_TIMEOUT 1000

int __main(void);
int MyErrExit(char*);
int _tmain(int argc, _TCHAR* argv[])
{
__main();
return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

VOID InstanceThread(LPVOID);

VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD);

VOID GetAnswerToRequest(HANDLE hFile);

int xx = 0;



/*

//./pipe/egbpipe

*/

int __main(void)
{
BOOL fConnected;

DWORD dwThreadId;

HANDLE hPipe, hThread;

LPTSTR lpszPipename = &quot;////.//pipe//egbpipe&quot;;


// The main loop creates an instance of the named pipe and
// then
waits for a client to connect to it. When the client
// connects, a thread is created to handle communications
// with that client, and the loop is repeated.

for (;;)
{
hPipe = CreateNamedPipe(
lpszPipename, // pipe name
PIPE_ACCESS_DUPLEX, // read/write access
PIPE_TYPE_MESSAGE | // message type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
BUFSIZE, // output buffer size
BUFSIZE, // input buffer size
PIPE_TIMEOUT, // client time-out
NULL);
// no security attribute

if (hPipe == INVALID_HANDLE_VALUE)
MyErrExit(&quot;CreatePipe&quot;);


// Wait for the client to connect;
if it succeeds,
// the function returns a nonzero value. If the function returns
// zero, GetLastError returns ERROR_PIPE_CONNECTED.

fConnected = ConnectNamedPipe(hPipe, NULL) ?
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);


if (fConnected)
{
// Create a thread for this client.
hThread = CreateThread(
NULL, // no security attribute
0, // default stack size
(LPTHREAD_START_ROUTINE) InstanceThread,
(LPVOID) hPipe, // thread parameter
0, // not suspended
&amp;dwThreadId);
// returns thread ID

if (hThread == NULL)
MyErrExit(&quot;CreateThread&quot;);

else

CloseHandle(hThread);


}
else

// The client could not connect, so close the pipe.
CloseHandle(hPipe);

}
return 1;

}

VOID InstanceThread(LPVOID lpvParam)
{
CHAR chRequest[BUFSIZE];

CHAR chReply[BUFSIZE];

DWORD cbBytesRead, cbReplyBytes, cbWritten;

BOOL fSuccess;

HANDLE hPipe;


// The thread's parameter is a handle to a pipe instance.

hPipe = (HANDLE) lpvParam;


// while (1)
{
// Read client requests from the pipe.
/* fSuccess = ReadFile(
hPipe, // handle to pipe
chRequest, // buffer to receive data
BUFSIZE, // size of buffer
&amp;cbBytesRead, // number of bytes read
NULL);
// not overlapped I/O

if (! fSuccess || cbBytesRead == 0)
break;

*/
//GetAnswerToRequest(chRequest, chReply, &amp;cbReplyBytes);

GetAnswerToRequest(hPipe);
/*
// Write the reply to the pipe.
fSuccess = WriteFile(
hPipe, // handle to pipe
chReply, // buffer to write from
cbReplyBytes, // number of bytes to write
&amp;cbWritten, // number of bytes written
NULL);
// not overlapped I/O

// if (! fSuccess || cbReplyBytes != cbWritten) break;

*/ }

// Flush the pipe to allow the client to read the pipe's contents
// before disconnecting. then
disconnect the pipe, and close the
// handle to this pipe instance.

FlushFileBuffers(hPipe);

DisconnectNamedPipe(hPipe);

CloseHandle(hPipe);

}

int MyErrExit(char* szInfo)
{
return MessageBox(0, szInfo, &quot;Whoo&quot;, MB_OK);
}

VOID GetAnswerToRequest(HANDLE hFile)
{
const int BuffLen = 10;
byte buff[BuffLen] = {0};

FILE* f = fopen(&quot;blue.swf&quot;, &quot;rb&quot;);

int iLen = BuffLen;
while(iLen == BuffLen)
{
iLen = fread(buff, sizeof(byte), BuffLen, f);

Sleep(3);
DWORD uLen = 0;
WriteFile(hFile, buff, iLen, &amp;uLen, NULL);
}
_fcloseall( );
}

作者Blog:http://blog.csdn.net/whoo/
 
测试一下先,谢谢tseug
 
有没有DELPHI的啊!
谁能共享一下啊!
 
对啊,有没delphi的
 
qq:171833017,http://www.websamba.com/dxmylove
我解决了这个问题,联系我
 
播放Flash资源文件

procedure FlashResToFile(const ResName, ResType, FileName: string);
var
FlashRes: TResourceStream;
begin

FlashRes := TResourceStream.Create(HInstance, ResName, PChar(ResType));
try
FlashRes.SaveToFile(FileName);
//将资源保存为文件,即还原文件
finally
FlashRes.Free;
end;

end;


procedure TFlashResFrm.PlayResFileBtnClick(Sender: TObject);
begin

if FileExists(ExtractFilePath(ParamStr(0)) + 'Thanks.SWF') then

DeleteFile(ExtractFilePath(ParamStr(0)) + 'Thanks.SWF');
FlashResToFile('FLASH', 'SwfFile1', 'Thanks.SWF');
ShockwaveFlash1.Movie := ExtractFilePath(ParamStr(0)) + 'Thanks.SWF';
ShockwaveFlash1.Play;
end;
 
后退
顶部