相信大家都有過演講的經歷,當我們演講時,一手拿著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 else112 {113 try114 {115 slide = slides[slideIndex];116 slides[slideIndex].Select();117 }118 catch119 {120 // 在閱讀模式下使用下面的方式來切換到下一張幻燈片121 pptApplication.SlideShowWindows[1].View.Next();122 slide = pptApplication.SlideShowWindows[1].View.Slide;123 }124 }125 }126 //最后一頁127 public void LastPage()128 {129 try130 {131 slides[slidescount].Select();132 slide = slides[slidescount];133 }134 catch135 {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 + "/r/n");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("收到客戶端
新聞熱點
疑難解答