Windows环境+C#实现显示接口测试

代码如下:

using Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tools;
using DisplayMode = Models.DisplayMode;

namespace TestItem
{
    public partial class VideoTestManager : Form
    {
        private string originalDirectory = System.Environment.CurrentDirectory; // 保存当前目录
        private string programName = string.Empty;//程式名称
        public event Action<bool> CallExit = null;//回调函数
        private bool isPass = false;
        private string readValues = null; // 测试参数
        private string testArgs = null;//测试参数
        private List<string> testItem=null;//测试项目
        private string playFileName = string.Empty;//播放文件名称
        private List<DisplayEntity> displayEntity;//显示实体
        private int random_number = 0;//随机数
        private int input_number = 0;//输入数

        #region 构造函数
        //显示模式
        public VideoTestManager()
        {
            InitializeComponent();
            this.CallExit += (isPass) => { }; // 初始化事件
            this.Load += VideoTestManager_Load;
            this.FormClosing += VideoTestManager_FormClosing;
            this.KeyDown += VideoTestManager_KeyDown;
            this.KeyPreview = true; // Enable the form to receive key events
        }
        #endregion

        #region 窗体加载
        private const byte VK_LEFT = 0x25;
        private const byte VK_RIGHT = 0x27;
        private async void VideoTestManager_Load(object sender, EventArgs e)
        {
            if (await this.GetTestArgs())
            {
                this.SetHeaderStyle(); // 设置表头信息样式
                this.displayEntity = new List<DisplayEntity>();//初始化显示实体
                timer_Test.Enabled = true;
            }
        }
        #endregion

        #region 切屏显示
        /// <summary>
        /// 切屏显示
        /// </summary>
        /// <param name="mode"></param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        private void SwitchDisplayMode(DisplayMode mode)
        {
            string argument;
            switch (mode)
            {
                case DisplayMode.Internal:
                    argument = "/internal";
                    break;
                case DisplayMode.Clone:
                    argument = "/clone";
                    break;
                case DisplayMode.Extend:
                    argument = "/extend";
                    break;
                case DisplayMode.External:
                    argument = "/external";
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            Process.Start("DisplaySwitch.exe", argument);
        }
        #endregion

        #region 获取测试参数
        private async Task<bool> GetTestArgs()
        {
            try
            {
                //获取程式名称
                this.programName = AuxiliaryItemArray.GetProgramName(this.lbl_ShowResult) != null ? AuxiliaryItemArray.GetProgramName(this.lbl_ShowResult) + @".exe" : null;
                if (this.programName == null)
                    return false;

                // 获取测试参数
                this.testArgs = AuxiliaryItemArray.GetTestParameter(this.originalDirectory, this.programName, this.lbl_ShowResult);
                if (this.testArgs == null)
                    return false;

                //解析参数
                string[] args = this.testArgs.Split('|');

                this.playFileName = args[1].Split('=')[1];

                this.testItem = new List<string>();
                this.testItem = args[0].Split(',').ToList();
                this.lbl_TestArgs.BeginInvoke(new Action(() => { 
                    this.lbl_TestArgs.Text= args[0];
                }));

                return this.testItem.Count>0;
            }
            catch (Exception ex)
            {
                this.Invoke(new Action(() =>
                {
                    AuxiliaryItemArray.Loginfo($@"获取测试参数:{ex.Message}", false, lbl_ShowResult);
                }));
                return false;
            }
        }
        #endregion

        #region 播放视频
        /// <summary>
        /// 播放视频
        /// </summary>
        /// <param name="playFileName">播放文件</param>
        /// <returns></returns>
        private async Task<bool>Mp4Play(string playFileName)
        {
            try
            {
                //设置播放器URL
                // 获取当前目录
                string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;
                // 拼接视频文件路径
                string videoPath = Path.Combine(currentDirectory, "Video", playFileName);

                if (File.Exists(videoPath))
                {
                    // 设置播放器URL
                    wmpPlayer.URL = videoPath;
                    // 设置循环播放模式
                    wmpPlayer.settings.setMode("loop", true);
                    return true;
                }
                else
                {
                    this.Invoke(new Action(() =>
                    {
                        AuxiliaryItemArray.Loginfo("视频文件未找到: " + videoPath, false, lbl_ShowResult);
                    }));
                    return false;
                }
            }
            catch(Exception ex)
            {
                this.Invoke(new Action(() =>
                {
                    AuxiliaryItemArray.Loginfo($@"播放MP4错误:{ex.Message}", false, lbl_ShowResult);
                }));
                return false;
            }
        }
        #endregion

        #region 设置表头信息样式
        private void SetHeaderStyle()
        {
            // 设置参数列宽度,使用百分比
            this.tabPanel_Args.ColumnStyles[0].SizeType = SizeType.Percent;
            this.tabPanel_Args.ColumnStyles[0].Width = 25;
            this.tabPanel_Args.ColumnStyles[1].SizeType = SizeType.Percent;
            this.tabPanel_Args.ColumnStyles[1].Width = 25;
            this.tabPanel_Args.ColumnStyles[2].SizeType = SizeType.Percent;
            this.tabPanel_Args.ColumnStyles[2].Width = 25;
            this.tabPanel_Args.ColumnStyles[3].SizeType = SizeType.Percent;
            this.tabPanel_Args.ColumnStyles[3].Width = 25;
        }
        #endregion

        #region 关闭窗体
        private void VideoTestManager_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.readValues = JsonConvert.SerializeObject(this.displayEntity, Formatting.Indented);//将实体类转换成json文件
            AuxiliaryItemArray.UpdateJsonInfo(this.programName, this.readValues, this.isPass, this.originalDirectory, this.lbl_ShowResult);
            this.ProcessExit(this.isPass);
        }
        #endregion

