鼠标连点工具:

工具编写背景:

因在游戏公司工作,游戏运行测试,偶尔需要测试升级或其他操作需要鼠标持续点击,网上下载的连点器广告太多,所以想自己编写了一款鼠标连点工具。

工具需求:

通过命令或操作,使鼠标特定按键 持续、有规律的点击屏幕指定位置。

实现原理:

热键相关:

使用Hook(钩子),监听键盘按下事件。

根据按键获取到按下按键的键值(Keys)。

判断该键值是否为命令热键(快捷键),(是否为 开始 | 结束)。

如果是开始,则判断当前工具的状态是否为已开始,如果是,则不执行,否则执行开启连点器功能。

如果是结束,则判断当前工具的状态是否为已开始,如果是,则执行结束命令,否则不执行。

判断该键值是否为紧急结束功能快捷键(ESC键)

为了防止误触,判定需要连续按键4次以上,且每次按键间隔不超过1.5秒。则为有效执行。否则视为无效操作。

鼠标点击相关:

调用了Windows自带的Dll动态连接库 user32.dll  操作鼠标左键的按下、左键抬起,右键按下、右键抬起、移动鼠标等。

使用Timer控件,实现了定时执行点击命令。

其他相关:

使用 Configuration 保存工具配置信息。

具体代码:

钩子相关:

