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

news2024/9/18 23:10:33

代码如下:

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.coloradmin.cn/o/1919056.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ThreadLocal与ThreadLocalMap

参考&#xff1a;理清ThreadLocal、ThreadLocalMap、Thread之间的关系 - 翎野君 - 博客园 (cnblogs.com) ThreadLocalMap 是 ThreadLocal 类中的一个静态内部类&#xff0c;但它存在于每个线程的 Thread 对象内部&#xff0c;而不是 ThreadLocal 实例本身。 ThreadLocal 类&am…

怎么压缩视频?推荐7款必备视频压缩软件免费版(强烈建议收藏)

如今&#xff0c;视频内容日益丰富&#xff0c;并占据了许多人的日常娱乐和工作生活。然而&#xff0c;随着高清和超高清视频的普及&#xff0c;视频文件的体积也越来越大&#xff0c;给存储和传输带来了挑战。因此&#xff0c;学会如何压缩视频文件成为了许多人的需求之一。本…

Spring Web MVC入门(1)(建立连接)

一.什么是Spring Web MVC? Spring Web MVC是基于ServletAPI构建的原始Web框架,从一开始就包含在Spring框架中.它的正式名称"Spring Web MVC"来自其源模块的名称(Spring-webmvc),但它通常被称为"Spring MVC". 二.MVC的定义 MVC是Model View Controller的缩…

[终端安全]-7 后量子密码算法

本文参考资料来源&#xff1a;NSA Releases Future Quantum-Resistant (QR) Algorithm Requirements for National Security Systems > National Security Agency/Central Security Service > Article Commercial National Security Algorithm Suite 2.0” (CNSA 2.0) C…

高性价比之战,希喂、霍尼韦尔、安德迈宠物空气净化器真实PK

在拥有孕妇与小孩的家庭中饲养宠物&#xff0c;营造一个既温馨又健康的居家环境显得尤为重要。尽管日常的打扫与清洁工作已做得相当到位&#xff0c;但空气中仍难免悬浮着细微的宠物浮毛与不易察觉的异味&#xff0c;这些长期累积下来&#xff0c;极易成为细菌滋生的温床&#…

双一流高校某教学系统存在多个高危漏洞

脆弱资产搜集 信息搜集过程中&#xff0c;除了用常见子域名扫一遍&#xff0c;还可以通过空间搜索引擎手动搜索。我用的就是把学校名称或者缩写作为关键字&#xff0c;利用语法: web.body“关键字”&&web.body“系统” web.body“关键字”&&web.body“登录”…

05:定时器中断

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

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

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

小程序项目记录

写小程序遇到的问题&#xff1a; 1、如何发行小程序 第一步点击“发行” 然后选择“小程序-微信(仅适用于uni-app)” 然后会弹出一个这样的框 微信小程序名称和AppId会自动带入 然后控制台会出现这些信息 注意&#xff1a;生成的这个路径build为线上环境部署所使用路径&…

Hydra-MDP: 端到端多模态规划与多目标 Hydra 蒸馏

Hydra-MDP: End-to-end Multimodal Planning with Multi-target Hydra-Distillation Hydra-MDP: 端到端多模态规划与多目标 Hydra 蒸馏 Abstract We propose Hydra-MDP, a novel paradigm employing multiple teachers in a teacher-student model. This approach uses know…

音质强者悠律Ringbuds pro,时尚与音质并存

首次将手机使用的“素皮”材料用在充电仓的设计上&#xff0c;不仅手感好&#xff0c;质感直接拉满&#xff0c;而这样的工业设计不仅获得了很多消费者的喜爱&#xff0c;同时也荣获了世界知名的红点设计大奖&#xff0c;此奖项并一直被冠以“国际工业设计的奥斯卡”之称。可见…

Android 使用 Debug.startMethodTracing 分析方法耗时

参考 Generate Trace Logs by Instrumenting Your App 官网提供了 trace 工具来分析方法耗时。 生成 trace 文件 package com.test.luodemo.trace;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.os.Debug; import android.uti…

从点击到转化,Xinstall解析移动广告全链路数据,优化ROI的秘密

在疫情的持续影响下&#xff0c;全球营销环境正经历着前所未有的变革。品牌广告主们面对挑战&#xff0c;展现出前所未有的积极与韧性。移动端广告投放的持续增长&#xff0c;尤其是短视频和图文广告的兴起&#xff0c;为品牌带来了新的机遇。然而&#xff0c;如何在激烈的市场…

Dify 与 Xinference 最佳组合 GPU 环境部署全流程

背景介绍 在前一篇文章 RAG 项目对比 之后&#xff0c;确定 Dify 目前最合适的 RAG 框架。本次就尝试在本地 GPU 设备上部署 Dify 服务。 Dify 是将模型的加载独立出去的&#xff0c;因此需要选择合适的模型加载框架。调研一番之后选择了 Xinference&#xff0c;理由如下&…

【PostgreSQL】Spring boot + Mybatis-plus + PostgreSQL 处理json类型情况

Spring boot Mybatis-plus PostgreSQL 处理json类型情况 一、前言二、技术栈三、背景分析四、方案分析4.1 在PostgreSQL 数据库中直接存储 json 对象4.2 在PostgreSQL 数据库中存储 json 字符串 五、自定义类型处理器5.1 定义类型处理器5.2 使用自定义类型处理器 一、前言 在…

微信闪退怎么回事?实用技巧助你轻松应对

在使用微信的过程中&#xff0c;偶尔会遇到闪退的问题&#xff0c;这不仅影响我们的日常沟通&#xff0c;还可能导致重要信息的丢失。那么&#xff0c;微信闪退怎么回事呢&#xff1f;闪退的原因可能有很多&#xff0c;包括软件问题、手机存储不足、系统不兼容等。本文将详细分…

好用的IP反查接口(2)

IP-地理信息查询接口-本地化 参考&#xff1a; 通过Ip查询对应地址,Ip2location全球IP地址网段-CSDN博客 因为在线接口有限制&#xff08;毕竟别人提供服务&#xff0c;服务器&#xff0c;数据维护&#xff0c;域名啥的都要费用&#xff09;&#xff0c; 所以本地化服务的需…

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

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

C嘎嘎类与对象上篇

类的定义 1. class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后⾯分号不能省略 。类体中内容称为类的成员&#xff1a;类中的变量称为类的属性或成员变量; 类中的函数称为类的⽅法或者成员函数。 2. C中struct也可以…

C++入门基础题:数组元素逆序(C++版互换方式)

1.题目&#xff1a; 数组元素逆置案例描述: 请声明一个5个元素的数组&#xff0c;并且将元素逆置. (如原数组元素为:1,3,2,5,4;逆置后输出结果为:4,5,2,3,1) 2.图解思路&#xff1a; 3.代码演示&#xff1a; #include<iostream>using namespace std;int main(){int a…