        #region 关闭进程
        private void ProcessExit(bool isPass)
        {
            CallExit?.Invoke(isPass);
        }
        #endregion

        #region 定时触发器
        private async void timer_Test_Tick(object sender, EventArgs e)
        {
            timer_Test.Enabled = false;
            bool testResult = true;
            string[] testArgsValues = this.testArgs.Split(',');

            foreach (var a in testArgsValues)
            {
                if (!this.displayEntity.Any(d => d.ProtName == a))
                {
                    testResult = false;
                    break;
                }
            }

            if (testResult)
            {
                this.readValues = JsonConvert.SerializeObject(this.displayEntity, Formatting.Indented);//将实体类转换成json文件
                AuxiliaryItemArray.UpdateJsonInfo(this.programName, this.readValues, true, this.originalDirectory, this.lbl_ShowResult);
                this.ProcessExit(this.isPass);
            }
            else
            {
                DisplayManager displayManager = new DisplayManager();
                DisplayEntity tempdata = new DisplayEntity();
                displayManager.DetectDisplays();
                if (displayManager.displayEntity.Count > 0)
                {
                    foreach (DisplayEntity ds in displayManager.displayEntity)
                    {
                        this.currentTestPort = new DisplayEntity();
                        if (!displayEntity.Any(d => d.ProtName == ds.ProtName) || displayEntity.Count == 0)
                        {
                            this.currentTestPort = ds;
                            tempdata = ds;
                            TestDisplayPort();//测试显示接口
                            if (ds.DeviceName.ToUpper().Contains("DISPLAY1"))
                            {
                                this.SwitchDisplayMode(DisplayMode.Internal);//仅第一个屏显示
                                this.currentTestPort.SwDisplayMode = DisplayMode.Internal;
                                break;
                            }
                            else
                            {
                                this.SwitchDisplayMode(DisplayMode.External);//仅第二个屏显示
                                this.currentTestPort.SwDisplayMode = DisplayMode.External;
                                break;
                            }
                        }
                    }
                }
            }
        }

        #endregion

        #region 显示接口测试
        /// <summary>
        /// 测试显示接口
        /// </summary>
        /// <param name="protName">接口名称</param>
        private async void TestDisplayPort()
        {
            this.input_number = 0;
            Random random = new Random();
            this.random_number = random.Next(1,9);

            this.lbl_ShowResult.BeginInvoke(new Action(() => {
                this.lbl_ShowResult.ForeColor = Color.SteelBlue;
                this.lbl_ShowResult.Text = $@"{this.currentTestPort.ProtName}接口测试中..";
            }));

            this.lbl_Random.BeginInvoke(new Action(() => {
                this.lbl_Random.Text = this.random_number.ToString();
            }));

            await this.Mp4Play(this.playFileName);//Mp4播放

            waitTime = 20;
            timer_random.Enabled = true;
            
        }
        #endregion

