• 如何实现用windows phone控制PowerPoint的播放


      相信大家都有过演讲的经历,当我们演讲时,一手拿着windows phone手机按按键就可以操作powerPoint幻灯片的播放,是不是显得比较高端?你如果想了解这种互动是怎么实现的,那么你可以继续往下看。

      使用windows phone操作PC的PPT播放并不是一件多难的事儿,同样是对于android和IOS移动端,主要涉及到两个方面:通信和调用PowerPoint 的API。对于第一方面,既然手机端可以控制PC端,那么他们之间必然有信息传递,你可以使用手机的蓝牙和电脑的蓝牙进行通信,不过考虑到现在的PC还有很多不支持蓝牙,再加上蓝牙传输可能并不稳定,所以在这里我们可以使用Socket进行通信;对于第二方面,也很简单,我们只需要在PC端去调用PowerPoint的API就OK,主要涉及的操作包括:切换幻灯片到第一张、切换幻灯片到下一张、切换幻灯片到上一张、切换幻灯片到最后一张。

      举个例子来说,我们当用手机点击上一页按钮时,会传递一个数字a到服务端,服务端会判断这个数字a是要执行切换到上一页操作的命令,所以我们就调用切换到上一页的API,就能成功实现切换,所以如果想实现这个功能不仅仅需要手机客户端,还需要一个PC的服务端用来接收手机端发来的消息并进行处理,当然手机端需要输入PC端IP和端口来和PC端通信,我在这里仅实现了最基本的功能,其他功能可以在此基础上进行扩展。

      下面首先介绍服务端调用PowerPoint API 的代码:(参考了貌似是一位微软工程师的博客)

      

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Runtime.InteropServices;
      5 using System.Text;
      6 using System.Threading.Tasks;
      7 using PPt = Microsoft.Office.Interop.PowerPoint;
      8 namespace ServerPPT
      9 {
     10     class PPTServer
     11     {
     12         // 定义PowerPoint应用程序对象
     13         PPt.Application pptApplication;
     14         // 定义演示文稿对象
     15         PPt.Presentation presentation;
     16         // 定义幻灯片集合对象
     17         PPt.Slides slides;
     18         // 定义单个幻灯片对象
     19         PPt.Slide slide;
     20 
     21         // 幻灯片的数量
     22         int slidescount;
     23         // 幻灯片的索引
     24         int slideIndex;
     25         //检查幻灯片是否已经打开
     26         public void CheckPPT()
     27         {
     28             // 必须先运行幻灯片,下面才能获得PowerPoint应用程序,否则会出现异常
     29             // 获得正在运行的PowerPoint应用程序
     30             try
     31             {
     32                 pptApplication = Marshal.GetActiveObject("PowerPoint.Application") as PPt.Application;
     33 
     34                 // 成功获取了PowerPoint程序时,使UI按钮可用
     35             }
     36             catch
     37             {
     38                 //  MessageBox.Show("请先启动遥控的幻灯片", "Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error);
     39             }
     40             if (pptApplication != null)
     41             {
     42                 //获得演示文稿对象
     43                 presentation = pptApplication.ActivePresentation;
     44                 // 获得幻灯片对象集合
     45                 slides = presentation.Slides;
     46                 // 获得幻灯片的数量
     47                 slidescount = slides.Count;
     48                 // 获得当前选中的幻灯片
     49                 try
     50                 {
     51                     // 在普通视图下这种方式可以获得当前选中的幻灯片对象
     52                     // 然而在阅读模式下,这种方式会出现异常
     53                     slide = slides[pptApplication.ActiveWindow.Selection.SlideRange.SlideNumber];
     54                 }
     55                 catch
     56                 {
     57                     // 在阅读模式下出现异常时,通过下面的方式来获得当前选中的幻灯片对象
     58                     slide = pptApplication.SlideShowWindows[1].View.Slide;
     59                 }
     60             }
     61         }
     62 
     63         //第一页
     64         public  void FirstPage()
     65         {
     66             try
     67             {
     68                 // 在普通视图中调用Select方法来选中第一张幻灯片
     69                 slides[1].Select();
     70                 slide = slides[1];
     71             }
     72             catch
     73             {
     74                 // 在阅读模式下使用下面的方式来切换到第一张幻灯片
     75                 pptApplication.SlideShowWindows[1].View.First();
     76                 slide = pptApplication.SlideShowWindows[1].View.Slide;
     77             }
     78         }
     79         //上一页
     80         public void PreviousPage()
     81         {
     82             slideIndex = slide.SlideIndex - 1;
     83             if (slideIndex >= 1)
     84             {
     85                 try
     86                 {
     87                     slide = slides[slideIndex];
     88                     slides[slideIndex].Select();
     89                 }
     90                 catch
     91                 {
     92                     // 在阅读模式下使用下面的方式来切换到上一张幻灯片
     93                     pptApplication.SlideShowWindows[1].View.Previous();
     94                     slide = pptApplication.SlideShowWindows[1].View.Slide;
     95                 }
     96             }
     97             else
     98             {
     99                 // MessageBox.Show("已经是第一页了");
    100             }
    101         }
    102 
    103         //下一页
    104         public void NextPage()
    105         {
    106             slideIndex = slide.SlideIndex + 1;
    107             if (slideIndex > slidescount)
    108             {
    109                 //MessageBox.Show("已经是最后一页了");
    110             }
    111             else
    112             {
    113                 try
    114                 {
    115                     slide = slides[slideIndex];
    116                     slides[slideIndex].Select();
    117                 }
    118                 catch
    119                 {
    120                     // 在阅读模式下使用下面的方式来切换到下一张幻灯片
    121                     pptApplication.SlideShowWindows[1].View.Next();
    122                     slide = pptApplication.SlideShowWindows[1].View.Slide;
    123                 }
    124             }
    125         }
    126         //最后一页
    127         public void LastPage()
    128         {
    129             try
    130             {
    131                 slides[slidescount].Select();
    132                 slide = slides[slidescount];
    133             }
    134             catch
    135             {
    136                 // 在阅读模式下使用下面的方式来切换到最后幻灯片
    137                 pptApplication.SlideShowWindows[1].View.Last();
    138                 slide = pptApplication.SlideShowWindows[1].View.Slide;
    139             }
    140         }
    141     }
    142 }

        其次介绍服务端PC和和客户端(windows phone)使用Socket通信的代码,服务端等待接收消息代码如下所示:

     

     1         Socket listenner = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     2         private Control control = new Control();
     3         
     4         public Form1()
     5         {
     6             InitializeComponent();
     7             TextBox.CheckForIllegalCrossThreadCalls = false;
     8             
     9         }
    10         //打印提示信息
    11         public void showMessage(String strMsg)
    12         {
    13            output.AppendText(strMsg + "
    ");
    14         }
    15         private static AutoResetEvent _flipFlop = new AutoResetEvent(false);
    16         private void start_Click(object sender, EventArgs e)
    17         {
    18             
    19             
    20             IPAddress address = IPAddress.Parse(iptext.Text.Trim());//创建IP对象
    21 
    22             IPEndPoint localEP = new IPEndPoint(address,int.Parse(porttext.Text.Trim()));
    23 
    24           //  MessageBox.Show("运行中");
    25                  showMessage("本地IP地址和端口是"+localEP);
    26                 listenner.Bind(localEP);
    27                 listenner.Listen(10);
    28                 Thread threadlisten;//定义监听线程
    29                 threadlisten = new Thread(startlisten);
    30                 threadlisten.IsBackground = true;//创建线程时默认false,为false时,主线程退出,仍然执行,直到结束
    31                 threadlisten.Start();
    32 
    33         }
    34         private void startlisten() {
    35             while (true)
    36             {
    37                 // Console.WriteLine("等待windows phone客户端的连接。。。。");
    38                 showMessage("等待windows phone客户端的连接");
    39                 listenner.BeginAccept(AcceptCallback, listenner);
    40                 _flipFlop.WaitOne();
    41             }
    42         }
    43         private void AcceptCallback(IAsyncResult ar)
    44         {
    45             Socket listener = (Socket)ar.AsyncState;
    46             Socket socket = listener.EndAccept(ar);
    47            // Console.WriteLine("连接到windows phone 客户端");
    48             showMessage("连接到windows phone 客户端");
    49             _flipFlop.Set();
    50             var state = new StateObject();
    51             state.Socket = socket;
    52             socket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, ReceiveCallback, state);
    53         }
    54 
    55         private void ReceiveCallback(IAsyncResult ar)
    56         {
    57             StateObject state = (StateObject)ar.AsyncState;
    58             Socket socket = state.Socket;
    59             int read = socket.EndReceive(ar);
    60             if (read > 0)
    61             {
    62                 string chunk = Encoding.UTF8.GetString(state.Buffer, 0, read);
    63                 state.StringBuilder.Append(chunk);
    64                 if (state.StringBuilder.Length > 0)
    65                 {
    66                     string result = state.StringBuilder.ToString();
    67                   //  Console.WriteLine("收到客户端传来的消息:{0}", result);
    68                     control.Dispatcher(int.Parse(result));
    69                     //showMessage("收到客户端传来的消息:"+result);
    70                     //Send(socket, "s" + result);
    71                     //Console.WriteLine("发给客户端的消息:{0}", "s" + result);
    72                     //showMessage("发给客户端的消息"+result);
    73                 }
    74             }
    75         }

      客户端发起连接的代码如下:

      

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Net;
      5 using System.Windows;
      6 using System.Windows.Controls;
      7 using System.Windows.Navigation;
      8 using Microsoft.Phone.Controls;
      9 using Microsoft.Phone.Shell;
     10 using SocketClient.Resources;
     11 using System.Net.Sockets;
     12 using System.Text;
     13 
     14 namespace SocketClient
     15 {
     16     public partial class MainPage : PhoneApplicationPage
     17     {
     18        
     19         public MainPage()
     20         {
     21             InitializeComponent();
     22 
     23         }
     24 
     25         private void Send(string str)
     26         {
     27             if (string.IsNullOrEmpty(Host.Text) || string.IsNullOrEmpty(Port.Text)) {
     28                 MessageBox.Show("请输入以下主机IP和端口号,谢谢");
     29                 return;
     30             }
     31 
     32             string host = Host.Text.Trim();
     33 
     34             int port = Convert.ToInt32(Port.Text.Trim());
     35 
     36             DnsEndPoint hostEntry = new DnsEndPoint(host, port);
     37             Socket sock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
     38 
     39             SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
     40             byte[] buffer = Encoding.UTF8.GetBytes(str);
     41             socketEventArg.SetBuffer(buffer, 0, buffer.Length);
     42             socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(SocketAsyncEventArgs_Completed);
     43             socketEventArg.RemoteEndPoint = hostEntry;
     44             socketEventArg.UserToken = sock;
     45             try
     46             {
     47                 sock.ConnectAsync(socketEventArg);
     48             }
     49             catch (SocketException ex) {
     50                 throw new SocketException((int)ex.ErrorCode);
     51             }
     52 
     53 
     54         }
     55         private void SocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)
     56         {
     57             if(e.SocketError!=SocketError.Success){
     58                 if (e.SocketError == SocketError.ConnectionAborted) { 
     59                     Dispatcher.BeginInvoke(()=>MessageBox.Show("连接超时请重试"+e.SocketError));
     60                 }
     61                 else if (e.SocketError == SocketError.ConnectionRefused)
     62                 {
     63                     Dispatcher.BeginInvoke(() => MessageBox.Show("服务器端启动" + e.SocketError));
     64                 }
     65                 else {
     66                     Dispatcher.BeginInvoke(() => MessageBox.Show("出错了" + e.SocketError));
     67                 }
     68 
     69                 if (e.UserToken != null) {
     70                     Socket sock = e.UserToken as Socket;
     71                     sock.Shutdown(SocketShutdown.Both);
     72                     sock.Close();
     73                 }
     74                 return;
     75             }
     76 
     77             switch (e.LastOperation) { 
     78                 case SocketAsyncOperation.Connect:
     79                     if (e.UserToken != null) {
     80                         Socket sock = e.UserToken as Socket;
     81                         bool completeAsynchronously = sock.SendAsync(e);
     82                         if (!completeAsynchronously) {
     83                             SocketAsyncEventArgs_Completed(e.UserToken, e);
     84                         }
     85                     };
     86                     break;
     87                 case SocketAsyncOperation.Send:
     88                     Dispatcher.BeginInvoke(()=>{
     89                         //listBox1.Items.Add("客户端"+DateTime.Now.ToShortTimeString()+"发送的消息:"+Message.Text);
     90                     }
     91                 );
     92                     if (e.UserToken != null)
     93                     {
     94                         Socket sock = e.UserToken as Socket;
     95                         bool completesAsynchronously = sock.ReceiveAsync(e);
     96                         if (!completesAsynchronously) {
     97                             SocketAsyncEventArgs_Completed(e.UserToken,e);
     98                         }
     99                     }
    100                     break;
    101                 case SocketAsyncOperation.Receive:
    102                     if (e.UserToken != null) {
    103                         string dataFromServer = Encoding.UTF8.GetString(e.Buffer,0,e.BytesTransferred);
    104                         Socket sock = e.UserToken as Socket;
    105                         Dispatcher.BeginInvoke(() =>
    106                         {
    107 
    108 
    109                           //  listBox1.Items.Add("服务器端" + DateTime.Now.ToShortTimeString() + "传过来的消息:" + dataFromServer);
    110                         });
    111                      }
    112                     break;
    113                     }
    114 
    115             }
    116 
    117         private void check_Click(object sender, RoutedEventArgs e)
    118         {
    119             Send("1");
    120         }
    121 
    122         private void First_Click(object sender, RoutedEventArgs e)
    123         {
    124             Send("2");
    125         }
    126 
    127         private void previous_Click(object sender, RoutedEventArgs e)
    128         {
    129             Send("3");
    130         }
    131 
    132         private void next_Click(object sender, RoutedEventArgs e)
    133         {
    134             Send("4");
    135         }
    136 
    137         private void last_Click(object sender, RoutedEventArgs e)
    138         {
    139             Send("5");
    140         }
    141         
    142     }
    143 
    144         
    145 
    146     
    147 }

       源代码我已经上传到百度网盘链接: http://pan.baidu.com/s/1mg5HAsS 密码: i4a9,欢迎大家学习,并进行二次开发。

      

  • 相关阅读:
    吊打996,来了?!
    微软开源浏览器自动化工具Playwright for Python(附源码)
    从0到1开始建设安全测试体系
    网友爆料vivo将取消大小周,不降薪,官方证实消息属实
    认识了一个在华为任职的50岁程序员!
    漫画:什么是自动驾驶?
    中国十大杰出人物
    最难调试修复的 bug 是怎样的?
    “十年不升职多得是,四年算什么”
    appium+pytest实现APP并发测试
  • 原文地址:https://www.cnblogs.com/zhaolizhen/p/WP8controlPowerPoint.html
Copyright © 2020-2023  润新知