精华内容
下载资源
问答
  • C# KTV项目 练手

    2017-12-21 23:15:52
    C# KTV项目 练手
  • C#练手项目10-1之正义永不缺席

    千次阅读 2020-11-20 20:47:07
    C#实例练手之test10-1 ————2020/11/20 写作目的:相互学习交流,提供实例,练习C#,有啥问题,可以直接留言,也可以加我vx:poyeezy996. 目标题目: 1.参照P209例8.7进行实验,要求用到抽象...
    										C#实例练手之test10-1
    																				————2020/11/20
    

    写作目的:相互学习交流,提供实例,练习C#,有啥问题,可以直接留言,也可以加我vx:poyeezy996.

    目标题目:
    1.参照P209例8.7进行实验,要求用到抽象类以及抽象方法。
    2. 定义玩家类(Player)、枪类(Gun)。以及派生于玩家类的警察类(Police)
    和坏人类(Robber),派生于枪类的手枪类(Handgun)和机关枪类
    (MachineGun);
    3. 手枪类可以造成1点初始伤害值,并且发出的声音为“biubiu” 。机关枪类可
    以造成2点初始伤害值,发出的声音为“boomboom

    4. 警察类有初始20点血量,可以使用手枪对坏人射击,造成手枪的伤害值的伤害,
    也可以选择前进一步,使得手枪伤害值提高100%;坏人类有初始20点血量,可
    以使用机关枪对警察射击,造成机关枪的伤害值的伤害,也可以选择前进一步,
    使得机关枪伤害值提高50%。
    5. 在Main函数中循环坏人与警察进行选择判断,分别轮流输入数字进行操作。前
    进增加伤害:1,开枪造成伤害:2。
    6. 直至一方血量低于0,结束游戏。

    目标生成内容:在这里插入图片描述
    思路讲解
    这一个题目涉及到的知识点其实吧,很简单。
    1.抽象类以及抽象方法
    (首先来看看抽象类和抽象方法是什么呢)
    自己看书或者百度吧,记得抽象类不能实例化就行了。
    1.1基本语法
    1.1.1
    抽象类:

    abstarct class 类名{
    	//声明类成员
    }
    

    1.1.2
    抽象方法:

    abstract [修饰符] 返回值类型 方法名 ([形参列表];
    

    2.定义基类和派生类

    using System;
    
    namespace test10_1
    {
        public abstract class Player
        {
            public int hp;   //血量
            public abstract void forward();
        public Player(int hp) { this.hp = hp; }
        }
    
        class Police : Player
        {
            public override void forward()
            {
                Console.WriteLine("前进1步,伤害提升100%");    
            } 
            public Police(int hp=20) : base(hp) { }//定义初始值
        }
    
        class Robber : Player
        {   
            public override void forward()
            {
                Console.WriteLine("前进1步,伤害提升50%"); 
            }       
            public Robber(int hp=20) : base(hp) { }
        }
    
    
        abstract class Gun
        {
            public string voice;
            public double damage;
            public abstract void shoot();
            public Gun(string voice,double damage) { this.voice = voice;this.damage = damage; }
        }
    
        class Handgun:Gun
        {
            public override void shoot()
            {
                Console.Write("警察使用手枪向坏人射击。");
            }
            public Handgun(string voice="biu~biu", double damage=1) : base(voice,damage) { }
        }
        class Machinegun : Gun
        {
            public override void shoot()
            {
                Console.Write("坏人使用手枪向警察射击。");
            }
            public Machinegun(string voice="boom~boom", double damage=2) : base(voice,damage) { }
        }
    
    
    

    对于上面的代码,根据题目要求,基类有Player、Gun,派生类分别是Police、Robber;Handgun、Machinegun.
    要完成动作,前进和射击的功能,我们在基类中分别定义抽象方法forward、shoot,在派生类中,对抽象方法重写,并对属性给定默认值,接下来对后面的对象创建,我们就可以不用给定值了
    3.处理逻辑
    这里是带佬给出来的思路
    在这里插入图片描述
    图都有了,自己看呗,不会留言区见。
    于是我们就处理一下下面的逻辑问题。

      class testprogram
        {
            static void Main()
            {
                int i;
                int people=1;
                Police pc = new Police();
                Robber rb = new Robber();
                Handgun hg = new Handgun();
                Machinegun mg = new Machinegun();
                Console.WriteLine("警察共有"+pc.hp+"滴血,射击一次造成"+hg.damage+"伤害");
                Console.WriteLine("坏人共有" + rb.hp + "滴血,射击一次造成" + mg.damage + "伤害");
                Console.WriteLine("开始游戏:");
    			while (pc.hp > 0 && rb.hp > 0)
    			{
                    if (people % 2 != 0)
                    {
                        Console.Write("坏人选择操作:1:前进1步,伤害提高50%;2:射击,造成"+ mg.damage +"点伤害。请选择:");
                        i = Convert.ToInt32(Console.ReadLine());
                        switch (i)
                        {
                            case 1:
                                rb.forward();
                                mg.damage *= 1.5;
                                people += 1;
                                break;
                            case 2:
                                mg.shoot();
                                Console.WriteLine(mg.voice);
                                pc.hp -= (int)mg.damage;
                                if(pc.hp<=0){Console.WriteLine("警察死亡!");}
                                else{
                                Console.WriteLine("警察受到" + mg.damage + "点伤害,还剩" + pc.hp + "血");
                                }
                                people += 1;
                                break;
                        }
                    }
    
                    else if (people % 2 == 0)
                    {
                        Console.Write("警察选择操作:1:前进1步,伤害提高100%;2:射击,造成"+ hg.damage +"点伤害。请选择:");
                        i = Convert.ToInt32(Console.ReadLine());
                        switch (i)
                        {
                            case 1:
                                pc.forward();
                                hg.damage *= 2;
                                people += 1;
                                break;
                            case 2:
                                hg.shoot();
                                Console.WriteLine(hg.voice);
                                rb.hp -= (int)hg.damage;
                                if (rb.hp <= 0) { Console.WriteLine("坏人死亡!"); }
                                else { 
                                Console.WriteLine("坏人受到" + hg.damage + "点伤害,还剩" + rb.hp + "血");
                                }
                                people += 1;
                                break;
                        }
                    }   
                }
            Console.ReadLine();
            }
            
        }
    }
    
    

    ps:上面两行代码在一起才能运行哦
    嗯哼,首先定义一个i作为派生类在行动时的选择;people作为后面判定该谁进行选择用。
    直接看,while一个都不能死,死了就不玩了。
    if看到谁行动了
    switch看选择啥选择中,把伤害算一下,people要累加。单数时坏人,双数是jc
    于是代码就这样:你一枪我一枪的,演起来了电视桥段,最终正义或许回来迟,但是他永远不会缺席。
    在这里插入图片描述
    PS:我可真想把这玩意放到无限大.
    今天完。

    展开全文
  • C#五子棋练手项目源码,控制台五子棋小游戏,包括棋盘绘图,棋子布局,键盘控制下棋子,分两个玩家,控制台显示,可以作为初学者练习代码功底
  • 最近有越来越多做电气的小伙伴开始学习C#来做上位机开发,很多人在学习一段时间后,都有这种感觉,似乎学到了很多知识,但是不知道怎么应用,因此我找了一个真实的上位机小项目,让大家来练练。这篇文章主要对这个...

            最近有越来越多做电气的小伙伴开始学习C#来做上位机开发,很多人在学习一段时间后,都有这种感觉,似乎学到了很多知识,但是不知道怎么应用,因此我找了一个真实的上位机小项目,让大家来练练手。这篇文章主要对这个项目案例及开发过程做个整体介绍。

    1. 项目案例介绍

            很多人对单片机有一种特殊的情怀,总是感觉单片机很神秘或很复杂。单片机简称MCU,即Micro Control Unit,是将CPU、存储器(RAM和ROM)、多种IO接口等集成在一块芯片上,形成一个芯片级计算机,可以这么说,在我们的生活和工作中,单片机无处不在。

            单片机MCU的使用分为两种,一种是单片机开发,就是嵌入式开发,一般采用C语言编程,另一种是单片机应用,比如和单片机进行通信控制,而作为上位机开发人员,我们更多偏向于后者,上位机按照既定的协议对单片机实现控制。控制系统的使用者是操作人员,他们不可能去直接操作单片机,因此上位机的职责是将单片机和操作人员联系起来,通过UI界面给操作人员提供展示和控制,再将指令传递给单片机来执行动作,最终形成一套完整的控制系统。

            本案例是一个基于单片机的串口通信案例,主要是通过上位机来实现对电机的速度控制,并显示电机实时速度。调速模式会有多种,包括电机正转、电机反转、电机正反转、双向混沌、单向混沌五种模式。

    2. MCU协议分析

    针对五种调速模式的描述如下所示:

    调速模式 调速说明
    电机正转 发送一个大于0的速度给单片机
    电机反转 发送一个小于0的速度给单片机
    电机正反转 发送一个速度正负值及换速时间给单片机
    单向混沌 随机或手动生成N个的随机正数,定时发送给单片机
    双向混沌 随机或手动生成N个随机自然数,定时发送给单片机

    从上面的描述,我们可以看出,调速的本质都是发送报文给单片机,不同的调速模式影响的是发送的数值和发送的频率,因此上位机和单片机之间必须要约定协议,协议如下所示:

    功能命令 协议格式 备注
    电机正转 S+速度值+; 速度值必须为正数,如S+40;
    电机正转 S+速度值+; 速度值必须为负数,如S-40;
    电机正反转 T+时间+S+速度值+; 时间为换速时间,如T5+-40;
    单向混沌 S+速度值+; 速度值为正数,生成随机数,定时发送
    双向混沌 S+速度值+; 速度值为自然数,生成随机数,定时发送
    速度反馈 V+速度值+; 返回的速度值,如V+40;
    速度清零 S+速度值+; 速度值设为0,即S+0;或者S-0;

    协议规定:单片机与上位机之间的通信格式为:波特率9600,数据位8,停止位1,校验位无,设定速度范围为10-300rpm,反馈速度范围为0-1000rpm,换算时间范围为1-10秒,通信编码格式为ASCII。

    上位机开发功能要求:

    • 与单片机之间的连接提示及断开提示

    • 可以自由选择通讯端口

    • 调试模式可以随时调整

    • 混沌模式随机数支持自动生成和人为输入/复制粘贴

    • 支持换速时间快速设置

    • 支持实时速度显示并可控

    • 支持实时数据写入并可控

    • 支持发送命令可存储、可追溯

    • 软件打开时保持上次关闭时的状态

    3. 上位机界面设计

    根据开发功能要求,整体设计界面如下图所示:

    当选择双向混沌或者单向混沌时,会弹出混沌值设置界面,支持自动生成及手动输入,如下图所示:

    4. 上位机功能实现

    • 首先创建一个Windows窗体应用项目,项目名称为thinger.com.MCUPro。

    • 将单片机的协议封装成一个类MCULib,便于后续直接调用,该类应该具备建立连接、断开连接、设定速度、接收速度的功能。

    • 日志显示功能:日志显示采用ListView进行显示,绑定一个ImageList用来区分信息、报警、错误,添加日志方法的参数包含日志等级及日志内容。

    • 建立连接和断开连接:这里通过单按钮实现建立连接和断开连接2个功能。

    • 设置目标转速:设置目标转速仅对电机正转、电机反转及电机正反转这三种模式有效。

    • 速度清零:速度清零时要判断当前模式是否处于混沌模式,如果处于混沌模式,要先将定时器停止,否则直接发送速度为0的命令就行了。

    • 混沌模式:当调速方式切换到混沌模式时,将启用一个定时器,该定时器周期与换速时间一致,定时向MCU中发送速度指令,速度值来源于一个集合,该集合将通过一个子窗体获取,因此单向混沌与双向混沌的区别在于集合的不同。

    • 混沌速度设置:混沌值设置在一个独立的窗体中实现,可以通过手动添加、随机添加或手动输入的方式,速度值之间通过空格分割,如果手动输入时,需要注意速度范围。

    • 混沌模式定时发送:混沌模式下如果定时器开启,将从集合中逐个取出数据发送到MCU中,取完之后停止定时器。

    • 数据接收处理:数据接收处理方法也是委托的原型方法,将读取的字节数组转换成字符串进行解析,解析获取到实际转速后,判断是否进行速度显示,如果需要进行速度显示,则将数据添加到Chart控件中,再判断是否需要写入文件,如果需要写入文件,将实时数据写入到CSV文件中。

    • 实时数据写入:本案例的实时数据存储采用CSV的方式,第一次写入时,会自动创建时间及标题栏,后面不断地追加数据。软件会在每次开启或者重启写入文件时,自动按照当前时间创建一个新的文件,因此需要编写一个写入CSV的通用方法。

    • 软件打开时保持上次关闭时的状态:这个功能的实现的思路是通过配置文件来实现,在每次软件关闭时,将相关信息以配置文件的形式存储起来,当软件运行时,再次从配置文件中进行读取,由于参数较多,因此采用实体类的方式,也是便于后续扩展。

    5. 写在最后

            这个项目整体来说难度不是很大,但是很具有代表性,非常适合上位机初学者来练手。很多初学者学习最大的问题就是手头没有实际项目,大家可以把这个当做一个实际项目来练手。

    关注新阁教育服务号thinger_as,后台回复【抽奖】,奖品丰厚,先到先得。

     

    回顾往期内容

     

    【西门子】基于PLCSIM-Advanced搭建西门子PLC环境

    【西门子】西门子S7通信协议,你不知道的那些事儿

    【OPCUA】C#上位机实现OPCUA通信案例

    【OPCUA】OPCUA+MQTT+阿里云,能做哪些事儿

    【WinCC】C#/.NET联合WinCC实现数据通信

    【WinCC】手把手教你基于C#开发Wincc语音报警插件【附源码】

    【云APP】基于C#实现手机APP访问西门子PLC【附源码】

    展开全文
  • 项目的流程如下: 1.检索文件 2.修改图片的尺寸比例成3:2 3.按3:2比例分割图片成一块块正方形 4.批量修改名字 5.按顺序名字把子图片合并完整的一张图 namespace ImageTool { class Program { private ...

    案例所涉及到的内容:文件读取,写入。图片的形变,切割,缝合。

    项目的流程如下:

    1.检索文件

    2.修改图片的尺寸比例成3:2

    3.按3:2比例分割图片成一块块正方形

    4.批量修改名字

    5.按顺序名字把子图片合并完整的一张图

     

     

    namespace ImageTool
    {
        class Program
        {
            private static string _fileNameWithoutExtension; //文件名
            private static string _fileExtension;//扩展名
            private static string _fileDirectory;//所属文件夹
            private static string _targetImagePath = null;//分割图片所属的文件路径
            private static string _imageSuffix; //设置图片后缀格式
    
            public static class Data
            {
                public const string jpg = ".jpg";
                public const string bmg = ".bmg";
                public const string png = ".png";
                public const string tiff = ".tiff";
    
                public const string sprit = "\\";
    
                private static string image = null;
    
                public static string Image
                {
                    get
                    {
                        if (image == null)
                        {
                            return image = ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000).ToString();
                        }
                        else
                        {
                            return image;
                        }
    
                    }
                }
    
            }
    
    
            enum StatusMessage
            {
                Null,
                Move,
                Unusual
            }
    
            static void MessageHandling(StatusMessage SM)
            {
                switch (SM)
                {
                    case StatusMessage.Null:
                        Console.WriteLine("程序未启动...");
                        break;
                    case StatusMessage.Move:
                        Console.WriteLine("程序运行中...");
                        break;
                    case StatusMessage.Unusual:
                        Console.WriteLine("出现异常...");
                        return;
                }
            }
    
            public Program() { }
    
            static void Main()
            {
                Program program = new Program();
    
                Console.WriteLine("输入修改图片的地址...");
                var inputImgPath = Console.ReadLine();
    
                string[] suffix = { ".exe" };
                ArrayList Lists = FileSearch(inputImgPath, suffix);
                Console.WriteLine("\n" + "检索到的文件列表如下: ");
                if (Lists.Count == 0) {
    
                    Console.WriteLine("文件列表为null");
                }
                for (int i = 0; i < Lists.Count; i++)
                {
                    Console.WriteLine("files[" + i + "]: "+Lists[i].ToString());
                }
                for (int i = 0; i < Lists.Count; i++)
                {
                    if (File.Exists(Lists[i].ToString()))
                    {
                        _fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(Lists[i].ToString());
                        _fileExtension = System.IO.Path.GetExtension(Lists[i].ToString());
                        _fileDirectory = System.IO.Path.GetDirectoryName(Lists[i].ToString());
    
                    }
                    else
                    {
                        Console.WriteLine("文件不存在...");
                        MessageHandling(StatusMessage.Unusual);
                        return;
                    }
                    Console.WriteLine("\n#####################################################################");
                    Console.WriteLine("开始对文件:[--“" + Lists[i].ToString() + "”--]进行处理####");
                    var inputChangImgPath = _fileDirectory + Data.sprit + Data.Image;
                    string ChangImgPath = program.ChangImageSize(inputChangImgPath, Data.jpg);
                    program.CroppingToScale(ChangImgPath, Program._imageSuffix,false);
                    program.ChangeFilesName(_targetImagePath);
                    program.CombineImages(_targetImagePath, _targetImagePath + Data.sprit + Data.Image +"_"+ _fileNameWithoutExtension, Program._imageSuffix);
                    initialise();
                }
    
                System.Diagnostics.Process.Start(inputImgPath);//处理完成后打开相应的文件夹
                Console.WriteLine("\n" + "---输入回车键退出程序---");
                Console.ReadLine();
    
            }
    
            public static void initialise() {
    
                _fileNameWithoutExtension = null;
                _fileExtension = null;
                _fileDirectory = null;
                _targetImagePath = null;
                _imageSuffix = null;
    
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="path">路径</param>
            /// <param name="exception">排除文件名</param>
            /// <returns></returns>
            public static ArrayList FileSearch(string path, string[] exception)
            {
                if (!Directory.Exists(path))
                {
                    Console.WriteLine("不存在文件...");
                    return null;
                }
    
                int j = 0;
                ArrayList mItem = new ArrayList();
                DirectoryInfo search = new DirectoryInfo(path);
                FileSystemInfo[] fsinfos = search.GetFileSystemInfos();
    
                foreach (FileSystemInfo fsinfo in fsinfos)
                {
                    if (!(fsinfo is DirectoryInfo))
                    {
                        for (int i = 0; i < exception.Length; i++)
                        {
                            if (fsinfo.Name.Contains(exception[i]) == false)
                            {
                                mItem.Add(fsinfo.FullName);
                                j++;
                            }
                        }
    
                    }
                    else
                    {
                        //这个用于检索当前文件夹下包含的所有子文件夹
                        //DirectoryInfo dtinfo = new DirectoryInfo(fsinfo.FullName);
                        //FileInfo[] f = dtinfo.GetFiles();
                        //foreach (FileInfo file in f)
                        //{
                        //    for (int i = 0; i < exception.Length; i++)
                        //    {
                        //        if (file.Name.Contains(exception[i]) == false)
                        //        {
    
                        //            mItem.Add(file.FullName);
                        //            j++;
                        //        }
                        //    }
                        //}
    
                    }
                }
    
                return mItem;
            }
    
            /// <summary>
            /// 修正图片比例,更改为3:2比例
            /// </summary>
            /// <param name="destPath">修正后图片生成地址</param>
            /// <param name="imageSuffix">图片格式</param>
            /// <returns></returns>
            public string ChangImageSize(string destPath, string imageSuffix = Data.png)
            {
                var srcPath = _fileDirectory + Data.sprit + _fileNameWithoutExtension + _fileExtension;
                Program._imageSuffix = imageSuffix;
                try
                {
                    Image inputImg = Image.FromFile(srcPath);
                    Console.WriteLine("\n" + "修正图片尺寸");
                    int imgWidth = inputImg.Width;
                    int imgHeight = inputImg.Height;
    
                    if (imgWidth < imgHeight)
                    {
                        Console.WriteLine("当前图像“imgWidth < imgHeight”,旋转为水平方向");
                        int heightAfter = (int)Math.Ceiling(imgHeight * 1.00);
                        int widthAfter = (int)Math.Ceiling(((heightAfter * 2) / 3) * 1.00);
                        int OffsetWidth = Math.Abs((widthAfter - imgWidth) / 2);
    
                        Bitmap newBmp = new Bitmap(heightAfter, widthAfter, PixelFormat.Format24bppRgb);
                        Graphics newBmpGraphics = Graphics.FromImage(newBmp);
                        newBmpGraphics.Clear(SystemColors.AppWorkspace);
    
                        Rectangle rect = new Rectangle(0, 0, imgHeight, imgWidth);
                        Rectangle rectangle = new Rectangle(0, OffsetWidth, imgHeight, imgWidth);
                        rectangle.Inflate(0, OffsetWidth);
                        inputImg.RotateFlip(RotateFlipType.Rotate90FlipNone);//图片旋转,与画布Graphics无关
                        newBmpGraphics.DrawImage(inputImg, rectangle, rect, GraphicsUnit.Pixel);
                        newBmpGraphics.Save();
    
                        var ChangFinishImagePath = destPath + _fileNameWithoutExtension + imageSuffix;
                        BitMapSave(newBmp, ChangFinishImagePath);
    
                        inputImg.Dispose();
                        newBmp.Dispose();
                        newBmpGraphics.Dispose();
    
                        Console.WriteLine("修正成功,图片地址另存为: " + ChangFinishImagePath);
                        return ChangFinishImagePath;
    
                    }else{
    
                        int widthAfter = (int)Math.Ceiling(imgWidth * 1.00);
                        int heightAfter = (int)Math.Ceiling(((widthAfter * 2) / 3) * 1.00);
                        int OffsetHeight = Math.Abs((heightAfter - imgHeight) / 2);
    
                        Bitmap newBmp = new Bitmap(widthAfter, heightAfter, PixelFormat.Format24bppRgb);
                        Graphics newBmpGraphics = Graphics.FromImage(newBmp);
                        newBmpGraphics.Clear(SystemColors.AppWorkspace);
    
                        Rectangle rect = new Rectangle(0, 0, imgWidth, imgHeight);
                        Rectangle rectangle = new Rectangle(0, OffsetHeight, imgWidth, imgHeight);
                        rectangle.Inflate(0, OffsetHeight);                   
                        newBmpGraphics.DrawImage(inputImg, rectangle, rect, GraphicsUnit.Pixel);
                        newBmpGraphics.Save();
    
                        var ChangFinishImagePath = destPath + _fileNameWithoutExtension + imageSuffix;
                        BitMapSave(newBmp, ChangFinishImagePath);
    
                        inputImg.Dispose();
                        newBmp.Dispose();
                        newBmpGraphics.Dispose();
    
                        Console.WriteLine("修正成功,图片地址为: " + ChangFinishImagePath);
                        return ChangFinishImagePath;
                    }
                }
                catch (OutOfMemoryException e)
                {
                    Console.WriteLine("该文件没有有效的图像格式", e);
                    MessageHandling(StatusMessage.Unusual);
                    return null;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    MessageHandling(StatusMessage.Unusual);
                    return null;
                }
    
            }
    
            /// <summary>
            /// 按比例分割图片
            /// </summary>
            /// <param name="inputImgPath">导入地址</param>
            /// <param name="imageSuffix">图片格式</param>
            /// <param name="Bool">是否删除源文件</param>
            /// <returns></returns>
            public string CroppingToScale(string inputImgPath, string imageSuffix = Data.png, bool Bool = true)
            {
    
                if (!File.Exists(inputImgPath))
                {
                    Console.WriteLine("修正后的图片找不到,文件不存在...");
                    MessageHandling(StatusMessage.Unusual);
                    return null;
                }
               
                // 装载要分隔的图片 
                Image inputImg = Image.FromFile(inputImgPath);
    
                int imgWidth = inputImg.Width;
                int imgHeight = inputImg.Height;
                int cropWidth = imgWidth / 3;
                int cropHeigth = imgHeight / 2;
    
                //---------------------------------------------------------------------- 
                ArrayList areaList = new ArrayList();
    
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                sb.Append("<table cellpadding='0' cellspacing='0' border='[$border]'>");
                sb.Append(System.Environment.NewLine);
    
                int i = 0;
                int pointY = 0;
                for (int iHeight = 0; iHeight < 2; iHeight++)
                {
                    int pointX = 0;
                    sb.Append("<tr>");
                    sb.Append(System.Environment.NewLine);
                    for (int iWidth = 0; iWidth < 3; iWidth++)
                    {
                        string fileName = string.Format("<img src='http://localhost/File/{0}_{1}{2}'  />", _fileNameWithoutExtension, i, imageSuffix);
                        sb.Append("<td>" + fileName + "</td>");
                        sb.Append(System.Environment.NewLine);
                        string s = string.Format("{0};{1};{2};{3}", pointX, pointY, cropWidth, cropHeigth);
    
                        Rectangle rect = new Rectangle(pointX, pointY, cropWidth, cropHeigth);
                        areaList.Add(rect);
                        pointX += cropWidth;
                        i++;
                    }
                    pointY += cropHeigth;
                    sb.Append("</tr>");
                    sb.Append(System.Environment.NewLine);
                }
    
                sb.Append("</table>");
    
                Console.WriteLine("\n" + "检测是否存在子文件夹...");
    
                string fileSonName = System.IO.Path.GetDirectoryName(inputImgPath) + Data.sprit + Data.Image + Data.sprit + _fileNameWithoutExtension;
                _targetImagePath = fileSonName;
    
                if (Directory.Exists(fileSonName) == false)
                {
                    Console.WriteLine("文件夹不存在,创建中..");
                    Directory.CreateDirectory(fileSonName);
                }
                else
                {
                    Console.WriteLine("生成图片文件夹存在,清空已有数据..");
                    DirectoryInfo dirInfo = new DirectoryInfo(fileSonName);
                    FileInfo[] files = dirInfo.GetFiles();
    
                    foreach (FileInfo file in files)
                    {
                        file.Delete();
                        Console.WriteLine("删除数据的路径 : " + file.DirectoryName + Data.sprit + file.Name);
                    }
                    Console.WriteLine("删除完毕!!!");
                }
                Console.WriteLine("\n" + "开始切割图片...");
    
                for (int iLoop = 0; iLoop < areaList.Count; iLoop++)
                {
                    Rectangle rect = (Rectangle)areaList[iLoop];
                    string fileName = fileSonName + Data.sprit + iLoop.ToString() + imageSuffix;
    
                    Bitmap newBmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format24bppRgb);
                    Graphics newBmpGraphics = Graphics.FromImage(newBmp);
                    Rectangle rectangle = new Rectangle(0, 0, rect.Width, rect.Height);
                    newBmpGraphics.DrawImage(inputImg, rectangle, rect, GraphicsUnit.Pixel);
    
                    newBmpGraphics.Save();
                    BitMapSave(newBmp, fileName);
    
                    Console.WriteLine("图片生成路径: " + fileName);
                    newBmp.Dispose();
                    newBmpGraphics.Dispose();
                }
    
                inputImg.Dispose();
    
                if (Bool)
                {
                    File.Delete(inputImgPath);
                    Console.WriteLine("\n" + "修正图已被删除(***默认处理***)...,路径: " + inputImgPath);
                }
    
                string html = sb.ToString();
                Console.WriteLine("\n" + "Html(表): " + "\n" + html + "\n");
                return html;
            }
    
            /// <summary>
            /// 修改分割文件名字
            /// </summary>
            /// <param name="folderPath"></param>
            public void ChangeFilesName(string folderPath)
            {
                if (!Directory.Exists(folderPath)) {
                    MessageHandling(StatusMessage.Unusual);
                    return;
                }
                var files = new DirectoryInfo(folderPath).GetFiles();
                Console.WriteLine("进行图片名字批处理..." + "\n" + "读取到的总数: " + files.Length);
    
                if (files.Length == 0)
                {
                    Console.WriteLine("未读取到文件");
                    MessageHandling(StatusMessage.Unusual);
                    return;
                }
                    Console.WriteLine("开始修改... " + "\n\n" + "修改后名字: ");
                    int i = 0;
                    //文件名字处理在此修改
                    foreach (FileInfo file in files)
                    {
                        //string move_test = file.DirectoryName + Data.sprit + "New_image_" + Math.Abs(files.Length - int.Parse(file.Name.Remove(file.Name.IndexOf("."))));
                        //file.MoveTo(move_test + Data.png);
    
                        string move = file.DirectoryName + Data.sprit + "New_image_" + file.Name;
                        file.MoveTo(move);
                        Console.WriteLine("files[" + i + "]: " + move);
    
                        i++;
                    }
                    //int i = 0;
                    //while (i == files.Length)
                    //{
                    //    switch (i)
                    //    {
                    //        case 0:
                    //            files[i].MoveTo(files[i].DirectoryName + Data.sprit + "New_image_" + Math.Abs(files.Length - int.Parse(files[i].Name)));                            
                    //            break;
                    //        case 1:                            
                    //            files[i].MoveTo(files[i].DirectoryName + Data.sprit + "New_image_" + Math.Abs(files.Length - int.Parse(files[i].Name)));
                    //            break;
                    //        case 2:
                    //            files[i].MoveTo(files[i].DirectoryName + Data.sprit + "New_image_" + Math.Abs(files.Length - int.Parse(files[i].Name)));
                    //            break;
                    //        case 3:
                    //            files[i].MoveTo(files[i].DirectoryName + Data.sprit + "New_image_" + Math.Abs(files.Length - int.Parse(files[i].Name)));
                    //            break;
                    //        case 4:
                    //            files[i].MoveTo(files[i].DirectoryName + Data.sprit + "New_image_" + Math.Abs(files.Length - int.Parse(files[i].Name)));
                    //            break;
                    //        case 5:
                    //            files[i].MoveTo(files[i].DirectoryName + Data.sprit + "New_image_" + Math.Abs(files.Length - int.Parse(files[i].Name)));
                    //            break;
                    //    }
                    //    Console.WriteLine("Newfile: " + files[i].DirectoryName + Data.sprit + "New_image_" + Math.Abs(files.Length - int.Parse(files[i].Name)));
                    //    i++;
                    //}
                
    
            }
    
            /// <summary>
            /// 缝合图片,根据名字顺序
            /// </summary>
            /// <param name="folderPath">导入地址</param>
            /// <param name="toPath">导出图片地址</param>
            /// <param name="imageSuffix">图片格式</param>
            private void CombineImages(string folderPath, string toPath, string imageSuffix = Data.png)
            {
                if (!Directory.Exists(folderPath))
                {
                    MessageHandling(StatusMessage.Unusual);
                    return;
                }
                //var files = new DirectoryInfo(folderPath).GetFiles("*" + Data.png, SearchOption.TopDirectoryOnly);//目前检索到的文件只有图片,干脆全部获取
                var files = new DirectoryInfo(folderPath).GetFiles();
                if (files.Length == 0)
                {
                    Console.WriteLine("文件不存在...");
                    MessageHandling(StatusMessage.Unusual);
                }
                Console.WriteLine("\n" + "进行图片缝合..." + "\n" + "处理中...Biubiubiu...");
    
                var imgs = files.Select<FileInfo, Image>(f => Image.FromFile(f.FullName));
                var finalWidth = imgs.Max<Image>(img => img.Width * 3);
                var finalHeight = imgs.Max<Image>(img => img.Height * 2);
    
                var finalImg = new Bitmap(finalWidth, finalHeight);
                Graphics g = Graphics.FromImage(finalImg);
                g.Clear(SystemColors.AppWorkspace);
    
                var width = 0;
                var height = 0;
                for (int i = 0; i < files.Length; i++)
                {
    
                    Image img = Image.FromFile(files[i].FullName);
                    g.DrawImage(img, width, height);
                    width += img.Width;
    
                    bool res = (i == 2) ? true : false;
    
                    if (res)
                    {
                        width = 0;
                        height += img.Height;
                    }
    
                    img.Dispose();
                }
    
                var finalImage = toPath + imageSuffix;
                BitMapSave(finalImg, finalImage);
    
                finalImg.Dispose();
                g.Dispose();
    
                Console.WriteLine("文件已保存,地址: " + finalImage);
                Console.WriteLine("文件:[--" + _fileNameWithoutExtension + _fileExtension + "--]处理完毕!!!!");
    
            }
    
            /// <summary>
            /// 保存BitMap
            /// </summary>
            /// <param name="bmp"></param>
            /// <param name="path">保存路径</param>
            /// <param name="imageSuffix">文件后缀</param>
            public static void BitMapSave(Bitmap bmp, string path)
            {
    
                switch (_imageSuffix.ToLower())
                {
    
                    case ".bmg":
                        bmp.Save(path, ImageFormat.Bmp);
                        break;
                    case ".png":
                        bmp.Save(path, ImageFormat.Png);
                        break;
                    case ".jpg":
                    case ".jpeg":
                        bmp.Save(path, ImageFormat.Jpeg);
                        break;
                    case "gif":
                        bmp.Save(path, ImageFormat.Tiff);
                        break;
                }
    
            }
    
        }
    }
    

     

     

     

     

     

     

    展开全文
  • 配合Winform窗体界面,实现了简单的窗体间互相通信的小项目(可以互相发消息,服务器可以给客户端发送文件和震动弹出)。 现在把这两天学习到的知识点记录下来分享。。。 首先要声明:本篇博客并不会详细的讲解...

    在公司花了两天的时间来研究Socket编程,感觉也还是学到了一点点皮毛,不过也还是有一点点的小成就。

    配合Winform窗体界面,实现了简单的窗体间互相通信的小项目(可以互相发消息,服务器可以给客户端发送文件和震动弹出)。

    现在把这两天学习到的知识点记录下来分享。。。

    首先要声明:本篇博客并不会详细的讲解Socket底层的实现逻辑,只是讲解他是怎么运用的,是怎么实现窗体间通信的。


    Socket的简单原理

    Socket的两个概念:端口协议

    端口

    我们是通过服务端去访问应用程序的,但是在同一个服务端中的应用程序,他们的IP地址都是一样的,所以单单通过IP地址去访问对应的应用程序是不可能的,所以,得再结合端口去实现具体的访问。
    每个应用程序就会有一个端口,我们就可以根据IP地址和端口号去实现访问了。(每个应用程序的端口号都是唯一的)

    在这里插入图片描述

    通过端口和IP地址客户端就可以准确无误的去访问服务器里面的应用程序了。

    在访问的过程中,又会涉及到协议的问题!

    协议

    Socket有两个协议:TCPUDP

    TCP

    其中我们要知道,TCP协议是网络上比较安全稳定的协议,一般不会发送数据丢失。使用TCP协议建立网络连接,需要经过“三次握手”才建立连接。如下图:
    在这里插入图片描述
    只有客户端和服务器完成了这三次握手的过程,服务器才会和客户端进行数据的传输。(只要是少了一次都不会进行互相通信)

    TCP建立网络连接的优缺点:

    1. 优点:安全,稳定,防止数据丢失。
    2. 缺点:效率低,经过三次握手的过程,需要耗费一定的时间。

    UDP

    UDP协议是与TCP协议相反的。

    UDP协议不管服务器有没有空,就是一直给服务器发送消息,直到发完为止。他不管服务器有没有接收到,他只是要完成任务就行。
    在这里插入图片描述

    如果服务器很忙的话,并没有时间去处理客户端发过来的消息,那么就会造成数据丢失。

    UDP建立网络连接的优缺点:

    1. 优点:快速,效率高。
    2. 缺点:不稳定,容易造成数据丢失。

    两个协议各有的优缺点,也不好说哪个比较好。
    像UDP协议一般用于视频的传输等。

    好了TCP/UDP协议了解到这里就好了!


    Socket

    需要包含命名空间:
    using System.Net;
    using System.Net.Sockets;

    一个服务器至少有两个Socket用于通信,一个用来监听,一个用来连接客户端进行通信。

    我们先看一张图:
    在这里插入图片描述
    这张图描述的就是客户端和服务其进行互相通信的过程。
    下面的讲解也是根据这张图来说明。

    1. Socket
      他是一个类,用来定义对象进行通信。
      首先创建一个用于监听的Socket(监听有没有客户端连接服务器)
      如代码:
    // 一个负责监听的Socket ************************************************************************
    								// ip地址的类型(ipV4/ipv6)   选择以流的方式     流对应的是Tcp协议
    Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    

    参数一:填写IP地址的类型(ipv4:InterNetwork; ipv6:InterNetworkV6)

    参数二:填写TCP/UDP连接对应的方式
    补充知识点:TCP是以的方式(Stream);UDP是以数据报的方式(Dgram)。

    参数三:填写TCP/UDP协议
    这里就用了TCP的传输方式。

    然后创建ip地址和端口号对象:

    // 创建ip地址和端口号对象     
    IPAddress iPAddress = IPAddress.Any; //IPAddress.Parse(this.txtSever.Text);
    IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, Convert.ToInt32(this.txtPort.Text));
    

    Any是自动获取连接进行的客户端的IP地址。
    端口号是获取我们textBox控件里面的。

    1. Bind
      绑定监听端口

      // 让负责监听的Socket绑定IP地址和端口号
      socketWatch.Bind(iPEndPoint);
      

      到了这里,就完成了监听的工作。

    2. Listen
      设置监听队列
      在同一个时间段允许最大的连接个数

      // 设置监听队列(比如在同一个时间段允许最大的连接个数)
      socketWatch.Listen(10);
      

      比如在一秒内最多允许10个客户端连接服务器,从第11个客户端往后都得排队等待连接。

    3. Accept
      该函数用于等待客户端与服务器进行连接,并返回一个新的Socket,用于与客户端进行通信。

       // 负责监听的Socket来接受客户端的连接(创建跟客户端通信的Socket)
       Socket  socket = socketWatch.Accept();   // Accept() : 等待客户端连接
      

      利用死循环可以一直与多个客户端进行连接
      为了不卡死主线程,可以使用多线程对其进行操作!

       // 该线程的作用是:服务器不停的监听,等待客户端连接,并且创建与之通信用的Socket
      Thread th = new Thread(Listen);
      th.IsBackground = true;
      th.Start(socketWatch);
      
      private void Listen(Object o) {
      	Socket socketWatch = o as Socket;
      
      	// 等待客户端连接,并且创建与之通信用的Socket
      	while (true) {
      		// 负责监听的Socket来接受客户端的连接(创建跟客户端通信的Socket)
      		Socket socket= socketWatch.Accept();   // Accept() : 等待客户端连接                
      	}
             
      }
      
    4. Receive
      获取客户端发过来的消息(单位:byte)

      // 客户端连接成功后,服务器接收客户端发来的消息
      byte[] buffer = new byte[1024 * 1024 * 2];
      // b:实际接收到的有效字节数    
      int b = socket.Receive(buffer); // 调用Receive函数返回客户端发来的消息(单位:字节)
      

      可以根据b来判断客户端发过来的消息的字节个数。

    5. Send
      服务器给客户端发送消息

      仅支持字节发送数组发送

      byte[] newByte = Encoding.UTF8.GetBytes("我是服务器");
      socket.Send(newByte);
      

    好了,服务器的流程基本上就这样了。

    客户端与服务端雷同,就不演示了。




    练手小项目

    可能讲的不是很好,但是没关系,我把我自己写好的代码上传到此给需要的朋友玩一下。(可以实现两个窗口间互相通信)

    界面如下:

    服务器:
    在这里插入图片描述
    客户端:
    在这里插入图片描述

    代码如下:
    服务器

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace _Socket {
        public partial class Form1 : Form {
            public Form1() {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e) {
                Control.CheckForIllegalCrossThreadCalls = false;
            }
    
            private void btnStart_Click(object sender, EventArgs e) {
                try {
                    // 一个负责监听的Socket ************************************************************************
                    // ip地址的类型(ipV4/ipv6)   选择以流的方式     流对应的是Tcp协议
                    Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
                    // 创建ip地址和端口号对象     
                    IPAddress iPAddress = IPAddress.Any; //IPAddress.Parse(this.txtSever.Text);
                    IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, Convert.ToInt32(this.txtPort.Text));
    
                    // 让负责监听的Socket绑定IP地址和端口号
                    socketWatch.Bind(iPEndPoint);
    
                    ShowMsg("监听成功!");
    
                    // 设置监听队列(比如在同一个时间段允许最大的连接个数)
                    socketWatch.Listen(10);
    
    
                    // 该线程的作用是:服务器不停的监听,等待客户端连接,并且创建与之通信用的Socket
                    Thread th = new Thread(Listen);
                    th.IsBackground = true;
                    th.Start(socketWatch);
                }
                catch (Exception) {  }
                  
            }
    
    
            // 存储连接服务器的客户端的IP地址/端口号和负责通信的socket
            Dictionary<string, Socket> dictionary = new Dictionary<string, Socket>();
    
    
            Socket socket;  // 负责通信
            private void Listen(Object o) {
                Socket socketWatch = o as Socket;
    
                // 等待客户端连接,并且创建与之通信用的Socket
                while (true) {
                    try {
                        // 负责监听的Socket来接受客户端的连接(创建跟客户端通信的Socket)
                        socket = socketWatch.Accept();   // Accept() : 等待客户端连接
                        // 将连接成功后的客户端IP地址和端口号显示出来
                        ShowMsg(socket.RemoteEndPoint.ToString() + "连接成功\r\n");
    
                        // 将远程连接的客户端的IP地址和socket存入集合中
                        dictionary.Add(socket.RemoteEndPoint.ToString(), socket);
    
                        // 将远程连接的客户端的IP地址和端口号存储到下拉框中
                        this.cobUsers.Items.Add(socket.RemoteEndPoint.ToString());
    
                        // 该线程的作用是:使服务器不停的接收客户端发过来的消息
                        Thread th = new Thread(Recive);
                        th.IsBackground = true;
                        th.Start(socket);
                    }
                    catch (Exception) {  }
                             
                }
               
            }
    
    
            // 服务器不停的接收客户端发过来的消息
            private void Recive(Object o) {
                Socket socket = o as Socket;
    
                while (true) {
                    try {
                        // 客户端连接成功后,服务器接收客户端发来的消息
                        byte[] buffer = new byte[1024 * 1024 * 2];
                        // b:实际接收到的有效字节数    
                        int b = socket.Receive(buffer); // 调用Receive函数返回客户端发来的消息(单位:字节)
    
                        // 用户点击了叉×
                        if (b == 0) {
                            break;
                        }
    
                        // 将其转为人能看得懂的字符串类型
                        string str = Encoding.UTF8.GetString(buffer, 0, b);
                        ShowMsg(socket.RemoteEndPoint.ToString() + "(客户端):" + str);  // 显示出来
                    }
                    catch (Exception) { }
                    
                }
            }
    
            private void ShowMsg(string str) {
                this.txtLog.AppendText(str + "\r\n");
            }
    
    
            private void btnSend_Click(object sender, EventArgs e) {
    
                try {
                    // 获取文本的值并转换为byte类型数组
                    byte[] by = Encoding.UTF8.GetBytes(this.txtMsg.Text.Trim());
                    this.txtMsg.Text = "";
    
                    // 定义一个泛型集合,将文本表示符0 和 byte数组存储入集合中
                    List<byte> list = new List<byte>();
                    list.Add(0);
                    list.AddRange(by);
    
                    // 将泛型集合转换为数组
                    byte[] newByte = list.ToArray();
                    
    
                    // 服务器给客户端发送消息
                    //socket.Send(by);
                    string ip = this.cobUsers.SelectedItem.ToString();  // 获得下拉框中选中项的IP地址和端口号
                    dictionary[ip].Send(newByte);    // 将其传入Dictionary中获得跟客户端通信的socket
                }
                catch (Exception) {  }
                
            }
    
            // 选择需要发送的文件
            private void btnSelect_Click(object sender, EventArgs e) {
    
                try {
                    OpenFileDialog ofd = new OpenFileDialog();
    
                    // 设置初始路径
                    ofd.InitialDirectory = @"C:\Users\yangg\Desktop";
                    ofd.Title = "请选择你需要发送的文件";
                    // 设置文件筛选
                    ofd.Filter = "所有文件|*.*";
    
                    if (ofd.ShowDialog() == DialogResult.OK) {
                        this.txtPath.Text = ofd.FileName;
                    }
                }
                catch (Exception) {  }
                
            }
    
            private void btnSentFile_Click(object sender, EventArgs e) {
    
                try {
                    // 获取文件路径
                    string path = this.txtPath.Text;
    
                    // 使用文件流以读的方式打开文件
                    using (FileStream fileRead = new FileStream(path, FileMode.Open, FileAccess.Read)) {
                        byte[] buffer = new byte[1024 * 1024 * 10];
    
                        // 将文件中的数据读取进字节数组中,返回读取到的个数
                        int r = fileRead.Read(buffer, 0, buffer.Length);
    
                        List<byte> list = new List<byte>();
                        list.Add(1);
                        list.AddRange(buffer);
    
                        byte[] newBuffer = list.ToArray();
    
                        // 发送
                        dictionary[this.cobUsers.SelectedItem.ToString()].Send(newBuffer, 0, r + 1, SocketFlags.None);
                    }
                }
                catch (Exception) {  }
                
            }
    
            private void btnZD_Click(object sender, EventArgs e) {
                byte[] buffer = new byte[1];
                buffer[0] = 2;
                dictionary[this.cobUsers.SelectedItem.ToString()].Send(buffer);
            }
    
        }
    }
    
    

    客户端

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace _Client {
        public partial class Form1 : Form {
            public Form1() {
                InitializeComponent();
            }
    
            Socket socket;
            private void btnStart_Click(object sender, EventArgs e) {
    
                try {
                    // 创建一个发送消息的Socket
                    socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
                    // 建立IP地址和端口号的对象
                    IPAddress iPAddress = IPAddress.Parse(this.txtSever.Text);
                    IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, Convert.ToInt32(this.txtPort.Text));
    
                    // 客户端服务器建立连接
                    socket.Connect(iPEndPoint);
    
                    Shows("连接成功!");
    
                    // 建立线程,无限的接收服务器发过来的消息
                    Thread th = new Thread(Recive);
                    th.IsBackground = true;
                    th.Start();
                }
                catch (Exception) {  }
                
            }
    
            private void Shows(string str) {
                this.txtLog.AppendText(str + "\r\n");
            }
    
            // 客户端给服务器发送消息
            private void benSend_Click(object sender, EventArgs e) {
    
                try {
                    // 获取待发送的文本,并转换为byte字节数组
                    byte[] by = Encoding.UTF8.GetBytes(this.txtMsg.Text.Trim());
                    this.txtMsg.Text = "";
    
                    // 客户端给服务器发送消息
                    socket.Send(by);
                }
                catch (Exception) {  }
                
            }
    
    
            // 不停的接收服务器发过来的消息
            private void Recive() {
    
                while (true) {
    
                    try {
                        byte[] by = new byte[1024 * 1024 * 10];
                        // 获取服务器发过来的消息,返回接收到的个数
                        int r = socket.Receive(by);
                        if (r == 0) {
                            break;
                        }
    
    
                        // 表示发送文字消息
                        if (by[0] == 0) {
                            string str = Encoding.UTF8.GetString(by, 1, r - 1);
                            Shows(socket.RemoteEndPoint.ToString() + "(服务器):" + str);
                           
                        } else if (by[0] == 1) {    // 表示发送文件
                            SaveFileDialog sfd = new SaveFileDialog();
                            sfd.InitialDirectory = @"C:\Users\yangg\Desktop";
                            sfd.Title = "请选择报错位置";
                            sfd.Filter = "所有文件|*.*";
    
                            
                            if (sfd.ShowDialog(this) == DialogResult.OK) {
                                string path = sfd.FileName;
    
                                using (FileStream fileWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) {
                                    fileWrite.Write(by, 1, r - 1);                               
                                }
                                MessageBox.Show("保存成功");
                            }
                            
                        } else if (by[0] == 2) {    // 表示发送震动
                            ZD();
                        }
                    }
                    catch (Exception) {  }
                    
                }
                
            }
    
    
            // 震动
            private void ZD() {
                int x = this.Location.X;
                int y = this.Location.Y;
    
                for (int i = 0; i < 300; i++) {
                    this.Location = new Point(x - 50, y);
                    this.Location = new Point(x, y + 50);
                    this.Location = new Point(x + 50, y);
                    this.Location = new Point(x, y - 50);
                    
                }
    
                this.Location = new Point(x, y);
            }
    
            private void Form1_Load(object sender, EventArgs e) {
                Control.CheckForIllegalCrossThreadCalls = false;
            }
        }
    }
    
    

    CSDN:
    https://download.csdn.net/download/cpp_learner/12761444

    百度连接:
    链接:https://pan.baidu.com/s/16TE3Q51NhxMXNv2sp9gfcQ
    提取码:fc4n


    总结:
    也就基本上是这样了,其他的也就不会了,希望对大家有帮助吧!

    展开全文
  • 下面是文件加密和解密功能的代码 using System.Security.Cryptography;... public void EncryptFile(string filePath, string...完整项目下载地址: http://download.csdn.net/detail/wang03989/9620188
  • 开始学习C#之路,起当然是小小计算器了,这个小软件,包含了很多C#的精华,比如TextBox只处理数字和加减符号等,TextBox设置多行并一直显示最下面,编译生成更改自己的图标等......总之,麻雀虽小,五脏俱全!非常...
  • ...测试小项目: 工程下载: http://download.csdn.net/detail/wang03989/9618807 gif操作类库 http://download.csdn.net/detail/wang03989/9618833
  • JavaScript、C#、Ruby以及Objective-C……每一种编程语言,都有由其打造的顶级应用成果呈现。 根据TIOBE 刚刚发布了 5 月编程语言排行榜,排名前三的依旧有C/C++。而且都出现了不同幅度的增长,C语言增长幅度最高...
  • 原标题:推荐一些适合新手练手的Python项目最好的编程语言是什么?一千个程序员或许会有一千零一种答案:PHP自然是不会错过这个噱头、C/C++作为元老级的编程语言一直屹立不倒、Java依旧是市场上的香饽饽、当然还有...
  • c#语言,JDBC技术,加算法完成一个简单的俄罗斯方块游戏系统,合适初学者练手项目
  • ** 一、系统概述 ** 基于RFID的图书仓储管理系统的设计以...本系统的设计包括应用层Web端管理软件、传输层C#数据采集中间软件以及感知层RFID硬件阅读器,通过这三个主要的部分,系统完成了数据从感知到应用的有...
  • 一千个程序员或许会有一千零一种答案:PHP自然是不会错过这个噱头、C/C++作为元老级的编程语言一直屹立不倒、Java依旧是市场上的香饽饽、当然还有JavaScript、C#、Ruby以及Objective-C……每一种编程语言,都有由其...
  • 推荐一些适合新手练手的C/C++项目

    万次阅读 多人点赞 2018-05-09 20:27:08
    JavaScript、C#、Ruby以及Objective-C……每一种编程语言,都有由其打造的顶级应用成果呈现。根据TIOBE 刚刚发布了 5 月编程语言排行榜,排名前三的依旧有C/C++。而且都出现了不同幅度的增长,C语言增长幅度最高达到...
  • 这是一个用C#语言在visual studio2019上制作的简单计算器,包括四则运算和一些异常处理,界面也做了处理,不失为一个练手的小项目,欢迎大家下载

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 175
精华内容 70
关键字:

c#练手项目

c# 订阅