        #region 随机数检测
        private int waitTime = 0;//等待时间
        private DisplayEntity currentTestPort;//当前测试接口
        private async void timer_random_Tick(object sender, EventArgs e)
        {
            if(waitTime==0)
            {
                if(currentTestPort.ProtName=="VGA")
                {
                    this.lbl_VGA_result.Text = "FAIL";
                    this.lbl_VGA_result.ForeColor = Color.Red;
                }
                else if(currentTestPort.ProtName == "DVI")
                {
                    this.lbl_DVI_result.Text = "FAIL";
                    this.lbl_DVI_result.ForeColor = Color.Red;
                }
                else if (currentTestPort.ProtName == "DP")
                {
                    this.lbl_DP_result.Text = "FAIL";
                    this.lbl_DP_result.ForeColor = Color.Red;
                }
                else if (currentTestPort.ProtName == "HDMI")
                {
                    this.lbl_HDMI_result.Text = "FAIL";
                    this.lbl_HDMI_result.ForeColor = Color.Red;
                }

                this.lbl_ShowResult.BeginInvoke(new Action(() => {
                    this.lbl_ShowResult.Text = $@"{this.currentTestPort.ProtName}接口测试Fail";
                    this.lbl_ShowResult.ForeColor = Color.Red;
                }));

                this.SwitchDisplayMode(DisplayMode.Extend);//扩展屏显示
                await this.Mp4Play(this.playFileName);//Mp4播放
                timer_random.Enabled = false;
                this.timer_Test.Enabled = true;
            }
            else
            {
                if(this.input_number==0)
                    waitTime--;
                else
                {
                    if (currentTestPort.ProtName == "VGA")
                    {
                        this.lbl_VGA_result.Text = this.input_number == this.random_number ? "PASS" : "FAIL";
                        this.lbl_VGA_result.ForeColor = this.input_number == this.random_number ? Color.Green : Color.Red;
                    }
                    else if (currentTestPort.ProtName == "DVI")
                    {
                        this.lbl_DVI_result.Text = this.input_number == this.random_number ? "PASS" : "FAIL";
                        this.lbl_DVI_result.ForeColor = this.input_number == this.random_number ? Color.Green : Color.Red;
                    }
                    else if (currentTestPort.ProtName == "DP")
                    {
                        this.lbl_DP_result.Text = this.input_number == this.random_number ? "PASS" : "FAIL";
                        this.lbl_DP_result.ForeColor = this.input_number == this.random_number ? Color.Green : Color.Red;
                    }
                    else if (currentTestPort.ProtName == "HDMI")
                    {
                        this.lbl_HDMI_result.Text = this.input_number == this.random_number ? "PASS" : "FAIL";
                        this.lbl_HDMI_result.ForeColor = this.input_number == this.random_number ? Color.Green : Color.Red;
                    }

                    this.timer_random.Enabled = false;

                    if (this.input_number == this.random_number)
                    {
                        this.currentTestPort.TestResult = "PASS";
                        this.displayEntity.Add(this.currentTestPort);
                    }

                    this.lbl_ShowResult.BeginInvoke(new Action(() => {
                        this.lbl_ShowResult.Text = $@"{this.currentTestPort.ProtName}接口测试PASS";
                        this.lbl_ShowResult.ForeColor = Color.Green;
                    }));

                    this.waitTime = 0;
                    this.SwitchDisplayMode(DisplayMode.Extend);//扩展屏显示
                    await this.Mp4Play(this.playFileName);//Mp4播放
                    this.timer_Test.Enabled = true;
                }
            }
        }
        #endregion

