百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

C#程序设计_鼠标和键盘

bigegpt 2024-08-14 14:44 2 浏览

一、获取鼠标的窗体/屏幕坐标

protected override void OnMouseMove(MouseEventArgs e)
{
    Point clientMouse = e.Location; //相对窗体坐标
    Point screenMouse = PointToScreen(clientMouse); //相对屏幕坐标
    this.Text = string.Format("鼠标窗体坐标:({0},{1}) 鼠标屏幕坐标:({2},{3})",
    clientMouse.X, clientMouse.Y, screenMouse.X, screenMouse.Y);
}

该实例重写了鼠标移动事件函数OnMouseMove,利用参数e获取窗体坐标,利用PointToScreen方法获取屏幕坐标。

二、鼠标长时间按下事件

public partial class Form1 : Form
{
    Timer timer = new Timer(); //创建实例
    int timeout = 0; //超时时间
    MouseEventArgs LongDown; //鼠标长时间按下事件参数
    public Form1()//窗体构造函数
    {
        InitializeComponent();
        timer.Interval = 1000; //定时器间隔,单位毫秒
        timer.Tick += new EventHandler(timer_Tick); //注册timer_Tick事件
    }
    void timer_Tick(object sender, EventArgs e)//每个间隔执行一次
    {
        if (++timeout == 2) OnMouseLongDown(this.LongDown); 
        //鼠标按下2秒,调用长时间按下事件
    }
    protected override void OnMouseDown(MouseEventArgs e)
    {
        this.LongDown = e; //鼠标按下事件参数
        this.Cursor = Cursors.Hand; //鼠标按下为手型
        timeout = 0;  //超时时间清0
        timer.Start(); //计时器启动
    }
    protected override void OnMouseUp(MouseEventArgs e)
    {
        this.Cursor = Cursors.Arrow;//鼠标松开为箭头
        timer.Stop(); //计时器停止
    }
    protected virtual void OnMouseLongDown(MouseEventArgs e)
    {
        MessageBox.Show("鼠标被长时间按下!");
    }
}

鼠标按下,启动定时器;

鼠标抬起,停止定时器;

定时器计时后,每秒timeout加1,达到设定时间后触发函数OnMouseLongDown,弹窗。

三、根据区域设置鼠标类型

protected override void OnMouseMove(MouseEventArgs e)
{
      if (e.X < ClientSize.Width / 2)
          if (e.Y < ClientSize.Height / 2)
              this.Cursor = Cursors.Hand; //左上,鼠标为手形图标
          else
              this.Cursor = Cursors.Help; //左下,鼠标为帮助图标
      else
          if (e.Y < ClientSize.Height / 2)
              this.Cursor = Cursors.WaitCursor; //右上,鼠标为等待图标
          else
              this.Cursor = Cursors.Cross; //右下,鼠标为十字型图标
}

该实例通过修改窗体的Cursor对象实现鼠标样式的改变。

四、创建鼠标图标

protected override void OnLoad(EventArgs e)
{
    Bitmap icon = new Bitmap(100,100);//鼠标图标的大小
    Graphics G = Graphics.FromImage(icon); //创建新的绘图
    G.SmoothingMode = SmoothingMode.AntiAlias; //消除锯齿
    G.Clear(Color.Transparent); //图标背景设为透明
    G.FillPie(new SolidBrush(Color.FromArgb(255, Color.Red)) //绘制扇形作为鼠标指针
    , new Rectangle(0, 0, icon.Width, icon.Height), 30f, 30f);
    G.Dispose(); //释放绘图表面
    this.Cursor = new Cursor(icon.GetHicon()); //设置新的鼠标对象
    icon.Dispose();
}

该实例利用绘制图标自定义鼠标的图标:

1、创建了一个100x100位图对象;

2、在位图中绘制一个扇形形状作为鼠标指针;

3、通过GetHicon方法获取图标句柄,并创建Cursor对象。

五、限制鼠标活动范围

protected override void OnMouseDown(MouseEventArgs e)//鼠标按下
{
    this.Text = "鼠标按下,活动范围限制为窗体";
    Cursor.Clip = new Rectangle(this.Location, this.Size);
}
protected override void OnMouseUp(MouseEventArgs e)//鼠标抬起
{
    this.Text = "鼠标抬起,活动范围无限制";
    Rectangle clip = new Rectangle();
    foreach (var item in Screen.AllScreens) //遍历所有屏幕
        clip = Rectangle.Union(clip, item.Bounds);//包含所有屏幕的最小矩形
    Cursor.Clip = clip;
}

该实例通过调用Cursor类的Clip属性(Rectangle类型)来设置鼠标的活动区域。

六、隐藏和显示鼠标指针

protected override void OnMouseDown(MouseEventArgs e)
{
    this.Text = "鼠标按下:隐藏";
    Cursor.Hide(); //隐藏鼠标
}
protected override void OnMouseUp(MouseEventArgs e)
{
    this.Text = "鼠标抬起:显示";
    Cursor.Show(); //显示鼠标
}

该实例通过调用Cursor类的Hide和Show方法来实现鼠标的隐藏与显示。

