• 基于windowsphone7的控制ppt播放


    最近突然想起了一个学长的一个利用手机控制ppt播放的一个创意,并想将其在windows phone7上实现一下。

    经过几天的努力已经可以控制ppt的播放,暂停,上一张,下一张了,并且电脑会将当前ppt的截图发送到手机端这里。

    在代码的编写过程中,参考了IT黄老邪Windows Phone开发(46):与Socket有个约会 进行服务端与wp客户端的socket通讯的编写,并加入了键盘消息模拟,服务端截屏,图片发送,与客户端的图片接受。

    代码如下:

    WP客户端

    1、新建Windows Phone应用程序项目。(我这里的名称是叫PhoneApp2)

    2、打开MainPage.xaml文件,输入以下代码。

    <phone:PhoneApplicationPage 
        x:Class="PhoneApp2.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        shell:SystemTray.IsVisible="True">
    
        <!--LayoutRoot 是包含所有页面内容的根网格-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    
            <!--TitlePanel 包含应用程序的名称和页标题-->
            <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
                <TextBlock x:Name="ApplicationTitle" Text="我的应用程序" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock x:Name="PageTitle" Text="PPT播放" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
            </StackPanel>
    
            <!--ContentPanel - 在此处放置其他内容-->
            <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Grid Grid.Row="0">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0" VerticalAlignment="Center" Text="服务器IP:" />
                    <TextBox Name="txtServerIP" Grid.Column="1" Text="" />
                    <Button Grid.Column="2" Content="连接" Click="onConnect"/>
                </Grid>
              
                    <Button Content="播放" Click="onPlay" Width="154" Margin="54,0,248,463" Grid.Row="1" />
                    <Button Content="下一张" Click="onPlayNext" Margin="0,78,21,358" Grid.Row="1" HorizontalAlignment="Right" Width="197" />
                <Button Content="上一张" Click="onPlayBack" Margin="6,78,248,358" Grid.Row="1" />
                    <Button Content="暂停" Click="onPause" Width="143" Margin="237,0,75,463" Grid.Row="1" />
                    <TextBlock Name="txtbInfo"  Margin="6,475,0,6" Grid.Row="1" />
                <Image Grid.Row="1" Height="281" HorizontalAlignment="Left" Margin="12,170,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="423" Tap="image1_Tap" />
            </Grid>
        </Grid>
    
        <!--演示 ApplicationBar 用法的示例代码-->
        <!--<phone:PhoneApplicationPage.ApplicationBar>  
            <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">  
                <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="按钮 1"/>  
                <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="按钮 2"/>  
                <shell:ApplicationBar.MenuItems>  
                    <shell:ApplicationBarMenuItem Text="菜单项 1"/>  
                    <shell:ApplicationBarMenuItem Text="菜单项 2"/>  
                </shell:ApplicationBar.MenuItems>  
            </shell:ApplicationBar>  
        </phone:PhoneApplicationPage.ApplicationBar>-->
    
    </phone:PhoneApplicationPage>  

    3、打开MainPage.xaml.cs,输入以下代码。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;
    using System.Net.Sockets;
    using System.Threading;
    using System.Text;
    using System.IO;
    using System.Windows.Media.Imaging;
    
    namespace PhoneApp2
    {
        public partial class MainPage : PhoneApplicationPage
        {
            Socket mySocket = null;
            ManualResetEvent MyEvent = null;
            Byte[] imgbyte = new Byte[262144];
            // 构造函数   
            public MainPage()
            {
                InitializeComponent();
            }
    
            protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
            {
                base.OnNavigatedTo(e);
    
                if (mySocket == null)
                {
                    mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    mySocket.ReceiveBufferSize = 262144;
                   
                }
                if (MyEvent == null)
                {
                    MyEvent = new ManualResetEvent(false);
                }
            }
    
            protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
            {
                try
                {
                    if (mySocket != null)
                    {
                        mySocket.Shutdown(SocketShutdown.Both);
                        mySocket.Close();
                    }
                    base.OnNavigatedFrom(e);
                }
                catch 
                {
                    base.OnNavigatedFrom(e);
                }
            }
    
            private void onConnect(object sender, RoutedEventArgs e)
            {
                if (mySocket != null)
                {
                    SocketAsyncEventArgs connArg = new SocketAsyncEventArgs();
                    if(this.txtServerIP.Text=="")
                    {
                        txtbInfo.Text="请输入正确的ip";
                        return;
                     }
                    // 要连接的远程服务器   
                    connArg.RemoteEndPoint = new DnsEndPoint(this.txtServerIP.Text, 1377);
                   
                    // 操作完成后的回调   
                    connArg.Completed += (sendObj, arg) =>
                    {
                        if (arg.SocketError == SocketError.Success) //连接成功   
                        {
                            Dispatcher.BeginInvoke(() => txtbInfo.Text = "连接成功。");
                            
                            imgbyte = arg.Buffer;
                        }
                        else
                        {
                            Dispatcher.BeginInvoke(() =>
                            {
                                txtbInfo.Text = "连接失败,错误:" + arg.SocketError.ToString();
                            });
                        }
                        // 向调用线程报告操作结束   
                        MyEvent.Set();
                    };
                    // 重置线程等待事件   
                    MyEvent.Reset();
                    txtbInfo.Text = "正在连接,请等候……";
                    // 开始异连接   
                    mySocket.ConnectAsync(connArg);
                    // 等待连接完成   
                    MyEvent.WaitOne(6000);
                }
            }
            Byte[] imgInfo;
            private void onPlayNext(object sender, RoutedEventArgs e)
            {
                SendCommand("playNext");
                receiveImg();
              
            }
            private void receiveImg()
            {
                try
                {
                    imgInfo = ReceiveInfo();
                    MemoryStream ms = new MemoryStream(imgInfo);
                    BitmapImage bitmapImage = new BitmapImage();
                    bitmapImage.SetSource(ms);
                    WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapImage);
    
                    this.image1.Source = writeableBitmap;
                }
                catch
                {
                    SendCommand("newimg");
                }
            }
            private void onPlayBack(object sender, RoutedEventArgs e)
            {
                SendCommand("playBack");
                receiveImg();
            }
            private void onPlay(object sender, RoutedEventArgs e)
            {
                SendCommand("play");
                receiveImg();
            }
    
            private void onPause(object sender, RoutedEventArgs e)
            {
                SendCommand("pause");
               receiveImg();
            }
            int i = 0;
            byte[] received = new Byte[1024 *9]; 
            private byte[] ReceiveInfo()
            {
              
                if (mySocket != null && mySocket.Connected)
                {
                    SocketAsyncEventArgs receiveArg = new SocketAsyncEventArgs();
                    
                    byte[] buffer = new byte[1024];
                    receiveArg.SetBuffer(buffer, 0, buffer.Length);
                    receiveArg.Completed += new EventHandler<SocketAsyncEventArgs>(receiveArg_Completed);
                    MyEvent.Reset();
                    mySocket.ReceiveAsync(receiveArg);
                    MyEvent.WaitOne(500);
                }
                return received;
    
            }
    
            void receiveArg_Completed(object sender, SocketAsyncEventArgs mArg)
            {
                
                if (mArg.SocketError == SocketError.Success)
                {
                   if (i < 9)
                    {
                        Buffer.BlockCopy(mArg.Buffer,0,received,i * 1024, 1024);
    
                        i++;
                        ReceiveInfo();
                    }
                    MyEvent.Set();
                    mArg.Dispose();
                }
               
            }
    
    
            private void SendCommand(string txt)
            {
                i = 0;
                if (mySocket != null && mySocket.Connected)
                {
                    SocketAsyncEventArgs sendArg = new SocketAsyncEventArgs();
               
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(txt);
                    sendArg.SetBuffer(buffer, 0, buffer.Length);
                    // 发送完成后的回调   
                    sendArg.Completed += (objSender, mArg) =>
                    {
                        // 如果操作成功                       
                        if (mArg.SocketError == SocketError.Success)
                        {
                            Dispatcher.BeginInvoke(() => txtbInfo.Text = "发送成功。");
                           
                        }
                      
                        else
                        {
                            Dispatcher.BeginInvoke(() =>
                            {
                                this.txtbInfo.Text = "发送失败,错误:" + mArg.SocketError.ToString();
                               
                            });
                        }
                        // 报告异步操作结束   
                        MyEvent.Set();
                    };
                    // 重置信号   
                    MyEvent.Reset();
                    txtbInfo.Text = "正在发送,请等候……";
                    // 异步发送   
                    mySocket.SendAsync(sendArg);
                    // 等待操作完成   
                    MyEvent.WaitOne(6000);
                }
            }
    
    
            private void image1_Tap(object sender, GestureEventArgs e)
            {
                SendCommand("newimg");
                 receiveImg();
            }
        }
    }

    第一部分 服务器端

    1、新建WPF应用程序项目。(我这里的名称是叫做WpfApplication4)

    2、打开MainWindow.xaml文件,输入以下XAML代码。

    <Window x:Class="WpfApplication4.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Title="服务器端" Height="350" Width="525">         
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            
            <TextBlock Name="txtDisplay2" Grid.Row="1" Margin="240,0,12,0" />
            <TextBlock Name="txtDisplay" Grid.Row="1" Margin="0,0,261,0" />
            <TextBlock Height="181" TextWrapping="Wrap" HorizontalAlignment="Left" Margin="88,60,0,0" Name="textBlock1"  VerticalAlignment="Top" FontSize="25" Width="319" >
                打开客户端,输入服务器ip后,将程序最小化,打开需要的ppt。
            </TextBlock>
        </Grid>
    </Window>  

    3.MainWindow.xaml.cs的代码如下。

    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.Forms;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Windows.Media.Animation;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    using System.Drawing;
    using System.IO;
    using System.Drawing.Imaging;
    
    namespace WpfApplication4
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
    
    
            Socket Server;
            Byte[] imgInfo=new Byte[1024*5];
            public MainWindow()
            {
                InitializeComponent();
                InitialTray();
    
                // 从资源中把Key为std的Storyboard读出来   
             
                // 声明用于监听连接请求的Socket   
               Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //
             
               string strHostName = Dns.GetHostName();
             
                //得到本机的主机名 
                IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
                ////取得本机IP 
                IPAddress strAddr = ipEntry.AddressList[7];//.ToString();
                txtDisplay2.Text = "服务器IP:" + strAddr.ToString();//假设本地主机为单网卡
                //
                IPEndPoint local = new IPEndPoint(IPAddress.Any, 1377); //监听所有网络接口上的地址   
                Server.Bind(local);// 绑定本地终结点   
                Server.Listen(100);// 侦听连接请求   
                // 开始异步接受传入的连接请求   
                Server.BeginAccept(new AsyncCallback(this.AcceptSocketCallback), Server);
            }
            private System.Windows.Forms.NotifyIcon notifyIcon = null;
            
             private void InitialTray()
            {
    
                //设置托盘的各个属性
                notifyIcon = new System.Windows.Forms.NotifyIcon();
                notifyIcon.BalloonTipText = "程序开始运行";
                notifyIcon.Text = "ppt服务端";
                notifyIcon.Icon = new System.Drawing.Icon("Downloads.ico");
                notifyIcon.Visible = true;
                notifyIcon.ShowBalloonTip(2000);
                notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(notifyIcon_MouseClick);
    
             
                //退出菜单项
                System.Windows.Forms.MenuItem exit = new System.Windows.Forms.MenuItem("exit");
                exit.Click += new EventHandler(exit_Click);
    
                //关联托盘控件
                System.Windows.Forms.MenuItem[] childen = new System.Windows.Forms.MenuItem[] { exit };
                notifyIcon.ContextMenu = new System.Windows.Forms.ContextMenu(childen);
    
                //窗体状态改变时候触发
                this.StateChanged += new EventHandler(SysTray_StateChanged);
            }
            ///
            /// 窗体状态改变时候触发
            ///
            ///
    
            ///
    
            private void SysTray_StateChanged(object sender, EventArgs e)
            {
                if (this.WindowState == WindowState.Minimized)
                {
                    this.Visibility = Visibility.Hidden;
                }
            }
    
            ///
            /// 退出选项
            ///
            ///
    
            ///
    
            private void exit_Click(object sender, EventArgs e)
            {
                if (System.Windows.MessageBox.Show("确定要关闭吗?",
                                                   "退出",
                                                    MessageBoxButton.YesNo,
                                                    MessageBoxImage.Question,
                                                    MessageBoxResult.No) == MessageBoxResult.Yes)
                {
                    notifyIcon.Dispose();
                    System.Windows.Application.Current.Shutdown();
                }
            }
    
            ///
            /// 鼠标单击
            ///
            ///
    
            ///
    
            private void notifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    if (this.Visibility == Visibility.Visible)
                    {
                        this.Visibility = Visibility.Hidden;
                       
                    }
                    else
                    {
                        this.Visibility = Visibility.Visible;
                       
                        this.Activate();
                    }
                }
            }
    
            //
            /// <summary>   
            /// 接受传入的Socket的回调   
            /// </summary>   
            private void AcceptSocketCallback(IAsyncResult ia)
            {
                Socket _socket = ia.AsyncState as Socket;
                Socket accptSocket = _socket.EndAccept(ia);
                try
                {
                    IPEndPoint remote = (IPEndPoint)accptSocket.RemoteEndPoint;
                    // 显示客户端的IP   
                    Dispatcher.BeginInvoke(new Action<string>(this.SetIPForText), remote.Address.ToString());
                    StateObject so = new StateObject();
                    so.theSocket = accptSocket;
                    // 开始异步接收消息   
                    accptSocket.BeginReceive(so.Buffer, 0, so.Buffer.Length, SocketFlags.None, new AsyncCallback(this.ReceiveCallback), so);
                }
                catch
                {
    
                }
                // 继续接受连接请求   
                _socket.BeginAccept(new AsyncCallback(this.AcceptSocketCallback), _socket);
            }
            /// <summary>   
            /// 接收消息的回调   
            /// </summary>   
            private void ReceiveCallback(IAsyncResult ia)
            {
                StateObject _so = ia.AsyncState as StateObject;
                Socket _socket = _so.theSocket;
                try
                {
                    int n = _socket.EndReceive(ia);//n就是接收到的字节数   
                    string msg = Encoding.UTF8.GetString(_so.Buffer, 0, n);
                    
                    // 判断客户端发送了啥命令   
                    switch (msg)
                    {
                        case "playNext":
                           
                            System.Windows.Forms.SendKeys.SendWait("{Right}");
                            SendCommand(_socket, CatchScreen());
                            break;
                        case "playBack":
                           
                            System.Windows.Forms.SendKeys.SendWait("{Left}");
                            SendCommand(_socket, CatchScreen());
                            break;
                        case "pause":
                           
                            System.Windows.Forms.SendKeys.SendWait("{B}");
                            SendCommand(_socket, CatchScreen());
                            break;
                        case "play":
                           
                            System.Windows.Forms.SendKeys.SendWait("{F5}");
                            SendCommand(_socket, CatchScreen());
                            break;
                        case "newimg":
                            SendCommand(_socket, CatchScreen());
                            break;
                        default:
                            break;
                    }
                }
                catch
                {
                }
                _so = new StateObject();
                _so.theSocket = _socket;
                // 继续接收消息   
                _socket.BeginReceive(_so.Buffer,
                                    0,
                                    _so.Buffer.Length,
                                    SocketFlags.None,
                                    new AsyncCallback(this.ReceiveCallback),
                                    _so);
            }
    
            
            private void SendCommand(Socket handler,byte[] imginfo)
            {
               
                try
                {
                    handler.BeginSend(imginfo, 0, imginfo.Length, 0, new AsyncCallback(SendCallBack), handler);
                }
                catch
                {
                }
          
            }
            private void SendCallBack(IAsyncResult ar)
            {
                try
                {
                    Socket handler = (Socket)ar.AsyncState;
                    int bytesSend = handler.EndSend(ar);
                    if (bytesSend > 0)
                    {
                        Console.WriteLine("Succeed");
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
    
            }
            private byte[]  CatchScreen()
            {
                Screen scr = Screen.PrimaryScreen;
                System.Drawing.Rectangle rc = scr.Bounds;
                int iWidth = rc.Width;
                int iHeight = rc.Height;
                //创建一个和屏幕一样大的Bitmap
                System.Drawing.Image myImage = new Bitmap(iWidth, iHeight);
               
                //从一个继承自Image类的对象中创建Graphics对象
                Graphics g = Graphics.FromImage(myImage);
              
                g.CopyFromScreen(new System.Drawing.Point(0, 0), new System.Drawing.Point(0, 0), new System.Drawing.Size(iWidth, iHeight));   
                return ImgToByt(myImage.GetThumbnailImage(iWidth / 6, iHeight/6, new System.Drawing.Image.GetThumbnailImageAbort(CallBack), IntPtr.Zero));
            }
            private static bool CallBack()
            {
                return false;
                
            }
    
            public  byte[] ImgToByt(System.Drawing.Image img)
            {
                MemoryStream ms = new MemoryStream();
                byte[] imagedata = new Byte[1024 * 9];// null;
                byte[] imagedata2 = null;
                img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                 imagedata2 = ms.GetBuffer();
                 Buffer.BlockCopy(imagedata2, 0, imagedata, 0, imagedata2.Length);
                return imagedata;
            }
            /// <summary> 
            /// 字节流转换成图片 
            /// </summary> 
            /// <param name="byt">要转换的字节流</param> 
            /// <returns>转换得到的Image对象</returns> 
            public System.Drawing.Image BytToImg(byte[] byt)
            {
                MemoryStream ms = new MemoryStream(byt);
                System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
                return img;
            } 
            /// <summary>   
            /// 显示客户端的IP   
            /// </summary>   
            private void SetIPForText(string ip)
            {
                this.txtDisplay.Text = "客户端IP:" + ip;
            }
    
          
        }
    
        /// <summary>   
        /// 用于异步Socket操作传递的状态对象   
        /// </summary>   
        public class StateObject
        {
            private const int BUFFER_SIZE = 512;
    
            public byte[] Buffer { get; set; }
    
            public Socket theSocket { get; set; }
    
            /// <summary>   
            /// 构造函数   
            /// </summary>   
            public StateObject()
            {
                this.Buffer = new byte[BUFFER_SIZE];
            }
        }
    }

    4.新建一个叫做KeyboardToolkit.cs的类,用于模拟键盘消息,代码如下。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Input;
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Security.Permissions;
    using System.ComponentModel;
    
    namespace WpfApplication4
    {
        class KeyboardToolkit
        {
            internal static class NativeMethods
            {
                #region User32
                // Various Win32 constants
                internal const int KeyeventfKeyup = 0x0002;
                internal const int KeyeventfScancode = 0x0008;
                internal const int InputKeyboard = 1;
    
                // Various Win32 data structures
                [StructLayout(LayoutKind.Sequential)]
                internal struct INPUT
                {
                    internal int type;
                    internal INPUTUNION union;
                };
    
                [StructLayout(LayoutKind.Explicit)]
                internal struct INPUTUNION
                {
                    [FieldOffset(0)]
                    internal MOUSEINPUT mouseInput;
                    [FieldOffset(0)]
                    internal KEYBDINPUT keyboardInput;
                };
    
                [StructLayout(LayoutKind.Sequential)]
                internal struct MOUSEINPUT
                {
                    internal int dx;
                    internal int dy;
                    internal int mouseData;
                    internal int dwFlags;
                    internal int time;
                    internal IntPtr dwExtraInfo;
                };
    
                [StructLayout(LayoutKind.Sequential)]
                internal struct KEYBDINPUT
                {
                    internal short wVk;
                    internal short wScan;
                    internal int dwFlags;
                    internal int time;
                    internal IntPtr dwExtraInfo;
                };
    
                // Importing various Win32 APIs that we need for input
                [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
                internal static extern int GetSystemMetrics(int nIndex);
    
                [DllImport("user32.dll", CharSet = CharSet.Auto)]
                internal static extern int MapVirtualKey(int nVirtKey, int nMapType);
    
                [DllImport("user32.dll", SetLastError = true)]
                internal static extern int SendInput(int nInputs, ref INPUT mi, int cbSize);
    
                [DllImport("user32.dll", CharSet = CharSet.Auto)]
                internal static extern short VkKeyScan(char ch);
    
                #endregion User32
            }
    
            public static class Keyboard
            {
                /// <summary>
                /// Presses down a key.
                /// </summary>
                /// <param name="key">The key to press.</param>
                public static void Press(Key key)
                {
                    SendKeyboardInput(key, true);
                }
    
                /// <summary>
                /// Releases a key.
                /// </summary>
                /// <param name="key">The key to release.</param>
                public static void Release(Key key)
                {
                    SendKeyboardInput(key, false);
                }
    
                /// <summary>
                /// Resets the system keyboard to a clean state.
                /// </summary>
                public static void Reset()
                {
                    foreach (Key key in Enum.GetValues(typeof(Key)))
                    {
                        if (key != Key.None && (System.Windows.Input.Keyboard.GetKeyStates(key) & KeyStates.Down) > 0)
                        {
                            Release(key);
                        }
                    }
                }
    
                /// <summary>
                /// Performs a press-and-release operation for the specified key, which is effectively equivallent to typing.
                /// </summary>
                /// <param name="key">The key to press.</param>
                public static void Type(Key key)
                {
                    Press(key);
                    System.Threading.Thread.Sleep(100);
                    Release(key);
                }
    
    
    
                [PermissionSet(SecurityAction.Assert, Name = "FullTrust")]
                private static void SendKeyboardInput(Key key, bool press)
                {
                    PermissionSet permissions = new PermissionSet(PermissionState.Unrestricted);
                    permissions.Demand();
    
                    NativeMethods.INPUT ki = new NativeMethods.INPUT();
                    ki.type = NativeMethods.InputKeyboard;
                    ki.union.keyboardInput.wVk = (short)KeyInterop.VirtualKeyFromKey(key);
                    ki.union.keyboardInput.wScan = (short)NativeMethods.MapVirtualKey(ki.union.keyboardInput.wVk, 0);
    
                    int dwFlags = 0;
    
                    if (ki.union.keyboardInput.wScan > 0)
                    {
                        dwFlags |= NativeMethods.KeyeventfScancode;
                    }
    
                    if (!press)
                    {
                        dwFlags |= NativeMethods.KeyeventfKeyup;
                    }
    
                    ki.union.keyboardInput.dwFlags = dwFlags;
    
                    ki.union.keyboardInput.time = 0;
                    ki.union.keyboardInput.dwExtraInfo = new IntPtr(0);
    
                    if (NativeMethods.SendInput(1, ref ki, Marshal.SizeOf(ki)) == 0)
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }
    
            }
        }
    }

    先打开服务端

    在手机客户端,输入服务器端的IP地址,点击连接,连接成功后就可以进行操作了

    作者:magicsoar
    联系方式:sungaofei008@163.com邮我邮我
    qq:1021842556点我
  • 相关阅读:
    Unity PhysicsScene测试
    游戏编程精粹学习
    Unity StreamingMipmaps 简单测试
    稀疏贴图 SparseTexture
    前端工程师是怎样一种职业
    web资源预加载-生产环境实践
    2019年终总结——三十而立
    一种前端灰度发布方案
    2018年终总结——越过山丘
    记录一个前端bug的解决过程
  • 原文地址:https://www.cnblogs.com/magicsoar/p/3158878.html
Copyright © 2020-2023  润新知