利用多线程句柄设置鼠标忙碌状态的实现方法

实现鼠标忙碌状态的方法一般有两种,分别是使用win32api的SetCursor和自定义控件来实现。使用多线程句柄设置鼠标忙碌状态需要采用自定义控件的方法,因为SetCursor属于UI线程接口,不能在多线程中直接调用。

以下是实现方法的完整攻略:

  1. 创建自定义控件

首先需要创建一个自定义控件来替代系统的鼠标指针。这个自定义控件可以是一个静态图片,也可以是一个动态图标(GIF或者APNG)。

示例一:

在HTML页面中,可以使用CSS的cursor属性来指定自定义的鼠标指针,通过设置指向自定义图标的URL来实现。例如:

body {
    cursor: url(custom-cursor.gif), auto;
}

这样就把鼠标指针指向了一个名为custom-cursor.gif的图标。

示例二:

C#的WinForm应用程序中,可以继承System.Windows.Forms.Control类来创建一个自定义控件。自定义控件可以通过标准的WinForm方式加载和显示,也可以在程序中动态添加或删除。

下面是一个示例代码:

public class CustomCursor : Control
{
    public CustomCursor()
    {
        this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        // 在这里绘制自定义鼠标指针
    }
}

这个CustomCursor类继承了Control类,并在构造函数中设置控件的样式。在OnPaint方法中,可以实现自定义鼠标指针的绘制代码。

  1. 通过多线程句柄控制鼠标指针

接下来需要使用多线程句柄来控制鼠标指针的显示与隐藏。这里使用C++示例代码说明:

#include <windows.h>

DWORD WINAPI threadFunc(LPVOID lpParam)
{
    HWND hWnd = *(HWND*)lpParam;
    while (1) {
        ShowCursor(false);
        SetCursorPos(0,0);
        Sleep(1000);
        ShowCursor(true);
        Sleep(1000);
    }
    return 0;
}

int main(int argc, char** argv)
{
    HANDLE hThread;
    DWORD dwThreadId;
    HWND hWnd = GetDesktopWindow();
    hThread = CreateThread(NULL, 0, threadFunc, &hWnd, 0, &dwThreadId);
    if (hThread != NULL) {
        WaitForSingleObject(hThread, INFINITE);
        CloseHandle(hThread);
    }
    return 0;
}

这段代码创建一个新的线程,并通过HWND参数获取桌面窗口句柄。线程中循环执行ShowCursor和SetCursorPos函数,控制鼠标指针的显示与隐藏。最后使用WaitForSingleObject和CloseHandle函数强制结束线程。

  1. 结合自定义控件和多线程句柄

最后,在自定义控件的OnPaint方法中,根据需要绘制自定义鼠标指针并控制其显示状态。以下是一个C#的WinForm示例代码:

public class CustomCursor : Control
{
    private Thread thread;

    public CustomCursor()
    {
        this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
        this.thread = new Thread(new ThreadStart(()=> {
            while (true) {
                Cursor.Hide();
                this.Invalidate();
                Thread.Sleep(1000);
                Cursor.Show();
                this.Invalidate();
                Thread.Sleep(1000);
            }
        }));
        this.thread.IsBackground = true;
        this.thread.Start();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (Cursor.Current == Cursors.WaitCursor) {
            e.Graphics.DrawImage(Properties.Resources.wait_cursor, Cursor.Position.X - 16, Cursor.Position.Y - 16);
        }
        else {
            base.OnPaint(e);
        }
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing) {
            if (this.thread != null) {
                this.thread.Abort();
                this.thread = null;
            }
        }
        base.Dispose(disposing);
    }
}

在构造函数中启动线程,使用Invalidate方法强制更新自定义控件的绘制。在OnPaint方法中判断鼠标指针是否为等待状态,如果是则绘制自定义鼠标指针。在Dispose方法中结束线程。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:利用多线程句柄设置鼠标忙碌状态的实现方法 - Python技术站

