WPF中实现对Flash的播放

方案一:用WebBrowser实现

要想实现Flash的播放支持,需要借助Flash自身的ActiveX控件.

  而WPF作为一种展现层的技术,不能自身插入COM组件,必需借助Windows Form引入ActiveX控件.

比较标准的实现方法,可以参考以下链接:http://blogs.msdn.com/b/jijia/archive/2007/06/07/wpf-flash-activex.aspx

而本文则是介绍通过借助System.Windows.Forms下的WebBrowser实现.

  但无论是那一种方法,本质上都是通过在WPF程序中引用Windows Form窗体,再在其内引入ActiveX控件.

  实现对Flash的播放


  首先,引入可在WPF上承载 Windows 窗体控件的元素:WindowsFormsHost,及添加对 Windows 窗体的引用.

  具体的实现过程:项目引用--添加引用--程序集中选择 "WindowsFormsIntegration" 及 "System.Windows.Forms" --添加

  在WPF页面分别添加这两者的引用:

xmlns:host="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"

xmlns:forms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

XAML中的所有实现代码:

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:host="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"

        xmlns:forms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

        Title="File Capture" Height="600" Width="800"

        Unloaded="Window_Unloaded"

        >

   

       

           

           

       

       

           

       

       

           

               

               

               

                Loop Capture

           

       

   

当需要把一选中的Flash文件(.swf 文件)添加进WebBrowser 中播放:browser.Navigate(currentPath);

实现对Flash的截图

  实现对Flash的截图,只要使用WebBrowser的基类WebBrowserBase里面的DrawToBitmap方法.

  参数Bitmap为所绘制的位图(需初始化位图的大小),Rectangle为截取WebBrowser内容的区域(大小)

public voidDrawToBitmap(

Bitmap bitmap,

Rectangle targetBounds

)

具体的实现代码:

private void Capture()

        {

            string fileName = System.IO.Path.GetFileNameWithoutExtension(currentPath);

            string capturePath = string.Format("{0}\\Capture\\{1}", System.Environment.CurrentDirectory, fileName);

            if (!Directory.Exists(capturePath))

            {

                Directory.CreateDirectory(capturePath);

            }

            Bitmap myBitmap = new Bitmap((int)host.ActualWidth, (int)host.ActualHeight);

            System.Drawing.Rectangle DrawRect = new System.Drawing.Rectangle(0, 0, (int)host.ActualWidth, (int)host.ActualHeight);

            browser.DrawToBitmap(myBitmap, DrawRect);

            string timeNow = DateTime.Now.ToString("yyyyMMddHHmmssfff");

            myBitmap.Save(string.Format("{0}\\{1}_{2}.png", capturePath, fileName, timeNow));

        }

本实例实现了对Flash的循环截图,时间间隔为1秒.本部分比较简单,

通过使用System.Windows.Threading下的DispatcherTimer即可实现.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

using Microsoft.Win32;

using System.Drawing;

using System.IO;

using System.Windows.Threading;

namespace Capture

{

    ///

    /// MainWindow.xaml 的交互逻辑

    ///

    public partial class MainWindow : Window

    {

        private string currentPath;

        private DispatcherTimer captureTimer;

        public MainWindow()

        {

            InitializeComponent();

        }

        private void btnOpen_Click(object sender, RoutedEventArgs e)

        {

            currentPath = OpenUserFileDialog();

            if (!string.IsNullOrEmpty(currentPath))

                LoadedFile();

        }

        private void btnCapture_Click(object sender, RoutedEventArgs e)

        {

            if ((bool)cboxLoop.IsChecked)

                RunTimer();

            else

                Capture();

        }

        private void btnStop_Click(object sender, RoutedEventArgs e)

        {

            if (captureTimer != null && captureTimer.IsEnabled)

                captureTimer.Stop();

        }

        private string OpenUserFileDialog()

        {

            string pathFile = string.Empty;

            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.FilterIndex = 1;

            openFileDialog.Multiselect = false;

            openFileDialog.AddExtension = true;

            openFileDialog.ValidateNames = true;

            if (openFileDialog.ShowDialog().Equals(true))

                pathFile = openFileDialog.FileName;

            return pathFile;

        }

        private void LoadedFile()

        {

            try

            {

                browser.Navigate(currentPath);

            }

            catch { }

        }

        private void Capture()

        {

            string fileName = System.IO.Path.GetFileNameWithoutExtension(currentPath);

            string capturePath = string.Format("{0}\\Capture\\{1}", System.Environment.CurrentDirectory, fileName);

            if (!Directory.Exists(capturePath))

            {

                Directory.CreateDirectory(capturePath);

            }

            Bitmap myBitmap = new Bitmap((int)host.ActualWidth, (int)host.ActualHeight);

            System.Drawing.Rectangle DrawRect = new System.Drawing.Rectangle(0, 0, (int)host.ActualWidth, (int)host.ActualHeight);

            browser.DrawToBitmap(myBitmap, DrawRect);

            string timeNow = DateTime.Now.ToString("yyyyMMddHHmmssfff");

            myBitmap.Save(string.Format("{0}\\{1}_{2}.png", capturePath, fileName, timeNow));

        }