七、利用鼠标进行书写

bool isMouseDown = false; //声明Bool变量:鼠标是否按下
Point pointMouse = new Point();//鼠标上一时刻的坐标
protected override void OnMouseDown(MouseEventArgs e)
{
    pointMouse = e.Location; //鼠标上一时刻坐标
    isMouseDown = true; //鼠标已经按下
}
protected override void OnMouseMove(MouseEventArgs e)
{
    if (isMouseDown)
    {
        using (Graphics G = this.CreateGraphics()) //获取窗体绘制表面
        {
            G.SmoothingMode = SmoothingMode.AntiAlias; //消除锯齿
            using (Pen pen = new Pen(Color.Red, 3f)) //创建宽度为3像素的黑色画笔
            {
                G.DrawLine(pen, pointMouse, e.Location); //绘制连接两个坐标的线段
                pointMouse = e.Location; //重新设置鼠标坐标
            }
        }
    }
}
protected override void OnMouseUp(MouseEventArgs e)
{
    isMouseDown = false; //鼠标未按下
}
private void button1_Click(object sender, EventArgs e)
{
    this.Invalidate();//清屏
}

该实例通过利用DrawLine方法绘制连续的线段实现书写。

鼠标按下,把实时坐标赋值给pointMouse;

鼠标按下并移动,绘制当前点与pointMouse之间的线段;

鼠标抬起,停止绘制。

八、按下组合键实现窗体全屏

protected override void OnKeyDown(KeyEventArgs e)
{
    if (e.KeyData == (Keys.Control | Keys.Enter)) //判断键盘按键类型
    {
        if (this.WindowState == FormWindowState.Maximized) //判断窗体是否最大化
        {
            this.WindowState = FormWindowState.Normal; //窗体还原
        }
        else if (this.WindowState == FormWindowState.Normal)//判断窗体是否默认大小
        {
            this.WindowState = FormWindowState.Maximized; //窗体最大化
        }
    }
}

该实例通过函数OnKeyDown的KeyEventArgs参数对象的KeyData属性来获取键盘按下的键。通过判断属性值是否为Ctrl+Enter组合键的值来决定是否将窗体最大化。

九、屏蔽Alt+F4组合键

protected override void OnKeyDown(KeyEventArgs e)
{
    if (e.KeyData == (Keys.Alt | Keys.F4))
    {
        MessageBox.Show("Alt+F4组合键已被屏蔽,无法关闭当前窗体!");
        e.Handled = true; //标记为已处理状态
    }
}

如果检测到Alt+F4组合键按下,则将参数对象KeyEventArgs的Handled属性设置为true,标记Alt+F4组合键消息已经被处理过。

十、使用Shift+方向键调整窗体大小

protected override void OnKeyDown(KeyEventArgs e)
{
    if (e.KeyData == (Keys.Shift | Keys.Left)) this.Width -= 10; //减小宽度
    if (e.KeyData == (Keys.Shift | Keys.Right)) this.Width += 10; //增加宽度
    if (e.KeyData == (Keys.Shift | Keys.Up)) this.Height -= 10; //减小高度
    if (e.KeyData == (Keys.Shift | Keys.Down)) this.Height += 10; //增加高度
    this.Text = "使用Shift+方向键调整窗体大小" + string.Format("({0},{1})", this.Width, this.Height);
}

十一、录制并回放鼠标移动轨迹

Queue<Point> mousePoints = new Queue<Point>(); //保存鼠标轨迹
bool isCtrlDown = false; //标记Ctrl键是否按下
protected override void OnKeyDown(KeyEventArgs e)
{
    if (e.KeyData == (Keys.LButton | Keys.ShiftKey | Keys.Control))
    {//判断Ctrl键按下
        isCtrlDown = true; //标记Ctrl键按下
        timer1.Start(); //启动计时器
    }
}
private void timer1_Tick(object sender, EventArgs e)
{
    if (isCtrlDown) mousePoints.Enqueue(Cursor.Position); //添加轨迹
    else if (mousePoints.Count > 0) //鼠标轨迹数大于0
    {
        Cursor.Position = mousePoints.Dequeue(); //从轨迹中取出一个点设置为鼠标当前值
        Graphics g = this.CreateGraphics(); //获取窗体绘图表面                           
        Cursor.Draw(g, new Rectangle(PointToClient(Cursor.Position), Cursor.Size)); //绘制鼠标图标
        g.Dispose();
    }
    else timer1.Stop(); //停止录像或回放
}
protected override void OnKeyUp(KeyEventArgs e)
{
    if (e.KeyData == (Keys.LButton | Keys.ShiftKey)) //判断Ctrl键抬起
        isCtrlDown = false; //标记Ctrl键抬起
}

Ctrl键按下,启动计时器,将鼠标的实时位置添加到鼠标轨迹中。

Ctrl键抬起,将记录的鼠标轨迹逐一出队,调用Cursor的Draw方法来绘制鼠标的动作轨迹,停止计时器。

十二、模拟键盘输入