(0)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • c# WinForm 窗体之间传值的几种方式(小结)

    C# WinForm 窗体之间传值的几种方式(小结)是一篇关于C# WinForm中多个窗体之间进行数据传输的教程。下面,我将详细讲解这篇攻略的内容。 概述 该文主要讲解如何在 C# WinForm 中实现窗体之间的数据传输,我们知道在 Windows 系统下的许多应用程序中,除了主窗体以外可能会有一些其他的功能窗体,如登录窗体、设置窗体、信息弹窗等等,这些…

    C# 2023年6月7日
    00
  • C# 限制输入为字母或数字以及长度

    日常开发过程中,验证字符的合法性一直是一个必不可少的步骤,以前都是在用户输入完再做判断,不仅麻烦在不符合标准的时候还要提示用户修改,体验很差,为什么不在输入的时候加以限制呢? 以 Winform的TextBox控件为例,这里提供两种方案: 通过字符匹配 正则表达式 在用户输入时限制,所以选用KeyPress事件。 字符匹配 private void txt_…

    C# 2023年4月19日
    00
  • Unity实现俄罗斯方块(二)

    Unity实现俄罗斯方块(二)攻略 1. 前言 在上一篇文章《Unity实现俄罗斯方块(一)》中,我们实现了俄罗斯方块游戏的基本框架,包括生成指定形状的方块、方块下落、方块旋转、消行等基本功能。接下来,我们在这个基础上,继续实现俄罗斯方块游戏的其他功能,包括左右移动和加速下落。 下面,我们就一步一步来详细讲解如何实现这些功能。 2. 左右移动 在俄罗斯方块游…

    C# 2023年6月1日
    00
  • C#实现读取写入Json文件

    下面是详细的C#实现读取写入JSON文件的攻略: 1. Json.Net 库的引用 C#中常用的第三方JSON库是Json.Net,需要先引用它。可以通过NuGet来安装,在项目目录下执行以下命令: Install-Package Newtonsoft.Json 或在Visual Studio中通过菜单命令:Tools-> NuGet Package …

    C# 2023年5月31日
    00
  • C#中的问号(?号)用法小结

    下面是“C#中的问号(?号)用法小结”的详细讲解: 什么是问号(?号)? 问号(?号)是C# 2.0引入的一个新运算符,也称为“空值传播运算符(null conditional operator)”或者“Elvis运算符(因为它看起来像Elvis Presley的头发)”。它的作用是在一个对象的成员操作中及早地发现并处理空值(null)。 为什么使用问号(?…

    C# 2023年5月14日
    00
  • ASP.NET GridView 实现课程表显示(动态合并单元格)实现步骤

    ASP.NET GridView 是一个非常强大的可视化数据控制器,能够轻松处理表格数据。实现课程表显示的动态合并单元格可以通过以下步骤完成: 步骤 1:创建 GridView 控件 首先,需要在 ASP.NET 网页中创建一个 GridView 控件。在创建时,需要设置其 AutoGenerateColumns 属性为 False 并手动添加 BoundF…

    C# 2023年5月31日
    00
  • C#记录消息到日志文件的方法

    以下是C#记录消息到日志文件的方法的完整攻略: 简介 C#提供了许多工具和类来帮助我们记录日志,例如log4net和NLog等第三方库,也有.NET Framework提供的类库来实现对日志的记录,比如System.Diagnostics命名空间下的Trace, EventLog等类。 使用Trace类记录日志 Trace类可以跟踪调试信息,并记录到文件、控…

    C# 2023年6月1日
    00
  • C# 基础编程题集锦

    简单字符串加密 编写一个应用程序用来输入的字符串进行加密,对于字母字符串加密规则如下:’a→d’ ‘b’→’e’ ‘w’→z’ …… x’→’a’ ‘y’→b’ ‘z→c’ ‘A’→’D’ ‘B’→’E’ ‘W’→’Z’ ‘X’→’A’ ‘Y’→’B’ ‘Z’→’C’ ?对于其他字符,不进行加密。 static void Main(string[] …

    C# 2023年5月1日
    00
合作推广
合作推广
分享本页
返回顶部