        private void RunTimer()

        {

            if (captureTimer == null)

                captureTimer = new DispatcherTimer();

            captureTimer.Interval = TimeSpan.FromMilliseconds(1000);

            captureTimer.Tick += captureTimer_Tick;

            if (!captureTimer.IsEnabled)

                captureTimer.Start();

        }

        private void captureTimer_Tick(object sender, EventArgs e)

        {

            Capture();

        }

        private void Window_Unloaded(object sender, RoutedEventArgs e)

        {

            try

            {

                browser.Dispose();

            }

            catch { }

        }

    }

}


方案二:将Flash 嵌入WPF 程序

https://www.cnblogs.com/gnielee/archive/2010/07/27/wpf-flash-activex.html

https://blog.csdn.net/xingxing513234072/article/details/8919596

http://blog.sina.com.cn/s/blog_952cdb2a0100xl1f.html

 由于WPF 本身中不支持COM 组件同时也无法加载ActiveX 控件,所以需要借助WinForm 引用ActiveX 控件将Flash 加入其中。首先创建一个WPF 项目(WpfFlash),将Flash 文件(.swf)加入到项目中,并将Copy to Output Directory 设置为"Copy always"。

WPF中实现对Flash的播放_第1张图片

     在工程中新增一个Windows Forms Control Library 项目(FlashControlLibrary),利用该控件库加载Flash ActiveX。

WPF中实现对Flash的播放_第2张图片
WPF中实现对Flash的播放_第3张图片

     在FlashControlLibrary 项目工具栏(Toolbox)中点击鼠标右键,选择"Choose Items..."。在COM Components 标签中选择"Shockwave Flash Object",点击确定。


WPF中实现对Flash的播放_第4张图片

此时在工具栏中已经可以看到刚添加的Shockwave Flash Object 控件了。将控件拖入设计窗口,调整好控件尺寸使其满足Flash 的尺寸大小,对FlashControlLibrary 项目进行编译,并生成DLL 文件。


WPF中实现对Flash的播放_第5张图片
WPF中实现对Flash的播放_第6张图片

     返回WpfFlash 项目将上面编译的AxInterop.ShockwaveFlashObjects.dll 加入References,并添加System.Windows.Forms 和WindowsFormsIntegration,便于WinForm 程序在WPF 中交互使用。

WPF中实现对Flash的播放_第7张图片


WPF中实现对Flash的播放_第8张图片

接下来将通过两种方式将Flash 文件加入到WPF,一种侧重于使用XAML 代码实现,另一种则使用C#。可按各自需要选择其一。

XAML 方法

     打开MainWindow.xaml,加入命名空间xmlns:f="clr-namespace:AxShockwaveFlashObjects;assembly=AxInterop.ShockwaveFlashObjects"。在中加入WindowsFormsHost 用于调用WinForm 程序,并在其中添加AxShockwaveFlash 控件加载Flash 文件。

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:f="clr-namespace:AxShockwaveFlashObjects;assembly=AxInterop.ShockwaveFlashObjects"

        Title="Crab Shooter" Height="540" Width="655">

   

       

           

       

   

打开MainWindow.xaml.cs 将Flash 文件加载到flashShow 控件。

using System;using System.Windows;namespace WpfFlash{    public partial class MainWindow :Window

    {public MainWindow()        {            InitializeComponent();string flashPath =Environment.CurrentDirectory;            flashPath +=@"\game.swf";            flashShow.Movie = flashPath;        }    }}

C# 方法

使用C# 实现相同的效果,首先将XAML 代码按如下方式修改,在Window 中加入Loaded 事件。

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="Crab Shooter" Loaded="FlashLoaded" Height="540" Width="655">

   

定义FlashLoaded 方法,主要通过WindowsFormsHost和 AxShockwaveFlash 完成Flash 加载操作。

using System;using System.Windows;using System.Windows.Forms.Integration;using AxShockwaveFlashObjects;namespace WpfFlash{public partial class MainWindow :Window

    {public MainWindow()        {            InitializeComponent();        }private void FlashLoaded(object sender,RoutedEventArgs e)        {WindowsFormsHost formHost =new WindowsFormsHost();AxShockwaveFlash axShockwaveFlash =new AxShockwaveFlash();            formHost.Child = axShockwaveFlash;            mainGrid.Children.Add(formHost);string flashPath =Environment.CurrentDirectory;            flashPath +=@"\game.swf";                        axShockwaveFlash.Movie = flashPath;        }    }}

效果图

你可能感兴趣的:(WPF中实现对Flash的播放)