private void button1_Click(object sender, EventArgs e)//按钮1,输入字符
{
    textBox1.Focus(); //获取文本框焦点
    SendKeys.Send("1234ABCD+-×÷");
    SendKeys.Flush(); //处理所有的Windows消息
}
private void button2_Click(object sender, EventArgs e)//按钮2,退格
{
    textBox1.Focus();
    SendKeys.Send("{BS}");
    SendKeys.Flush();
}
private void button3_Click(object sender, EventArgs e)//按钮3,输入10个A
{
    textBox1.Focus();
    SendKeys.Send("{A 10}");
    SendKeys.Flush();
}
private void button4_Click(object sender, EventArgs e)//按钮4,输入Alt+F4键
{
    MessageBox.Show("窗口即将关闭!");
    SendKeys.Send("%{F4}");
}

通过SendKeys类的Send方法来实现向当前获取焦点的控件发送键盘按键。


参考:《C#程序设计经典300例》

相关推荐

为3D手游打造, Visual Studio Unity扩展下载

IT之家(www.ithome.com):为3D手游打造,VisualStudioUnity扩展下载7月30日消息,微软正式发布升级版VisualStudioToolsforUnity扩...

由ArcMap属性字段自增引出字段计算器使用Python的技巧

1.前言前些日子有人问我ArcMap中要让某个字段的值实现自增有什么方法?我首先想到像SQLServer中对于数值型字段可以设置自增。所以我打开ArcCatalog查看发现只提供默认值,没办法只能看...

微软首次回答 HoloLens 相关问题,终于爆料了

fengo2015/04/2115:11注:本文作者张静是NVIDIAGPU架构师,微信公众号“黑客与画家”(HackerAndPainter),知乎专栏地址。欢迎各位童鞋与他交流探讨。...

C#指针的应用(c#指针类型)

C#在有限的范围内支持指针。C#的指针只不过是一个持有另一类型内存地址的变量。但是在C#中,指针只能被声明为持有值类型和数组的内存地址。与引用类型不同,指针类型不被默认的垃圾收集机制所跟踪。出于同...

C# 堆栈(Stack)(c# 堆栈中定位调用messagebox 的地方)

C#集合在C#中,堆栈(Stack)是一种后进先出(LIFO,LastInFirstOut)的数据结构。堆栈(Stack)适用于存储和按顺序处理数据,其中最新添加的元素会最先被移除。堆...

欢迎回来:Fortran意外重回流行编程语言20强榜单

TIOBE指数是用来确定一种编程语言受欢迎程度的指标之一。它并不表明哪种编程语言是最好的,也不表明哪种编程语言写的代码行数最多,而是利用在谷歌、维基百科、必应、亚马逊、YouTube等各种引擎和网站上...

C#+NET MAUI实现跨平台/终端(linux,win,ios等)解决方案

简介.NETMulti-platformAppUI(.NETMAUI)是一个跨平台的框架,用于使用C#和XAML创建移动和桌面应用程序。使用.NETMAUI,您可以用一套代码库开发可以在A...

C#代码安全红线:SQL注入防护终极方案,让你的系统固若金汤

在数字化时代,应用系统的安全性至关重要。而SQL注入攻击,长期盘踞在OWASP(OpenWebApplicationSecurityProject)漏洞榜单的前列,成为众多基于数据库的应用系统...

C# (一)状态机模式(状态机代码实现)

最近空闲,炒炒隔夜饭,以前这些模式在自己项目种应用过不少,但一直没有像别人那样写一个系列,最近年纪大了,很多东西都忘记了,特别AI的兴起,更少写代码了,反正没什么事情,自己在重写一遍吧。创建型模式(5...

C# 中 Predicate 详解(c#中的replace)

Predicate泛型委托:表示定义一组条件并确定指定对象是否符合这些条件的方法。此委托由Array和List类的几种方法使用,用于在集合中搜索元素。Predicate<T>...

C#中$的用法?(c#中&&什么意思)

文章来自AI问答。在C#中,$符号用于字符串插值(StringInterpolation)。字符串插值是C#6.0引入的一种特性,它允许你在字符串中直接嵌入表达式,而不需要使用string.For...

C#并行编程:Parallel类(c# 并行处理)

在Parallel类中提供了三个静态方法作为结构化并行的基本形式:Parallel.Invoke方法:并行执行一组委托。Parallel.For方法:执行与C#for循环等价的并行方法。Parall...

颠覆认知!用Span重构foreach循环竟让数据处理快如闪电

在C#编程的世界里,数据处理效率始终是开发者们关注的焦点。随着项目规模的扩大和数据量的激增,哪怕是细微的性能提升,都可能对整个应用的响应速度和用户体验产生深远影响。近年来,C#引入的Span<T...

Unity3D手游开发实践《腾讯桌球》客户端开发经验总结

本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身。虽然基于Unity3D,很多东西同样适用于Cocos。本文从以下10大点进行阐述:1.架构设计2.原生插件/平台交互3.版本与补丁4.用脚本,...

.NET 7 AOT 的使用以及 .NET 与 Go 互相调用

目录背景C#部分环境要求创建一个控制台项目体验AOT编译C#调用库函数减少体积C#导出函数C#调用C#生成的AOTGolang部分安装GCCGolang导出函数.NETC#...