图片传输
C#获取屏幕二进制数据
代码语言:javascript复制using System.IO;
namespace z_remote_control.Utils
{
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
public class ZScreenUtils
{
public static byte[] GetScreenshot()
{
using (Bitmap screenshot = new Bitmap(
Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height
))
{
using (Graphics gfx = Graphics.FromImage(screenshot))
{
gfx.CopyFromScreen(
Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy
);
using (MemoryStream ms = new MemoryStream())
{
screenshot.Save(
ms,
ImageFormat.Png
);
return ms.ToArray();
}
}
}
}
}
}
我们使用单独的线程不停发送图片
代码语言:javascript复制private void SendPic()
{
new Thread(
() =>
{
while (true)
{
ZwsServer wsServer = ZwsServer.GetInstance();
var screenshot = ZScreenUtils.GetScreenshot();
wsServer.SendMessageToAll(screenshot);
}
}
).Start();
}
Web端接收显示
代码语言:javascript复制socket.onmessage = (evt) => {
if (typeof evt.data === 'string') {
// 处理字符串类型的数据
} else if (evt.data instanceof Blob) {
// 处理 Blob 类型的数据
const imageUrl = URL.createObjectURL(evt.data);
this.img_url = imageUrl;
}
};
鼠标事件传递
Web鼠标事件
获取鼠标所在元素内的位置
代码语言:javascript复制get_pos (e, box) {
// 获取鼠标相对于浏览器窗口视口的位置
var mouseX = e.clientX;
var mouseY = e.clientY;
// 获取元素相对于浏览器窗口视口的位置
var boxRect = box.getBoundingClientRect();
var boxX = boxRect.left;
var boxY = boxRect.top;
// 计算鼠标在元素内的相对位置
var relativeX = mouseX - boxX;
var relativeY = mouseY - boxY;
const width = box.offsetWidth;
const height = box.offsetHeight;
if (relativeX < 0) {
relativeX = 0;
}
if (relativeY < 0) {
relativeY = 0;
}
if (relativeX > width) {
relativeX = width;
}
if (relativeY > height) {
relativeY = height;
}
return {
btn: e.button,//0左键 2右键
x: relativeX / width,
y: relativeY / height
}
},
注意
这里返回的值是0-1。
元素监听事件
代码语言:javascript复制init_mouse_event () {
let myimg = this.$refs["myimg"];
let that = this;
myimg.addEventListener('contextmenu', function (e) {
e.preventDefault();
});
myimg.addEventListener('mousedown', function (e) {
var pos = that.get_pos(e, this);
console.log(pos.btn, "鼠标按下", '(' pos.x ',' pos.y ')');
});
myimg.addEventListener('mouseup', function (e) {
var pos = that.get_pos(e, this);
console.log(pos.btn, "鼠标抬起", '(' pos.x ',' pos.y ')');
});
myimg.addEventListener('mousemove', function (e) {
var pos = that.get_pos(e, this);
console.log(pos.btn, "移动", '(' pos.x ',' pos.y ')');
});
},
注意
这是用来禁用右键菜单
代码语言:javascript复制myimg.addEventListener('contextmenu', function (e) {
e.preventDefault();
});
C#模拟鼠标事件
在C#中触发鼠标事件:
SendInput
使用Windows API函数
- 首先导入Windows API类库,包括“using System.Runtime.InteropServices;”等命名空间。
- 在程序中定义鼠标事件的常量和结构体,如下所示:
public const int MOUSEEVENTF_MOVE = 0x0001; //移动鼠标
public const int MOUSEEVENTF_LEFTDOWN = 0x0002; //左键按下
public const int MOUSEEVENTF_LEFTUP = 0x0004; //左键抬起
public const int MOUSEEVENTF_RIGHTDOWN = 0x0008; //右键按下
public const int MOUSEEVENTF_RIGHTUP = 0x0010; //右键抬起
[DllImport("user32.dll")]
static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct INPUT
{
public int type;
public MOUSEINPUT mi;
}
- 编写代码触发相应的鼠标事件,如下所示:
public void MoveMouse(int x, int y)
{
INPUT input = new INPUT();
input.type = 0; //0表示鼠标事件
input.mi.dx = x;
input.mi.dy = y;
input.mi.mouseData = 0;
input.mi.dwFlags = MOUSEEVENTF_MOVE;
input.mi.time = 0;
input.mi.dwExtraInfo = IntPtr.Zero;
SendInput(1, ref input, Marshal.SizeOf(input));
}
public void LeftClick(int x, int y)
{
INPUT input = new INPUT();
input.type = 0; //0表示鼠标事件
input.mi.dx = x;
input.mi.dy = y;
input.mi.mouseData = 0;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input.mi.time = 0;
input.mi.dwExtraInfo = IntPtr.Zero;
SendInput(1, ref input, Marshal.SizeOf(input));
input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, ref input, Marshal.SizeOf(input));
}
mouse_event
使用C#触发鼠标的移动、按下和抬起事件的完整代码:
代码语言:javascript复制using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace MouseOperation
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
static extern bool SetCursorPos(int x, int y);
[DllImport("user32.dll")]
static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, int dwExtraInfo);
private const uint MOUSEEVENTF_LEFTDOWN = 0x02;
private const uint MOUSEEVENTF_LEFTUP = 0x04;
private const uint MOUSEEVENTF_MOVE = 0x0001;
public Form1()
{
InitializeComponent();
}
private void btnMove_Click(object sender, EventArgs e)
{
int x = Cursor.Position.X;
int y = Cursor.Position.Y;
SetCursorPos(x 10, y 10);
Thread.Sleep(500);
SetCursorPos(x, y);
}
private void btnClick_Click(object sender, EventArgs e)
{
mouse_event(MOUSEEVENTF_LEFTDOWN, Cursor.Position.X, Cursor.Position.Y, 0, 0);
Thread.Sleep(100);
mouse_event(MOUSEEVENTF_LEFTUP, Cursor.Position.X, Cursor.Position.Y, 0, 0);
}
private void btnDrag_Click(object sender, EventArgs e)
{
int x = Cursor.Position.X;
int y = Cursor.Position.Y;
mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
Thread.Sleep(500);
SetCursorPos(x 10, y 10);
mouse_event(MOUSEEVENTF_MOVE, x 10, y 10, 0, 0);
Thread.Sleep(500);
SetCursorPos(x, y);
mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
}
}
}
这个代码示例提供了三个按钮,分别用于模拟鼠标的移动、点击和拖拽操作。在 btnMove_Click
中,我们首先获取当前鼠标光标的位置,并将其向右下角移动 10 个像素,然后等待 500 毫秒,最后将鼠标光标移回原来的位置。在 btnClick_Click
中,我们模拟了鼠标左键按下和抬起的事件。在 btnDrag_Click
中,我们模拟了鼠标的拖拽事件。
为了调用鼠标事件,我们在代码中使用了 DllImport
库引入了 user32.dll
,并调用了其中的 SetCursorPos
和 mouse_event
方法。SetCursorPos
方法用于设置鼠标光标的位置,而 mouse_event
方法则用于向系统发送鼠标事件。在 mouse_event
方法中,我们可以使用 dwFlags
参数指定要模拟的鼠标事件类型,如左键按下、左键抬起和鼠标移动等。
需要注意的是
使用Windows API函数触发鼠标事件需要使用
[DllImport("user32.dll")]
引入相应的函数,并且需要在程序执行时以管理员身份运行。
对比
SendInput 和 mouse_event 都可以用于模拟鼠标事件,它们的主要区别在于:
- SendInput 是 Windows 操作系统提供的 API,而 mouse_event 是 Win32 API。
- SendInput 是较新的 API,可以用于模拟更多种类的输入设备(如键盘、鼠标、触摸屏等),而 mouse_event 只能模拟鼠标事件。
- SendInput 的精度比 mouse_event 更高,可以模拟出更精确的鼠标操作。
- SendInput 可以通过异步方式模拟鼠标事件,而 mouse_event 只能同步方式模拟。
因此,如果需要模拟多种输入设备事件或需要精确模拟鼠标操作,建议使用 SendInput。如果只需要模拟鼠标事件并且需求不是很高,则可以使用 mouse_event。