KeyboardHookLib.cs类


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Win32;
using System.Windows.Forms;
namespace MouseClicker
{public class KeyboardHookLib{private const int WH_KEYBOARD_LL = 13; //键盘 //键盘处理事件委托 ,当捕获键盘输入时调用定义该委托的方法. private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);//客户端键盘处理事件 public delegate void ProcessKeyHandle(HookStruct param, out bool handle);//接收SetWindowsHookEx返回值 private static int _hHookValue = 0;//勾子程序处理事件 private HookHandle _KeyBoardHookProcedure;//Hook结构 [StructLayout(LayoutKind.Sequential)]public class HookStruct{public int vkCode;public int scanCode;public int flags;public int time;public int dwExtraInfo;}//设置钩子 [DllImport("user32.dll")]private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);//取消钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]private static extern bool UnhookWindowsHookEx(int idHook);//调用下一个钩子 [DllImport("user32.dll")]private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);//获取当前线程ID [DllImport("kernel32.dll")]private static extern int GetCurrentThreadId();//Gets the main module for the associated process. [DllImport("kernel32.dll")]private static extern IntPtr GetModuleHandle(string name);private IntPtr _hookWindowPtr = IntPtr.Zero;//构造器 public KeyboardHookLib() { }//外部调用的键盘处理事件 private static ProcessKeyHandle _clientMethod = null;/// <summary> /// 安装勾子 /// </summary> /// <param name="hookProcess">外部调用的键盘处理事件</param> public void InstallHook(ProcessKeyHandle clientMethod){_clientMethod = clientMethod;// 安装键盘钩子 if (_hHookValue == 0){_KeyBoardHookProcedure = new HookHandle(OnHookProc);_hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);_hHookValue = SetWindowsHookEx(WH_KEYBOARD_LL,_KeyBoardHookProcedure,_hookWindowPtr,0);//如果设置钩子失败. if (_hHookValue == 0) UninstallHook();}}//取消钩子事件 public void UninstallHook(){if (_hHookValue != 0){bool ret = UnhookWindowsHookEx(_hHookValue);if (ret) _hHookValue = 0;}}//钩子事件内部调用,调用_clientMethod方法转发到客户端应用。 private static int OnHookProc(int nCode, int wParam, IntPtr lParam){if (nCode >= 0){//转换结构 HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));// hookStruct.vkCode = 0;if (_clientMethod != null){bool handle = false;//调用客户提供的事件处理程序。 _clientMethod(hookStruct, out handle);if (handle) return 1; //1:表示拦截键盘,return 退出 }}return CallNextHookEx(_hHookValue, nCode, wParam, lParam);}}
}

鼠标操作 + 逻辑处理

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace MouseClicker
{public partial class frmMain : Form{public frmMain(){InitializeComponent();}Timer timer = new Timer();private bool updateLock = false;//紧急按钮功能private int exigencyButtonClick = 0;private long exigencyLastDownTime = 0;private int exigencyHoldTime = 1500;//紧急事件处理等待时长 两次紧急处理时间间隔不得大于 超过则无效 private bool runsLock = false;private bool ResetFlag = false;private KeyboardHookLib _keyboardHook = null;private List<Keys> keyFilter = null;private EnumKeyType KeyType = EnumKeyType.none;private Keys updateKey = Keys.None;private delegate void Operate(EnumKeyType enumKey,Keys keyIndex);//    private List<Operate> OperateList = new List<Operate>();//  [System.Runtime.InteropServices.DllImport("user32")][DllImport("user32.dll")]private static extern int mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);[DllImport("user32.dll")]private static extern int SetCursorPos(int x, int y);/// <summary>/// 移动鼠标到指定的坐标点/// </summary>//移动鼠标 const int MOUSEEVENTF_MOVE = 0x0001;//模拟鼠标左键按下 const int MOUSEEVENTF_LEFTDOWN = 0x0002;//模拟鼠标左键抬起 const int MOUSEEVENTF_LEFTUP = 0x0004;//模拟鼠标右键按下 const int MOUSEEVENTF_RIGHTDOWN = 0x0008;//模拟鼠标右键抬起 const int MOUSEEVENTF_RIGHTUP = 0x0010;//模拟鼠标中键按下 const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;//模拟鼠标中键抬起 const int MOUSEEVENTF_MIDDLEUP = 0x0040;//标示是否采用绝对坐标 const int MOUSEEVENTF_ABSOLUTE = 0x8000;//模拟鼠标滚轮滚动操作,必须配合dwData参数const int MOUSEEVENTF_WHEEL = 0x0800;int screenHeight = Screen.PrimaryScreen.Bounds.Height;int screenWidth = Screen.PrimaryScreen.Bounds.Width;public void MoveMouseToPoint(Point p){SetCursorPos(p.X, p.Y);}/// <summary>/// 设置鼠标的移动范围/// </summary>public void SetMouseRectangle(Rectangle rectangle){System.Windows.Forms.Cursor.Clip = rectangle;}/// <summary>/// 设置鼠标位于屏幕中心/// </summary>public void SetMouseAtCenterScreen(){int winHeight = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;int winWidth = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;Point centerP = new Point(winWidth / 2, winHeight / 2);MoveMouseToPoint(centerP);}[Obsolete]private void Form1_Load(object sender, EventArgs e){lbl_screen_whVal.Text = string.Format("{0} * {1}",screenWidth,screenHeight);getMousePoint();//开启钩子_keyboardHook = new KeyboardHookLib();_keyboardHook.InstallHook(this.OnKeyPress);Console.WriteLine("钩子已开启..");LoadHotKey();}[Obsolete]private void LoadHotKey() {string StartHotKey = ConfigurationSettings.AppSettings["StartHotKey"].ToString();string EndHotKey = ConfigurationSettings.AppSettings["EndHotKey"].ToString();keyFilter = new List<Keys>();Keys keys = Keys.None;Enum.TryParse<Keys>(StartHotKey, true, out keys);keyFilter.Add(keys);if (string.IsNullOrEmpty(StartHotKey) || keys == Keys.None){lbl_start_hot_key.Text = "未设置";keyFilter.Remove(keys);}else{lbl_start_hot_key.Text = Enum.GetName(typeof(Keys),keys);}Enum.TryParse<Keys>(EndHotKey, true, out keys);keyFilter.Add(keys);if (string.IsNullOrEmpty(EndHotKey) || keys == Keys.None){lbl_end_hot_key.Text = "未设置";keyFilter.Remove(keys);}else{lbl_end_hot_key.Text = Enum.GetName(typeof(Keys), keys);}if (keyFilter.Contains(Keys.None)){keyFilter.Remove(Keys.None);}}private void SaveHotKey(EnumKeyType keyType,Keys key) {//获取Configuration对象Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);//写入元素的Valueint val = (int)key;string startKey = config.AppSettings.Settings["StartHotKey"].Value;string endKey = config.AppSettings.Settings["EndHotKey"].Value;if (KeyType == EnumKeyType.start){if (startKey.Equals(val.ToString())){return;} else if (endKey.Equals(val.ToString())){config.AppSettings.Settings["EndHotKey"].Value ="";}config.AppSettings.Settings["StartHotKey"].Value = val.ToString();}else if (KeyType == EnumKeyType.end){if (endKey.Equals(val.ToString())){return;}else if (startKey.Equals(val.ToString())){config.AppSettings.Settings["StartHotKey"].Value = "";}config.AppSettings.Settings["EndHotKey"].Value = val.ToString();}//一定要记得保存,写不带参数的config.Save()也可以config.Save(ConfigurationSaveMode.Modified);//刷新,否则程序读取的还是之前的值(可能已装入内存)System.Configuration.ConfigurationManager.RefreshSection("appSettings");}private Point getMousePoint() {Point point = Control.MousePosition;lbl_mouse_point.Text = string.Format("({0},{1})",point.X,point.Y);if (updateLock == false) {txt_mouse_x_point.Text = point.X.ToString();txt_mouse_y_point.Text = point.Y.ToString();}return point;}public void OnKeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle){handle = false;Keys key = (Keys)hookStruct.vkCode;//处理紧急结束按键if (key == Keys.Escape) {long nowTime = DateUtil.DateTimeToLongTimeStamp(DateTime.Now);exigencyButtonClick++;if ((exigencyLastDownTime + exigencyHoldTime) <= nowTime) {// 紧急处理时长 过长  清空本次紧急处理的记录exigencyButtonClick = 0;exigencyLastDownTime = 0;}exigencyLastDownTime = nowTime;if (exigencyButtonClick >= 6) {exigencyButtonClick = 0;if (isRun()) {stopRun();DialogResult result = MessageBox.Show("是否关闭连点器?", "提示", MessageBoxButtons.YesNo);if (result == DialogResult.Yes){Application.Exit();}}else{Application.Exit();}}}if (KeyType!= EnumKeyType.none) {Operate operate = new Operate(resetHotKey);operate(EnumKeyType.none, key);return;}string StartHotKey = ConfigurationSettings.AppSettings["StartHotKey"].ToString();string EndHotKey = ConfigurationSettings.AppSettings["EndHotKey"].ToString();int startKey = 0;int endKey = 0;if (IsNumber(StartHotKey)) {startKey = Convert.ToInt32(StartHotKey);}if (IsNumber(EndHotKey)){endKey = Convert.ToInt32(EndHotKey);}if (key == (Keys)startKey){if (isRun() == false) {Run();}}else if (key == (Keys)endKey) {if (isRun()){stopRun();}}}private bool isRun(){return runsLock;}private void stopRun() {Button button = GetControlOfName("btn_run", this.Controls) as Button;if (button != null){button.Text = "运行";}this.WindowState = FormWindowState.Normal; // 最小化runsLock = false;timer_clicker.Enabled = false;timer_clicker.Stop();}private void Run() {Button button = GetControlOfName("btn_run", this.Controls) as Button;if (button != null) {button.Text = "停止";}this.WindowState = FormWindowState.Minimized; // 最小化runsLock = true;timer_clicker.Enabled = true;timer_clicker.Start();}private void Form1_MouseMove(object sender, MouseEventArgs e){}private void timer_mouse_Tick(object sender, EventArgs e){getMousePoint();}private void cbx_unLock_CheckedChanged(object sender, EventArgs e){updateLock = cbx_unLock.Checked;}private void txt_mouse_x_point_TextChanged(object sender, EventArgs e){MouseChangePoint(txt_mouse_x_point.Text, txt_mouse_y_point.Text);}private void MouseChangePoint(string pointX,string pointY) {string xpoint = pointX;string ypoint = pointY;if (updateLock == false)return;if (IsNumber(xpoint) == false && IsNumber(ypoint) == false)return;int x = 0;int y = 0;if (IsNumber(xpoint)){x = Convert.ToInt32(xpoint);}if (IsNumber(ypoint)){y = Convert.ToInt32(ypoint);}Point point = new Point(x,y);// clearMousePoint();// mouse_event(MOUSEEVENTF_MOVE, x, y, 0, 0);SetMouseAtCenterScreen();//将鼠标置于屏幕中心MoveMouseToPoint(point);}private bool IsNumber(string text){if (string.IsNullOrEmpty(text))return false;try{Convert.ToInt32(text);return true;}catch (Exception){return false;}}private void Form1_KeyPress(object sender, KeyPressEventArgs e){/* if (e.KeyChar == 27){Application.Exit();}*/}private void txt_mouse_y_point_TextChanged(object sender, EventArgs e){MouseChangePoint(txt_mouse_x_point.Text, txt_mouse_y_point.Text);}private void Form1_FormClosed(object sender, FormClosedEventArgs e){UnInstallHook();}private void Form1_FormClosing(object sender, FormClosingEventArgs e){UnInstallHook();}private void UnInstallHook() {//移除钩子if (_keyboardHook != null){_keyboardHook.UninstallHook();Console.WriteLine("钩子移除成功..");}}private void btn_reset_start_Click(object sender, EventArgs e){if (isSave()) {saveHotKey();return;}if (updateState() == false)return;resetHotKey(EnumKeyType.start);}private bool isSave(){return KeyType != EnumKeyType.none && updateKey != Keys.None;}private void btn_reset_end_Click(object sender, EventArgs e){if (isSave()){saveHotKey();return;}if (updateState() == false)return;resetHotKey(EnumKeyType.end);}private void saveHotKey() {if (KeyType != EnumKeyType.none && updateKey != Keys.None) {//SaveHotKey(KeyType,updateKey);resetState(KeyType);LoadHotKey();}}private Control GetControlOfName(string controlName, Control.ControlCollection containChildControlWindow){if (string.IsNullOrEmpty(controlName)) return null;foreach (Control item in containChildControlWindow){if (item.Name.Equals(controlName)){return item;}}return null;}private bool updateState() {if (ResetFlag)return !ResetFlag;ResetFlag = !ResetFlag;return ResetFlag;}private void resetState(EnumKeyType type) {ResetFlag = false;KeyType = EnumKeyType.none;updateKey = Keys.None;Button button = GetControlOfName(string.Format("{0}", type == EnumKeyType.start ? "btn_reset_start" : "btn_reset_end"), this.Controls) as Button;if (button == null)return;button.Text = "重置";}private void resetHotKey(EnumKeyType type,Keys keys = Keys.None){if (type != EnumKeyType.none) {DialogResult result = MessageBox.Show(string.Format("是否重置{0}连点器按键?", type == EnumKeyType.start ? "开启" : "结束"), "提示", MessageBoxButtons.YesNo);if (result == DialogResult.Yes){Button button = GetControlOfName(string.Format("{0}",type == EnumKeyType.start ? "btn_reset_start" : "btn_reset_end"), this.Controls) as Button;if (button == null){return;}Label label = GetControlOfName(string.Format("{0}", type == EnumKeyType.start ? "lbl_start_hot_key" : "lbl_end_hot_key"), this.Controls) as Label;if (label == null){return;}label.Text = "未设置";button.Text = "保存";KeyType = type;}else{resetState(type);}}else{if (KeyType != EnumKeyType.none) {updateKey = keys;Label label = GetControlOfName(string.Format("{0}", KeyType == EnumKeyType.start ? "lbl_start_hot_key" : "lbl_end_hot_key"), this.Controls) as Label;if (label == null){return;}label.Text = Enum.GetName(typeof(Keys),keys);}else{resetState(KeyType);}}}private void nud_speed_check_ValueChanged(object sender, EventArgs e){updateTick();}private void updateTick() {if (isRun()){stopRun();//暂停一下if (nud_speed_check.Value <= 0 || nud_speed_check.Value >= 9999999){nud_speed_check.Value = 10000;}timer_clicker.Interval = (int)nud_speed_check.Value;Run();//继续}else{if (nud_speed_check.Value <= 0 || nud_speed_check.Value >= 9999999){nud_speed_check.Value = 10000;}timer_clicker.Interval = (int)nud_speed_check.Value;}}public int number = 0;private void timer_clicker_Tick(object sender, EventArgs e){if (rdb_left.Checked){mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, Convert.ToInt32(txt_mouse_x_point.Text), Convert.ToInt32(txt_mouse_y_point.Text), 0, 0);}else{mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, Convert.ToInt32(txt_mouse_x_point.Text), Convert.ToInt32(txt_mouse_y_point.Text), 0, 0);}//Console.WriteLine($"开始点击屏幕{number++}!!!!");}private void nud_speed_check_FontChanged(object sender, EventArgs e){}private void nud_speed_check_KeyPress(object sender, KeyPressEventArgs e){updateTick();}private void btn_run_Click(object sender, EventArgs e){if (isRun() == false) {Run();}else{stopRun();}}private void rdb_right_CheckedChanged(object sender, EventArgs e){if (rdb_right.Checked) {rdb_left.Checked = false;}else{rdb_left.Checked = true;}}private void rdb_left_CheckedChanged(object sender, EventArgs e){if (rdb_left.Checked){rdb_right.Checked = false;}else{rdb_right.Checked = true;}}}public enum EnumKeyType {none,start,end,}}

时间操作工具类

DateUtil.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace MouseClicker
{public class DateUtil{/// <summary>/// 时间戳计时开始时间/// </summary>private static DateTime timeStampStartTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);/// <summary>/// DateTime转换为10位时间戳(单位:秒)/// </summary>/// <param name="dateTime"> DateTime</param>/// <returns>10位时间戳(单位:秒)</returns>public static long DateTimeToTimeStamp(DateTime dateTime){return (long)(dateTime.ToUniversalTime() - timeStampStartTime).TotalSeconds;}/// <summary>/// DateTime转换为13位时间戳(单位:毫秒)/// </summary>/// <param name="dateTime"> DateTime</param>/// <returns>13位时间戳(单位:毫秒)</returns>public static long DateTimeToLongTimeStamp(DateTime dateTime){return (long)(dateTime.ToUniversalTime() - timeStampStartTime).TotalMilliseconds;}/// <summary>/// 10位时间戳(单位:秒)转换为DateTime/// </summary>/// <param name="timeStamp">10位时间戳(单位:秒)</param>/// <returns>DateTime</returns>public static DateTime TimeStampToDateTime(long timeStamp){return timeStampStartTime.AddSeconds(timeStamp).ToLocalTime();}/// <summary>/// 13位时间戳(单位:毫秒)转换为DateTime/// </summary>/// <param name="longTimeStamp">13位时间戳(单位:毫秒)</param>/// <returns>DateTime</returns>public static DateTime LongTimeStampToDateTime(long longTimeStamp){return timeStampStartTime.AddMilliseconds(longTimeStamp).ToLocalTime();}}
}

配置文件:

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration><startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /></startup><appSettings><add key="StartHotKey" value="114"/><add key="EndHotKey" value="115"/></appSettings></configuration>

个人练习 —— 使用c#、Winform窗体 编写鼠标连点器(附代码和工具逻辑)相关推荐

  1. 用 Dev-C++ 编写鼠标连点器

    用 Dev-C++ 编写鼠标连点器 前言 代码 前言 B站视频讲解:[小工具]用 Dev-C++ 编写连点器(快捷键操作+窗口化) [小工具]用 Dev-C++ 编写连点器(快捷键操作+窗口化) 代码 ...

  2. Winform中实现自定义屏保效果(附代码下载)

    场景 效果 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 新建form ...

  3. 独家 | 教你用不到30行的Keras代码编写第一个神经网络(附代码教程)

    翻译:陈丹 校对:和中华 本文长度为3000字,建议阅读5分钟 本文为大家介绍了如何使用Keras来快速实现一个神经网络. 回忆起我第一次接触人工智能的时候,我清楚地记得有些概念看起来是多么令人畏惧. ...

  4. Winform中实现监控CPU内存使用率(附代码下载)

    场景 效果 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 新建一个窗体 ...

  5. Winform中实现文件批量更名器(附代码下载)

    场景 对一个文件夹中的文件进行某种格式的重命名 比如下面文件夹内的文件 程序运行效果 点击文件-打开,打开此文件夹后然后Ctrl+a全选此文件夹所有文件,点击打开 然后在序号设置中可以选择预设模板和起 ...

  6. java音频播放器代码_谁可以用Java编写音频或视频播放器的代码. 您可以运行实现....

    全部展开 你好房东,你可以试试这个 import javax.media.ControllerEvent; import javax.media.ControllerListener; import ...

  7. C# WinForm中 获得当前鼠标所在控件 或 将窗体中鼠标所在控件名显示在窗体标题上...

    转:/********************** * 课题:将窗体中鼠标所在控件名显示在窗体标题上  * 作者:ZAXX  * QQ : 94027486  * 本课题可简单扩展:获取屏幕上鼠标所在 ...

  8. C# Winform 窗体美化(五、鼠标穿透)

    五.鼠标穿透 以前在玩射击游戏的时候,狙击枪的设定一般是开镜才有准星,所以想是不是可以自己造一个默认准星出来,思路是现在窗口上画一个准星,然后把窗体其他区域都透明,然后设置鼠标穿透: 结果是: Upd ...

  9. 【C#】 WinForm窗体应用程序学习笔记 (一)

    WinForm窗体应用程序学习笔记(一) 由于控制台应用程序的运行结果都是通过控制台输出的,不能提供良好的用户体验,为此,C#提供了WinForm窗体应用程序.WinForm具有一系列丰富的控件,用于 ...

  10. 重绘Winform窗体

    本文转载自:http://www.cnblogs.com/encoding/p/5603080.html 按照惯例,先来几张样例图(注:为了展示窗口阴影效果,截图范围向外扩展了些,各位凭想象吧). 还 ...

最新文章

  1. 视频处理器为电池供电的设计提供4K视频编码
  2. shell eval命令
  3. Javascript、Jquery获取浏览器和屏幕各种高度宽度[mark]
  4. mysql 开户机构_mysql开户、权限设置、建库流程及常用操作
  5. 【Python教程】python函数后面有多个括号的作用
  6. 3.odoo13之跟着官网做项目/实例(模型关联,模型类模型表的关联)
  7. Android NFC开发
  8. java中identifiers什么意思_javassist.是什么意思
  9. perl 访问类方法的几种方式
  10. 好好学习 天天编程—C语言之我的第一个hello world(二)
  11. 在 GitHub 上提交代码必备指南!
  12. 人脸方向学习(四):人脸关键点检测+Mobilenet_v3结构探索
  13. 关于docker容器中,外网访问阿里云服务器中tomcat,报404错误的解决方法
  14. python编程知识大全_python编程入门之二:必备基础知识
  15. 【最终幻想15 国王之剑】制作介绍2:最大限度满足角色,背景和道具的要求
  16. css 文本超出就隐藏并且显示省略号
  17. Mac 如何升级 Ruby 版本
  18. 怎么弄gif图片html,怎么弄gif动态图
  19. 用osworkflow写一个请假例子
  20. H264学习二:H.264/AVC编码标准

热门文章

  1. 延安大学计算机学院评分,延安大学计算机学院.docx
  2. 倍福TwinCAT 3 气缸动作程序编写
  3. 向日葵服务器怎么修改密码,向日葵远程服务器ip
  4. python自动化办公---工资说明excel生成word再转换成pdf
  5. IMX6ULL开发板,系统移植——第一步Uboot移植
  6. Protues8.6仿真STM32出现错误-VDDA和VSSA的问题解决办法
  7. 炭足迹计算机的火车好处,碳足迹与碳足迹计算器.pdf
  8. centos 7.7.1908上隐藏顶栏和任务栏
  9. c语言的实验,c语言 实验1
  10. 彻底删除Daemon虚拟光驱工具残留的光驱盘符