前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于windowsphone7的控制ppt播放 第一部分 服务器端

基于windowsphone7的控制ppt播放 第一部分 服务器端

作者头像
magicsoar
发布2019-05-25 18:39:24
5530
发布2019-05-25 18:39:24
举报
文章被收录于专栏:magicsoarmagicsoar

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

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

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

代码如下:

WP客户端

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

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

代码语言:javascript
复制
<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,输入以下代码。

代码语言:javascript
复制
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代码。

代码语言:javascript
复制
<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的代码如下。

代码语言:javascript
复制
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的类,用于模拟键盘消息,代码如下。

代码语言:javascript
复制
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地址,点击连接,连接成功后就可以进行操作了

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一部分 服务器端
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档