        #region 键盘入事件
        /// <summary>
        /// 键盘键入事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void VideoTestManager_KeyDown(object sender, KeyEventArgs e)
        {
            // Check if the pressed key is a number key (both top row and numpad)
            if ((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) || (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9))
            {
                // Get the digit from the key code
                int digit = (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) ? e.KeyCode - Keys.D0 : e.KeyCode - Keys.NumPad0;

                // Handle the digit input, for example:
                this.input_number = digit;
            }
        }
        #endregion
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using Models;

namespace Tools
{
    public class DisplayManager
    {
        public List<DisplayEntity> displayEntity; // 显示实体

        [DllImport("user32.dll")]
        private static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);

        [StructLayout(LayoutKind.Sequential)]
        private struct DISPLAY_DEVICE
        {
            public int cb;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string DeviceName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            public string DeviceString;
            public int StateFlags;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            public string DeviceID;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            public string DeviceKey;
        }

        /// <summary>
        /// 检测接入的显示接口
        /// </summary>
        public void DetectDisplays()
        {

            displayEntity = new List<DisplayEntity>();

            // 使用WMI查询显示器连接类型
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\wmi", "SELECT * FROM WmiMonitorConnectionParams");
            foreach (ManagementObject queryObj in searcher.Get())
            {
                uint videoOutputTechnology = (uint)queryObj["VideoOutputTechnology"];
                string connectionType = GetConnectionType(videoOutputTechnology);

                displayEntity.Add(new DisplayEntity
                {
                    DeviceIndex = displayEntity.Count,
                    DeviceName = queryObj["InstanceName"]?.ToString(),
                    //DeviceString = DeviceString = d.DeviceString,
                    ProtName = connectionType
                });
            }

            DeviceString();
        }

        /// <summary>
        /// 检测接入的显示接口
        /// </summary>
        public void DeviceString()
        {
            DISPLAY_DEVICE d = new DISPLAY_DEVICE();
            d.cb = Marshal.SizeOf(d);

            int deviceIndex = 0;
            //this.displayEntity = new List<DisplayEntity>();

            while (EnumDisplayDevices(null, (uint)deviceIndex, ref d, 0))
            {

                if (deviceIndex < displayEntity.Count)
                {
                    displayEntity[deviceIndex].DeviceString = d.DeviceString;
                    displayEntity[deviceIndex].DeviceName = d.DeviceName;
                }
                //Console.WriteLine($"Device {deviceIndex}: {d.DeviceName} - {d.DeviceString}");
                //this.displayEntity.Add(new DisplayEntity()
                //{
                //    DeviceIndex = deviceIndex,
                //    DeviceName = d.DeviceName,
                //    DeviceString = d.DeviceString
                //});
                deviceIndex++;
            }
        }

        /// <summary>
        /// 获取连接的显示类型
        /// </summary>
        /// <param name="videoOutputTechnology"></param>
        /// <returns></returns>
        private string GetConnectionType(uint videoOutputTechnology)
        {
            // 根据WMI查询结果中的VideoOutputTechnology值返回连接类型
            switch (videoOutputTechnology)
            {
                case 0x00000000: return "HD15 (VGA)";
                case 0x00000001: return "S-Video";
                case 0x00000002: return "Composite video";
                case 0x00000003: return "Component video (YPbPr)";
                case 0x00000004: return "DVI";
                case 0x00000005: return "HDMI";
                case 0x00000006: return "LVDS";
                case 0x00000007: return "DJPN";
                case 0x00000008: return "SDI";
                case 0x00000009: return "DP";
                //case 0x00000009: return "DisplayPort external";
                //case 0x0000000A: return "DisplayPort embedded";
                case 0x0000000A: return "VGA";
                case 0x0000000B: return "UDI external";
                case 0x0000000C: return "UDI embedded";
                case 0x0000000D: return "SDTVDongle";
                case 0x80000000: return "Miracast";
                case 0x80000001: return "Indirect Display";
                default: return "Unknown";
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;

namespace Models
{
    public class DisplayEntity
    {
        /// <summary>
        /// 硬件指针
        /// </summary>
        public int DeviceIndex { get; set; }

        /// <summary>
        /// 硬件名称
        /// </summary>
        public string DeviceName { get; set; }

        /// <summary>
        /// 硬件字符串
        /// </summary>
        public string DeviceString { get; set; }

        /// <summary>
        /// 接口名称
        /// </summary>
        public string ProtName { get; set; }


        /// <summary>
        /// 切换的显示模式
        /// </summary>
        public DisplayMode SwDisplayMode { get; set; } = DisplayMode.Internal;


        /// <summary>
        /// 测试结果
        /// </summary>
        public string TestResult { get; set; } = "Wait";
    }

    public enum DisplayMode
    {
        Internal,//仅电脑屏幕
        Clone,//复制
        Extend,//扩展
        External//仅第二屏幕
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/793013.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

短视频矩阵:批量发布的秘密揭秘

在数字化时代&#xff0c;短视频已经成为一种广受欢迎的媒体形式。无论是用于品牌推广、产品营销还是个人创作&#xff0c;短视频都提供了一种直观、生动的方式来吸引观众的注意力。然而&#xff0c;有效地制作、管理和发布短视频对于许多创作者和企业来说是一个挑战。 为此&am…

C++ 现代教程三

// 模板参数类型区分 template <class T> static std::string cppdemangle() {std::string s{cppdemangle(typeid(std::remove_cv_t<std::remove_reference_t<T>>))};if (std::is_const_v<std::remove_reference_t<T>>)s " const";if…

Linux 入门教程 by 程序员鱼皮

本文作者&#xff1a;程序员鱼皮 免费编程学习 - 编程导航网&#xff1a;https://www.code-nav.cn 大家好&#xff0c;我是鱼皮。 前两天我学编程的老弟小阿巴过生日&#xff0c;我问他想要什么礼物。 本来以为他会要什么游戏机、Q 币卡、鼠标键盘啥的&#xff0c;结果小阿巴…

【car】深入浅出学习机械燃油车知识、结构、原理、维修、保养、改装、编程

汽车的五大总成通常是指发动机、变速器、前后桥、车架和悬挂系统。 发动机&#xff1a;是汽车的动力来源&#xff0c;负责将燃料的化学能转化为机械能&#xff0c;驱动汽车行驶。常见的发动机类型有内燃机&#xff08;如汽油发动机、柴油发动机&#xff09;和电动机&#xff0…

网络安全应急响应信息收集利器-Eagle_Eye

项目介绍: 网络安全应急响应信息收集利器 - Eagle_Eye&#xff1a;您的终端信息自动收集专家 在网络安全的紧急时刻&#xff0c;每一秒都至关重要。Eagle_Eye&#xff0c;这款专为应急响应设计的工具&#xff0c;如同一位随时待命的侦察兵&#xff0c;能够在危机时刻迅速收集…

virturalBox+K8S部署jaeger-all-in-one

pod的yaml如下&#xff1a;这里使用的是主机host模式 apiVersion: apps/v1 kind: Deployment metadata:name: jaegerlabels:app: jaeger spec:replicas: 1selector:matchLabels:app: jaegertemplate:metadata:labels:app: jaegerspec:hostNetwork: truecontainers:- name: jae…

[激光原理与应用-109]:南京科耐激光-激光焊接-焊中检测-智能制程监测系统IPM介绍 - 12 - 焊接工艺之影响焊接效果的因素

目录 一、影响激光焊接效果的因素 1.1、光束特征 1.2、焊接特征 1.3、保护气体 二、材料对焊接的影响 2.1 材料特征 2.2 不同材料对激光的吸收率 &#xff08;一&#xff09;、不同金属材料对不同激光的吸收率 1. 金属材料对激光的普遍反应 2. 不同波长激光的吸收率差…

2024年新一代WebOffice内嵌网页组件——猿大师办公助手

背景 WebOffice控件这个中间件软件产品已存在二十余年&#xff0c;在国内众多大中小型企业、各级政府机关、科研机构和学校等事业单位的OA、ERP、文档系统、云盘等信息化B/S系统中得到了大量使用&#xff0c;为我国的信息化事业也做出了不小贡献。随着操作系统、浏览器及Offic…

05:定时器中断

中断 1、定时器T0中断2、案例&#xff1a;通过定时器T0中断来实现灯间隔1s亮灭 1、当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求&#xff0c;要求CPU暂停当前的工作&#xff0c;转而去处理这个紧急事件&#xff0c;处理完以后&#xff0c;再回到原来被中断的地方…

【数据分享】2021-2100年中国1km分辨率多情景多模式逐月降水量数据集

今天我们给大家分享一份根据IPCC耦合模式比较计划第六阶段&#xff08;CMIP6&#xff09;发布的全球>100 km气候模式数据集以及WorldClim发布的全球高分辨率气候数据集&#xff0c;通过空间降尺度方法得到的2021-2100年中国1km分辨率多情景多模式逐月降水量数据集。 数据来…

vue2学习笔记-官网使用指南和搭建开发环境

官网使用指南 官网地址&#xff1a;介绍 — Vue.js 1、学习 1.1 教程和API 最重要的两个板块。API是VUE的字典&#xff0c;需要时来查阅。 1.2、风格指南 如何写出风格优雅的VUE代码。规则分为四类&#xff1a;必要的&#xff0c;强烈推荐、推荐、谨慎使用。 1.3、示例 …

java的遍历的方法对比 效率对比

在 Java 中&#xff0c;遍历对象的方式主要取决于对象的类型和数据结构。以下是几种常见的遍历方式&#xff0c;以及它们的效率比较&#xff1a; 普通的 for 循环&#xff1a; 效率&#xff1a;高。使用普通的 for 循环可以直接根据索引来访问元素&#xff0c;适用于数组和实现…

js vue table单元格合并

实现效果 关键代码 <table classtable table-bordered><thead><tr><th>检测项目</th><th>详细说明</th><th>检测结果</th><th>检测说明</th></tr></thead><tbody><tr ng-repeatrow in…

ant design pro多页签功能

效果&#xff1a; 原理&#xff1a; 1、所有需要页签页面&#xff0c;都需要一个共同父组件 2、如何缓存&#xff0c;用的是ant的Tabs组件&#xff0c;在共同父组件中&#xff0c;实际是展示的Tabs组件 3、右键&#xff0c;用的是ant的Dropdown组件&#xff0c;当点击时&…

基于红黑树对map和set的封装

前言 前面我们已经对红黑树做了介绍和实现&#xff0c;本期我们来对红黑树进一步改造&#xff0c;然后基于改造后的红黑树封装出map和set&#xff01; 本期内容介绍 • 红黑树的改造 • 红黑树的迭代器实现 • map的封装 • set的封装 • 全部源码 ● 红黑树的改造 我们目前…

【JavaEE】网络编程——UDP

&#x1f921;&#x1f921;&#x1f921;个人主页&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;JavaEE专栏&#x1f921;&#x1f921;&#x1f921; 文章目录 1.数据报套接字(UDP)1.1特点1.2编码1.2.1DatagramSocket1.2.2DatagramPacket…

汽车预约维修小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;技师管理&#xff0c;技师信息管理&#xff0c;用户预约管理&#xff0c;取消预约管理&#xff0c;订单信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;技师信息&a…

接上一回C++:补继承漏洞+多态原理(带图详解)

引子&#xff1a;接上一回我们讲了继承的分类与六大默认函数&#xff0c;其实继承中的菱形继承是有一个大坑的&#xff0c;我们也要进入多态的学习了。 注意&#xff1a;我学会了&#xff0c;但是讲述上可能有一些不足&#xff0c;希望大家多多包涵 继承复习&#xff1a; 1&…

并查集+链表,CF 1131F - Asya And Kittens

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1131F - Asya And Kittens 二、解题报告 1、思路分析 本质是拼积木游戏 初始有n块积木&#xff0c;每次两块首尾拼成一块就行&#xff0c;拼接n - 1 次最后会得到一个大积木&#xff0c;我们从左往右输出组…

Nuxt3封装网络请求 useFetch $fetch

前言&#xff1a; 刚接触、搭建Nuxt3项目的过程还是有点懵的&#xff0c;有种摸石头过河的感觉&#xff0c;对于网络请求这块&#xff0c;与之前的Vue3项目有所区别&#xff0c;在Vue项目通常使用axios这个库进行网络请求&#xff0c;但在Nuxt项目并不推荐&#xff0c;因为有内…