双指缩放

This commit is contained in:
snltty
2023-10-17 00:41:05 +08:00
parent 1af668ae19
commit 4a52caecdd
65 changed files with 1241 additions and 5369 deletions

View File

@@ -1,8 +1,8 @@
import { sendWebsocketMsg } from './request'
export const notifyUpdate = (speed, msg) => {
export const notifyUpdate = (speed, msg, star) => {
return sendWebsocketMsg('notify/update', {
speed, msg
speed, msg, star
});
}

View File

@@ -1,7 +1,9 @@
import { sendWebsocketMsg } from './request'
export const reportUpdate = (names) => {
return sendWebsocketMsg('report/update', names);
export const reportUpdate = (names, reportType) => {
return sendWebsocketMsg('report/update', {
names, reportType
});
}
export const reportPing = (names) => {
return sendWebsocketMsg('report/ping', names);

View File

@@ -1,7 +1,9 @@
import { sendWebsocketMsg } from './request'
export const screenUpdateFull = (names) => {
return sendWebsocketMsg('screen/full', names);
export const screenUpdateFull = (names, type) => {
return sendWebsocketMsg('screen/full', {
names, type
});
}
export const screenUpdateRegion = (names) => {
return sendWebsocketMsg('screen/region', names);

View File

@@ -7,7 +7,8 @@ export default {
Report: {
fps: 0,
fpsTimes: 0,
ping: 0
ping: 0,
updated: false
},
}
},
@@ -32,7 +33,14 @@ export default {
reportInterval() {
if (this.reported) {
this.reported = false;
reportUpdate(this.globalData.value.reportNames).then(() => {
const names = this.globalData.value.reportNames;
let reportType = 1;
this.globalData.value.devices.filter(c => names.indexOf(c.MachineName) >= 0).forEach(item => {
reportType &&= Number(item.Report.updated);
item.Report.updated = true;
});
reportUpdate(names, reportType).then(() => {
this.reported = true;
this.reportTimer = setTimeout(() => {
this.reportInterval();

View File

@@ -5,12 +5,47 @@ export default {
field() {
return {
Screen: {
regions: [],
img: null,
fullUpdated: false,
draw(canvas, ctx) {
this.drawFps(canvas, ctx);
this.drawRectangle(canvas, ctx);
this.drawTouch(canvas, ctx);
},
lastInput: 0,
fps: 0,
fpsTimes: 0,
img: null,
regions: [],
LastInput: 0,
drawFps(canvas, ctx) {
ctx.lineWidth = 5;
ctx.font = 'bold 60px Arial';
ctx.fillStyle = 'rgba(0,0,0,0.5)';
ctx.fillText(`FPS : ${this.fps} 、LT : ${this.lastInput}ms`, 50, 70);
ctx.lineWidth = 2;
ctx.strokeStyle = '#fff';
ctx.strokeText(`FPS : ${this.fps} 、LT : ${this.lastInput}ms`, 50, 70);
},
rectangles: [],
drawRectangle(canvas, ctx) {
if (this.rectangles.length > 0 && this.touch.scale == 1) {
ctx.lineWidth = 5;
ctx.strokeStyle = 'rgba(255,0,0,1)';
for (let i = 0; i < this.rectangles.length; i++) {
const rectangle = this.rectangles[i];
ctx.rect(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
ctx.stroke();
ctx.font = 'bold 100px Arial';
ctx.fillStyle = 'rgba(255,0,0,1)';
ctx.fillText(i, rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2);
}
}
},
touch: {
//上次位置
lastTouch: { x1: 0, y1: 0, x2: 0, y2: 0, dist: 0, },
@@ -21,6 +56,20 @@ export default {
updated: false,
type: 0
},
drawTouch(canvas, ctx) {
if (this.touch.type == 2) {
ctx.fillStyle = 'red';
ctx.strokeStyle = 'yellow';
ctx.rect(this.touch.origin.x - 50, this.touch.origin.y - 50, 100, 100);
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = 'yellow';
ctx.moveTo(this.touch.lastTouch.x1, this.touch.lastTouch.y1);
ctx.lineTo(this.touch.lastTouch.x2, this.touch.lastTouch.y2);
ctx.stroke();
}
},
touchend(event) {
this.touch.type = 0;
@@ -75,6 +124,7 @@ export default {
};
} else if (event.touches.length == 1) {
if (this.touch.scale == 1) return;
this.touch.type = 1;
const { x1, y1 } = this.getPosition(event);
this.touch.lastTouch.x1 = x1;
@@ -102,7 +152,7 @@ export default {
this.touch.updated = true;
} else if (event.touches.length == 1) {
if (this.touch.type != 1) return;
if (this.touch.type != 1 || this.touch.scale == 1) return;
const { x1, y1 } = this.getPosition(event);
const distX = x1 - this.touch.lastTouch.x1;
@@ -222,36 +272,40 @@ export default {
const item = devices[i];
if (!item.canvas) {
item.canvas = document.getElementById(`canvas-${item.MachineName}`);
if (item.canvas) {
item.ctx = item.canvas.getContext('2d');
}
if (!item.infoCanvas) {
item.infoCanvas = document.createElement('canvas');
item.infoCanvas.width = item.canvas.width;
item.infoCanvas.height = item.canvas.height;
item.infoCtx = item.infoCanvas.getContext('2d');
}
if (item.ctx) {
item.infoCtx.clearRect(0, 0, item.infoCanvas.width, item.infoCanvas.height);
const img = item.Screen.img;
item.ctx.clearRect(0, 0, item.canvas.width, item.canvas.height);
if (img) {
item.ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, item.canvas.width, item.canvas.height);
} else {
//screenUpdateFull(this.globalData.value.reportNames);
}
const regions = item.Screen.regions;
for (let i = 0; i < regions.length; i++) {
const { x, y, w, h } = regions[i].param;
item.ctx.drawImage(regions[i], 0, 0, regions[i].width, regions[i].height, x, y, w, h);
item.infoCtx.drawImage(regions[i], 0, 0, regions[i].width, regions[i].height, x, y, w, h);
}
this.drawFps(item);
for (let j in item) {
try {
if (item[j] && item[j].draw) {
item[j].draw(item.canvas, item.ctx);
item[j].draw(item.infoCanvas, item.infoCtx);
}
} catch (e) {
console.log(e);
}
}
item.ctx.drawImage(item.infoCanvas, 0, 0, item.infoCanvas.width, item.infoCanvas.height, 0, 0, item.canvas.width, item.canvas.height);
}
}
requestAnimationFrame(() => {
@@ -268,42 +322,6 @@ export default {
this.fpsInterval();
}, 1000)
},
drawFps(item) {
item.ctx.lineWidth = 5;
item.ctx.font = 'bold 60px Arial';
item.ctx.fillStyle = 'rgba(0,0,0,0.5)';
item.ctx.fillText(`FPS : ${item.Screen.fps} 、LT : ${item.Screen.LastInput}ms`, 50, 70);
item.ctx.lineWidth = 2;
item.ctx.strokeStyle = '#fff';
item.ctx.strokeText(`FPS : ${item.Screen.fps} 、LT : ${item.Screen.LastInput}ms`, 50, 70);
if (item.Screen.rectangles.length > 0) {
item.ctx.lineWidth = 5;
for (let i = 0; i < item.Screen.rectangles.length; i++) {
item.ctx.strokeStyle = 'rgba(255,0,0,0.5)';
const rectangle = item.Screen.rectangles[i];
item.ctx.rect(rectangle.X / 0.2, rectangle.Y / 0.2, rectangle.Width / 0.2, rectangle.Height / 0.2);
item.ctx.stroke();
item.ctx.font = 'bold 100px Arial';
item.ctx.fillStyle = 'rgba(0,0,0,1)';
item.ctx.fillText(i, rectangle.X / 0.2, rectangle.Y / 0.2);
}
}
if (item.Screen.touch.type == 2) {
item.ctx.fillStyle = 'red';
item.ctx.strokeStyle = 'yellow';
item.ctx.rect(item.Screen.touch.origin.x - 50, item.Screen.touch.origin.y - 50, 100, 100);
item.ctx.fill();
item.ctx.lineWidth = 5;
item.ctx.strokeStyle = 'yellow';
item.ctx.moveTo(item.Screen.touch.lastTouch.x1, item.Screen.touch.lastTouch.y1);
item.ctx.lineTo(item.Screen.touch.lastTouch.x2, item.Screen.touch.lastTouch.y2);
item.ctx.stroke();
}
},
clipTimer: 0,
clipInterver() {
@@ -326,7 +344,9 @@ export default {
reportInterval() {
if (this.reported) {
this.reported = false;
screenUpdateFull(this.globalData.value.reportNames).then(() => {
const names = this.globalData.value.reportNames;
screenUpdateFull(names, 0).then(() => {
this.reported = true;
this.reportTimer = setTimeout(() => {
this.reportInterval();
@@ -347,6 +367,6 @@ export default {
update(item, report) {
if (!report.Screen) return;
item.Screen.LastInput = report.Screen.LT || 0;
item.Screen.lastInput = report.Screen.LT || 0;
}
}

View File

@@ -72,7 +72,7 @@ export default {
if (res) {
ElMessage.success('操作成功!');
if (value.notify) {
notifyUpdate(2, `恭喜[${props.data.Share.UserName.Value}]获得【${value.star}星】点评`);
notifyUpdate(2, props.data.Share.UserName.Value, value.star);
}
} else {
ElMessage.error('操作失败!');

View File

@@ -1,4 +1,5 @@
using cmonitor.server.service;
using cmonitor.server.client.reports;
using cmonitor.server.service;
using cmonitor.server.service.messengers.command;
using cmonitor.server.service.messengers.sign;
using common.libs;
@@ -22,15 +23,14 @@ namespace cmonitor.server.api.services
}
public bool Update(ClientServiceParamsInfo param)
{
string[] names = param.Content.DeJson<string[]>();
for (int i = 0; i < names.Length; i++)
UpdateInfo updateinfo = param.Content.DeJson<UpdateInfo>();
byte[] bytes = new byte[] { (byte)updateinfo.ReportType };
for (int i = 0; i < updateinfo.Names.Length; i++)
{
bool res = signCaching.Get(names[i], out SignCacheInfo cache)
&& cache.Connected
&& cache.GetReport(config.ReportDelay)
&& Interlocked.CompareExchange(ref cache.ReportFlag, 0, 1) == 1;
bool connectionRes = (signCaching.Get(updateinfo.Names[i], out SignCacheInfo cache) && cache.Connected);
bool reportTimeRes = cache.GetReport(config.ReportDelay) && Interlocked.CompareExchange(ref cache.ReportFlag, 0, 1) == 1;
if (res)
if (connectionRes && (reportTimeRes || updateinfo.ReportType == ReportType.Full))
{
cache.UpdateReport();
_ = messengerSender.SendOnly(new MessageRequestWrap
@@ -38,6 +38,7 @@ namespace cmonitor.server.api.services
Connection = cache.Connection,
MessengerId = (ushort)ReportMessengerIds.Update,
Timeout = 1000,
Payload = bytes,
}).ContinueWith((result) =>
{
Interlocked.Exchange(ref cache.ReportFlag, 1);
@@ -80,5 +81,12 @@ namespace cmonitor.server.api.services
return true;
}
sealed class UpdateInfo
{
public string[] Names { get; set; }
public ReportType ReportType { get; set; }
}
}
}

View File

@@ -20,21 +20,19 @@ namespace cmonitor.server.api.services
}
public bool Full(ClientServiceParamsInfo param)
{
string[] names = param.Content.DeJson<string[]>();
for (int i = 0; i < names.Length; i++)
ScreenReportInfo report = param.Content.DeJson<ScreenReportInfo>();
for (int i = 0; i < report.Names.Length; i++)
{
bool res = signCaching.Get(names[i], out SignCacheInfo cache)
&& cache.Connected
&& cache.GetScreen(config.ScreenDelay)
&& Interlocked.CompareExchange(ref cache.ScreenFlag, 0, 1) == 1;
if (res)
bool connectionRes = signCaching.Get(report.Names[i], out SignCacheInfo cache) && cache.Connected;
bool reportRes = cache.GetScreen(config.ScreenDelay) && Interlocked.CompareExchange(ref cache.ScreenFlag, 0, 1) == 1;
if (connectionRes && reportRes)
{
cache.UpdateScreen();
_ = messengerSender.SendOnly(new MessageRequestWrap
{
Connection = cache.Connection,
MessengerId = (ushort)ScreenMessengerIds.Full,
Timeout = 1000,
Timeout = 1000
}).ContinueWith((result) =>
{
Interlocked.Exchange(ref cache.ScreenFlag, 1);
@@ -60,7 +58,6 @@ namespace cmonitor.server.api.services
return true;
}
public bool Region(ClientServiceParamsInfo param)
{
string[] names = param.Content.DeJson<string[]>();
@@ -88,6 +85,12 @@ namespace cmonitor.server.api.services
return true;
}
}
public sealed class ScreenReportInfo
{
public string[] Names { get; set; }
public byte Type { get; set; }
}
public sealed class ScreenClipParamInfo
{
public string Name { get; set; }

View File

@@ -13,7 +13,7 @@ namespace cmonitor.server.client.reports
{
public string Name { get; }
public object GetReports();
public object GetReports(ReportType reportType);
}
public sealed class ReportTransfer : IReport
@@ -27,6 +27,8 @@ namespace cmonitor.server.client.reports
private List<IReport> reports;
private Dictionary<string, object> reportObj;
private ReportType reportType = ReportType.Full;
public ReportTransfer(ClientSignInState clientSignInState, MessengerSender messengerSender, ServiceProvider serviceProvider, Config config)
{
this.clientSignInState = clientSignInState;
@@ -39,7 +41,7 @@ namespace cmonitor.server.client.reports
}
}
public object GetReports()
public object GetReports(ReportType reportType)
{
return null;
}
@@ -53,8 +55,9 @@ namespace cmonitor.server.client.reports
private uint reportFlag = 0;
private long ticks = 0;
public void Update()
public void Update(ReportType reportType)
{
this.reportType = reportType;
ticks = DateTime.UtcNow.Ticks;
Interlocked.CompareExchange(ref reportFlag, 1, 0);
}
@@ -90,7 +93,7 @@ namespace cmonitor.server.client.reports
{
if (string.IsNullOrWhiteSpace(item.Name) == false)
{
object val = item.GetReports();
object val = item.GetReports(reportType);
if (val != null)
{
reportObj[item.Name] = val;
@@ -99,6 +102,7 @@ namespace cmonitor.server.client.reports
}
if (reportObj.Count > 0)
{
string json = reportObj.ToJsonDefault();
byte[] res = MemoryPackSerializer.Serialize(json);
await messengerSender.SendOnly(new MessageRequestWrap
@@ -110,4 +114,9 @@ namespace cmonitor.server.client.reports
}
}
}
public enum ReportType : byte
{
Full = 0, Trim = 1
}
}

View File

@@ -30,9 +30,9 @@ namespace cmonitor.server.client.reports.active
}
}
public object GetReports()
public object GetReports(ReportType reportType)
{
if (report.Pid != lastPid || report.Title != lastTitle)
if (reportType == ReportType.Full || report.Pid != lastPid || report.Title != lastTitle)
{
lastPid = report.Pid;
lastTitle = report.Title;

View File

@@ -7,7 +7,7 @@ namespace cmonitor.server.client.reports.command
{
public string Name => "Command";
public object GetReports()
public object GetReports(ReportType reportType)
{
return null;
}

View File

@@ -9,8 +9,10 @@ namespace cmonitor.server.client.reports.hijack
private readonly HijackEventHandler hijackEventHandler;
private readonly HijackConfig hijackConfig;
ulong[] array = new ulong[3];
ulong[] lastArray = new ulong[3];
private ulong[] array = new ulong[3];
private ulong[] lastArray = new ulong[3];
private long ticks = DateTime.UtcNow.Ticks;
public HijackReport(HijackEventHandler hijackEventHandler, HijackController hijackController, HijackConfig hijackConfig)
{
this.hijackEventHandler = hijackEventHandler;
@@ -28,15 +30,17 @@ namespace cmonitor.server.client.reports.hijack
}
}
public object GetReports()
public object GetReports(ReportType reportType)
{
array[0] = hijackEventHandler.UdpSend + hijackEventHandler.TcpSend;
array[1] = hijackEventHandler.TcpReceive + hijackEventHandler.UdpReceive;
ulong count = (ulong)(hijackConfig.AllowIPs.Length + hijackConfig.DeniedIPs.Length + hijackConfig.AllowDomains.Length + hijackConfig.DeniedDomains.Length + hijackConfig.AllowProcesss.Length + hijackConfig.DeniedProcesss.Length);
array[2] = count;
if(array.SequenceEqual(lastArray) == false)
long _ticks = DateTime.UtcNow.Ticks;
if (((_ticks - ticks) / TimeSpan.TicksPerMillisecond >= 300 && array.SequenceEqual(lastArray) == false))
{
ticks = _ticks;
lastArray[0] = array[0];
lastArray[1] = array[1];
lastArray[2] = array[2];

View File

@@ -21,9 +21,9 @@
}
}
public object GetReports()
public object GetReports(ReportType reportType)
{
if (report.Value != lastValue)
if (reportType == ReportType.Full || report.Value != lastValue)
{
lastValue = report.Value;
return report;

View File

@@ -20,13 +20,13 @@ namespace cmonitor.server.client.reports.llock
}
DateTime startTime = new DateTime(1970, 1, 1);
public object GetReports()
public object GetReports(ReportType reportType)
{
if (shareReport.GetShare(Name, out ShareItemInfo share) && string.IsNullOrWhiteSpace(share.Value) == false && long.TryParse(share.Value, out long time))
{
report.Value = (long)(DateTime.UtcNow.Subtract(startTime)).TotalMilliseconds - time < 1000;
}
if(report.Value != lastValue)
if(reportType == ReportType.Full || report.Value != lastValue)
{
lastValue = report.Value;
return report;

View File

@@ -11,7 +11,7 @@ namespace cmonitor.server.client.reports.notify
{
}
public object GetReports()
public object GetReports(ReportType reportType)
{
return null;
}
@@ -21,7 +21,7 @@ namespace cmonitor.server.client.reports.notify
Task.Run(() =>
{
CommandHelper.Windows(string.Empty, new string[] {
$"start notify.win.exe {notify.Speed} \"{notify.Msg}\""
$"start notify.win.exe {notify.Speed} \"{notify.Msg}\" {notify.Star}"
});
});
}
@@ -32,6 +32,7 @@ namespace cmonitor.server.client.reports.notify
{
public byte Speed { get; set; }
public string Msg { get; set; }
public byte Star { get; set; } = 1;
}
}

View File

@@ -1,6 +1,6 @@
using MemoryPack;
namespace cmonitor.server.client.reports.screen.sharpDX
namespace cmonitor.server.client.reports.screen
{
public class DesktopFrame
{
@@ -8,12 +8,8 @@ namespace cmonitor.server.client.reports.screen.sharpDX
public Rectangle[] UpdatedRegions { get; internal set; }
public Memory<byte> RegionImage { get; internal set; }
public int Width { get; internal set; }
public int Height { get; internal set; }
public float ScaleX { get; internal set; }
public float ScaleY { get; internal set; }
//public MovedRegion[] MovedRegions { get; internal set; }
public MovedRegion[] MovedRegions { get; internal set; }
//public Rectangle[] Updateds { get; internal set; }
}
@@ -25,6 +21,31 @@ namespace cmonitor.server.client.reports.screen.sharpDX
public Rectangle Destination { get; internal set; }
}
public struct Scale
{
public Scale(int x, int y,float scale)
{
X = x;
Y = y;
Value = scale;
}
public int X { get; set; }
public int Y { get; set; }
public float Value { get; set; }
}
public struct Rect
{
public Rect(int width, int height)
{
Width = width;
Height = height;
}
public int Width { get; set; }
public int Height { get; set; }
}
[MemoryPackable]
public partial struct Rectangle
{

View File

@@ -8,13 +8,11 @@ using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using SharpDX.Mathematics.Interop;
using common.libs;
using common.libs.extends;
using cmonitor.server.client.reports.screen.aforge;
using System.Drawing.Drawing2D;
using Factory1 = SharpDX.DXGI.Factory1;
namespace cmonitor.server.client.reports.screen.sharpDX
namespace cmonitor.server.client.reports.screen
{
public class DesktopDuplicator
public sealed class DxgiDesktop
{
private Adapter1 adapter;
private Device mDevice;
@@ -28,18 +26,24 @@ namespace cmonitor.server.client.reports.screen.sharpDX
private ShaderResourceView smallerTextureView = null;
private OutputDuplicateFrameInformation frameInfo = new OutputDuplicateFrameInformation();
public DesktopDuplicator(int whichMonitor)
private int whichGraphicsCardAdapter;
private int whichOutputDevice;
public DxgiDesktop(int whichMonitor)
: this(0, whichMonitor) { }
public DesktopDuplicator(int whichGraphicsCardAdapter, int whichOutputDevice)
public DxgiDesktop(int whichGraphicsCardAdapter, int whichOutputDevice)
{
this.whichGraphicsCardAdapter = whichGraphicsCardAdapter;
this.whichOutputDevice = whichOutputDevice;
if (OperatingSystem.IsWindows())
{
InitCapture(whichGraphicsCardAdapter, whichOutputDevice);
InitCapture();
}
}
private void InitCapture(int whichGraphicsCardAdapter, int whichOutputDevice)
private void InitAdapter()
{
try
{
@@ -56,11 +60,15 @@ namespace cmonitor.server.client.reports.screen.sharpDX
}
adapter = new Factory1().GetAdapter1(whichGraphicsCardAdapter);
}
catch (SharpDXException)
catch (Exception ex)
{
throw new Exception("Could not find the specified graphics card adapter.");
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error(ex);
}
}
private void InitDevice()
{
try
{
if (mDevice != null)
@@ -68,13 +76,17 @@ namespace cmonitor.server.client.reports.screen.sharpDX
mDevice.Dispose();
mDevice = null;
}
}
catch (Exception)
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error(ex);
}
mDevice = new Device(adapter);
}
private void InitOutput()
{
try
{
try
@@ -89,12 +101,14 @@ namespace cmonitor.server.client.reports.screen.sharpDX
{
}
output = adapter.GetOutput(whichOutputDevice);
}
catch (SharpDXException)
{
throw new Exception("Could not find the specified output device.");
}
mOutputDesc = output.Description;
}
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error(ex);
}
try
{
if (output1 != null)
@@ -102,12 +116,17 @@ namespace cmonitor.server.client.reports.screen.sharpDX
output1.Dispose();
output1 = null;
}
}
catch (Exception)
{
}
output1 = output.QueryInterface<Output1>();
this.mOutputDesc = output.Description;
}
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error(ex);
}
}
private void InitTexture()
{
int width = output1.Description.DesktopBounds.Right - output1.Description.DesktopBounds.Left;
int height = output1.Description.DesktopBounds.Bottom - output1.Description.DesktopBounds.Top;
@@ -174,7 +193,9 @@ namespace cmonitor.server.client.reports.screen.sharpDX
{
}
smallerTextureView = new ShaderResourceView(mDevice, smallerTexture);
}
private void InitDesk()
{
try
{
if (mDeskDupl != null)
@@ -182,27 +203,138 @@ namespace cmonitor.server.client.reports.screen.sharpDX
mDeskDupl.Dispose();
mDeskDupl = null;
}
this.mDeskDupl = output1.DuplicateOutput(mDevice);
mDeskDupl = output1.DuplicateOutput(mDevice);
}
catch (SharpDXException ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error(ex);
if (ex.ResultCode.Code == SharpDX.DXGI.ResultCode.NotCurrentlyAvailable.Result.Code)
{
throw new Exception("There is already the maximum number of applications using the Desktop Duplication API running, please close one of the applications and try again.");
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error("There is already the maximum number of applications using the Desktop Duplication API running, please close one of the applications and try again.");
}
}
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error(ex);
}
}
private void InitCapture()
{
try
{
InitAdapter();
InitDevice();
InitOutput();
InitTexture();
InitDesk();
}
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
Logger.Instance.Error(ex);
}
}
private bool RetrieveFrame()
{
SharpDX.DXGI.Resource desktopResource = null;
try
{
public DesktopFrame GetLatestFrame(ScreenReportType screenReportType, float configScale)
Result result = mDeskDupl.TryAcquireNextFrame(100, out frameInfo, out desktopResource);
if (desktopResource == null)
{
uint code = (uint)result.Code;
//超时、GPU繁忙、暂时不可用
if (code == 0x887A0027 || code == 0x887A000A || code == 0x887A0022)
{
//不需操作
}
//复制接口无效,比如切换了桌面
else if (code == 0x887A0026)
{
InitDesk();
}
return false;
}
}
catch (Exception)
{
InitDesk();
return false;
}
using Texture2D tempTexture = desktopResource.QueryInterface<Texture2D>();
mDevice.ImmediateContext.CopySubresourceRegion(tempTexture, 0, null, smallerTexture, 0);
desktopResource.Dispose();
return true;
}
private void RetrieveFrameMetadata(DesktopFrame frame)
{
if (frameInfo.TotalMetadataBufferSize > 0)
{
OutputDuplicateMoveRectangle[] movedRectangles = new OutputDuplicateMoveRectangle[frameInfo.TotalMetadataBufferSize];
mDeskDupl.GetFrameMoveRects(movedRectangles.Length, movedRectangles, out int movedRegionsLength);
//Console.WriteLine($"movedRegionsLength:{movedRegionsLength}");
frame.MovedRegions = new MovedRegion[movedRegionsLength / Marshal.SizeOf(typeof(OutputDuplicateMoveRectangle))];
for (int i = 0; i < frame.MovedRegions.Length; i++)
{
int width = movedRectangles[i].DestinationRect.Right - movedRectangles[i].DestinationRect.Left;
int height = movedRectangles[i].DestinationRect.Bottom - movedRectangles[i].DestinationRect.Top;
frame.MovedRegions[i] = new MovedRegion()
{
Source = new Point(movedRectangles[i].SourcePoint.X, movedRectangles[i].SourcePoint.Y),
Destination = new Rectangle(movedRectangles[i].DestinationRect.Left, movedRectangles[i].DestinationRect.Top, width, height)
};
}
RawRectangle[] dirtyRectangles = new RawRectangle[frameInfo.TotalMetadataBufferSize];
mDeskDupl.GetFrameDirtyRects(dirtyRectangles.Length, dirtyRectangles, out int dirtyRegionsLength);
frame.UpdatedRegions = new Rectangle[dirtyRegionsLength / Marshal.SizeOf(typeof(Rectangle))];
for (int i = 0; i < frame.UpdatedRegions.Length; i++)
{
int width = dirtyRectangles[i].Right - dirtyRectangles[i].Left;
int height = dirtyRectangles[i].Bottom - dirtyRectangles[i].Top;
frame.UpdatedRegions[i] = new Rectangle(dirtyRectangles[i].Left, dirtyRectangles[i].Top, width, height);
}
}
else
{
frame.MovedRegions = new MovedRegion[0];
frame.UpdatedRegions = new Rectangle[0];
}
}
private void ReleaseFrame()
{
try
{
mDeskDupl.ReleaseFrame();
}
catch (SharpDXException ex)
{
if (ex.ResultCode.Failure)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
Logger.Instance.Error("Failed to release frame.");
}
}
}
}
byte[] fullImageBytes = Helper.EmptyArray;
public DesktopFrame GetLatestFullFrame(float configScale)
{
DesktopFrame frame = new DesktopFrame() { FullImage = Helper.EmptyArray, RegionImage = Helper.EmptyArray };
bool retrievalTimedOut = RetrieveFrame(frame, configScale);
if (retrievalTimedOut)
bool success = RetrieveFrame();
if (success == false)
{
return null;
}
@@ -210,19 +342,172 @@ namespace cmonitor.server.client.reports.screen.sharpDX
try
{
RetrieveFrameMetadata(frame);
if (frame.UpdatedRegions.Length > 0 || GdiCapture.IsClip())
{
if (screenReportType == ScreenReportType.Full)
{
ProcessFrameFull(frame, configScale);
}
else if (screenReportType == ScreenReportType.Region)
catch
{
ReleaseFrame();
}
finally
{
try
{
ReleaseFrame();
}
catch
{
}
}
return frame;
}
private unsafe void ProcessFrameFull(DesktopFrame frame, float configScale)
{
if (OperatingSystem.IsWindows())
{
try
{
mDevice.ImmediateContext.GenerateMips(smallerTextureView);
Rect sourceRect = new Rect(smallerTexture.Description.Width, smallerTexture.Description.Height);
Rectangle sourceRectangle = new Rectangle(0, 0, sourceRect.Width, sourceRect.Height);
GetSystemScale(out float scaleX, out float scaleY, out int sourceWidth, out int sourceHeight);
//画布尺寸
GetNewSize(sourceRect, scaleX, scaleY, configScale, out Rect textureRect);
//最终尺寸
Rect distRect = textureRect;
//由于画布只能缩小2次方尺寸需要计算一下
int sourceSubresource = sourceRectangle.Width / textureRect.Width;
if (sourceSubresource >= 0)
{
while (sourceSubresource > 0 && sourceRect.Width / (1 << sourceSubresource) < textureRect.Width)
{
sourceSubresource--;
}
if (sourceSubresource >= 3) sourceSubresource = 3;
textureRect.Width = sourceRect.Width / (1 << sourceSubresource);
textureRect.Height = sourceRect.Height / (1 << sourceSubresource);
}
//拷贝画布
Texture2DDescription desc = desktopImageTexture.Description;
desc.Width = textureRect.Width;
desc.Height = textureRect.Height;
using Texture2D texture = new Texture2D(mDevice, desc);
mDevice.ImmediateContext.CopySubresourceRegion(smallerTexture, sourceSubresource, new ResourceRegion
{
Left = sourceRectangle.X,
Right = sourceRectangle.X + sourceRectangle.Width,
Top = sourceRectangle.Y,
Bottom = sourceRectangle.Y + sourceRectangle.Height,
Back = 1
}, texture, 0, 0, 0);
//拷贝到图像
DataBox mapSource = mDevice.ImmediateContext.MapSubresource(texture, 0, MapMode.Read, MapFlags.None);
using Bitmap image = new Bitmap(desc.Width, desc.Height, PixelFormat.Format32bppArgb);
System.Drawing.Rectangle boundsRect = new System.Drawing.Rectangle(0, 0, desc.Width, desc.Height);
BitmapData mapDest = image.LockBits(boundsRect, ImageLockMode.WriteOnly, image.PixelFormat);
nint sourcePtr = mapSource.DataPointer;
nint destPtr = mapDest.Scan0;
for (int y = 0; y < desc.Height; y++)
{
Utilities.CopyMemory(destPtr, sourcePtr, desc.Width * 4);
sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
destPtr = IntPtr.Add(destPtr, mapDest.Stride);
}
image.UnlockBits(mapDest);
mDevice.ImmediateContext.UnmapSubresource(texture, 0);
//弥补到最终尺寸
Bitmap bmp = image;
if (desc.Width - distRect.Width > 50)
{
bmp = new Bitmap(distRect.Width, distRect.Height);
using Graphics graphic = Graphics.FromImage(bmp);
graphic.DrawImage(image, new System.Drawing.Rectangle(0, 0, distRect.Width, distRect.Height), 0, 0, desc.Width, desc.Height, GraphicsUnit.Pixel);
}
using Graphics g = Graphics.FromImage(bmp);
WinApi.DrawCursorIcon(g, bmp.Width*1.0f/sourceRect.Width, bmp.Height*1.0f/sourceRect.Height);
//转字节数组
using Image image1 = bmp;
using MemoryStream ms = new MemoryStream();
image1.Save(ms, ImageFormat.Jpeg);
ms.Seek(0, SeekOrigin.Begin);
int length = (int)ms.Length;
if (length > fullImageBytes.Length)
{
fullImageBytes = new byte[length];
}
ms.Read(fullImageBytes.AsSpan(0, length));
frame.FullImage = fullImageBytes.AsMemory(0, length);
}
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
Logger.Instance.Error(ex);
}
}
}
}
private bool GetSystemScale(out float x, out float y, out int sourceWidth, out int sourceHeight)
{
x = 1;
y = 1;
sourceWidth = 0;
sourceHeight = 0;
IntPtr hdc = WinApi.GetDC(IntPtr.Zero);
if (hdc != IntPtr.Zero)
{
sourceWidth = WinApi.GetDeviceCaps(hdc, WinApi.DESKTOPHORZRES);
sourceHeight = WinApi.GetDeviceCaps(hdc, WinApi.DESKTOPVERTRES);
int screenWidth = WinApi.GetSystemMetrics(WinApi.SM_CXSCREEN);
int screenHeight = WinApi.GetSystemMetrics(WinApi.SM_CYSCREEN);
x = (sourceWidth * 1.0f / screenWidth);
y = (sourceHeight * 1.0f / screenHeight);
WinApi.ReleaseDC(IntPtr.Zero, hdc);
return true;
}
return false;
}
private bool GetNewSize(Rect sourceRect, float scaleX, float scaleY, float configScale, out Rect rect)
{
int width = (int)(sourceRect.Width * 1.0 / scaleX * configScale);
int height = (int)(sourceRect.Height * 1.0 / scaleY * configScale);
rect = new Rect(width, height);
return true;
}
public DesktopFrame GetLatestRegionFrame(float configScale)
{
DesktopFrame frame = new DesktopFrame() { FullImage = Helper.EmptyArray, RegionImage = Helper.EmptyArray };
bool success = RetrieveFrame();
if (success == false)
{
return null;
}
try
{
RetrieveFrameMetadata(frame);
if (frame.UpdatedRegions.Length > 0)
{
frame.UpdatedRegions = Rectangle.UnionRectangles(frame.UpdatedRegions);
ProcessFrameRegion(frame, configScale);
}
}
}
catch
{
ReleaseFrame();
@@ -240,192 +525,6 @@ namespace cmonitor.server.client.reports.screen.sharpDX
return frame;
}
private bool RetrieveFrame(DesktopFrame frame, float configScale)
{
SharpDX.DXGI.Resource desktopResource = null;
try
{
mDeskDupl.TryAcquireNextFrame(500, out frameInfo, out desktopResource);
if (desktopResource == null)
{
InitCapture(0,0);
return false;
}
}
catch (SharpDXException ex)
{
if (ex.ResultCode.Code == SharpDX.DXGI.ResultCode.WaitTimeout.Result.Code)
{
return true;
}
if (ex.ResultCode.Failure)
{
throw new Exception("Failed to acquire next frame.");
}
}
int sourceWidth = smallerTexture.Description.Width;
int sourceHeight = smallerTexture.Description.Height;
frame.Width = sourceWidth;
frame.Height = sourceHeight;
GdiCapture.GetScale(out float scalex, out float scaley, out int sourceWidth1, out int sourceHeight1);
frame.ScaleX = scalex;
frame.ScaleY = scaley;
GdiCapture.CalcClip(sourceWidth, sourceHeight, out int left, out int top, out int _width, out int _height);
frame.Width = _width;
frame.Height = _height;
using Texture2D tempTexture = desktopResource.QueryInterface<Texture2D>();
mDevice.ImmediateContext.CopySubresourceRegion(tempTexture, 0, new ResourceRegion
{
Left = left,
Top = top,
Right = left + _width,
Bottom = top + _height,
Back = 1
}, smallerTexture, 0);
desktopResource.Dispose();
return false;
}
private void RetrieveFrameMetadata(DesktopFrame frame)
{
if (frameInfo.TotalMetadataBufferSize > 0)
{
/*
OutputDuplicateMoveRectangle[] movedRectangles = new OutputDuplicateMoveRectangle[frameInfo.TotalMetadataBufferSize];
mDeskDupl.GetFrameMoveRects(movedRectangles.Length, movedRectangles, out int movedRegionsLength);
//Console.WriteLine($"movedRegionsLength:{movedRegionsLength}");
frame.MovedRegions = new MovedRegion[movedRegionsLength / Marshal.SizeOf(typeof(OutputDuplicateMoveRectangle))];
for (int i = 0; i < frame.MovedRegions.Length; i++)
{
int width = movedRectangles[i].DestinationRect.Right - movedRectangles[i].DestinationRect.Left;
int height = movedRectangles[i].DestinationRect.Bottom - movedRectangles[i].DestinationRect.Top;
frame.MovedRegions[i] = new MovedRegion()
{
Source = new System.Drawing.Point(movedRectangles[i].SourcePoint.X, movedRectangles[i].SourcePoint.Y),
Destination = new Rectangle(movedRectangles[i].DestinationRect.Left, movedRectangles[i].DestinationRect.Top, width, height)
};
}
*/
RawRectangle[] dirtyRectangles = new RawRectangle[frameInfo.TotalMetadataBufferSize];
mDeskDupl.GetFrameDirtyRects(dirtyRectangles.Length, dirtyRectangles, out int dirtyRegionsLength);
frame.UpdatedRegions = new Rectangle[dirtyRegionsLength / Marshal.SizeOf(typeof(Rectangle))];
for (int i = 0; i < frame.UpdatedRegions.Length; i++)
{
int width = dirtyRectangles[i].Right - dirtyRectangles[i].Left;
int height = dirtyRectangles[i].Bottom - dirtyRectangles[i].Top;
frame.UpdatedRegions[i] = new Rectangle(dirtyRectangles[i].Left, dirtyRectangles[i].Top, width, height);
}
}
else
{
//frame.MovedRegions = new MovedRegion[0];
frame.UpdatedRegions = new Rectangle[0];
}
}
byte[] fullImageBytes = Helper.EmptyArray;
private unsafe void ProcessFrameFull(DesktopFrame frame, float configScale)
{
if (OperatingSystem.IsWindows())
{
try
{
mDevice.ImmediateContext.GenerateMips(smallerTextureView);
GdiCapture.GetNewSize(smallerTexture.Description.Width, smallerTexture.Description.Height, frame.ScaleX, frame.ScaleY, configScale, out int width, out int height);
int sourceSubresource = frame.Width / width;
if (sourceSubresource >= 0)
{
while (sourceSubresource > 0 && smallerTexture.Description.Width / (1 << sourceSubresource) < width)
{
sourceSubresource--;
}
if (sourceSubresource >= 3) sourceSubresource = 3;
frame.Width = smallerTexture.Description.Width / (1 << sourceSubresource);
frame.Height = smallerTexture.Description.Height / (1 << sourceSubresource);
}
mDevice.ImmediateContext.CopySubresourceRegion(smallerTexture, sourceSubresource, new ResourceRegion
{
Left = 0,
Right = frame.Width,
Top = 0,
Bottom = frame.Height,
Back = 1
}, desktopImageTexture, 0);
DataBox mapSource = mDevice.ImmediateContext.MapSubresource(desktopImageTexture, 0, MapMode.Read, MapFlags.None);
using Bitmap image = new Bitmap(frame.Width, frame.Height, PixelFormat.Format32bppArgb);
System.Drawing.Rectangle boundsRect = new System.Drawing.Rectangle(0, 0, frame.Width, frame.Height);
BitmapData mapDest = image.LockBits(boundsRect, ImageLockMode.WriteOnly, image.PixelFormat);
nint sourcePtr = mapSource.DataPointer;
nint destPtr = mapDest.Scan0;
for (int y = 0; y < frame.Height; y++)
{
Utilities.CopyMemory(destPtr, sourcePtr, frame.Width * 4);
sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
destPtr = IntPtr.Add(destPtr, mapDest.Stride);
}
image.UnlockBits(mapDest);
mDevice.ImmediateContext.UnmapSubresource(desktopImageTexture, 0);
Bitmap bmp = image;
if (frame.Width - width > 50)
{
bmp = new Bitmap(width, height);
using Graphics graphic = Graphics.FromImage(bmp);
graphic.DrawImage(image, new System.Drawing.Rectangle(0, 0, width, height), 0, 0, frame.Width, frame.Height, GraphicsUnit.Pixel);
}
using System.Drawing.Image image1 = bmp;
using MemoryStream ms = new MemoryStream();
image1.Save(ms, ImageFormat.Jpeg);
ms.Seek(0, SeekOrigin.Begin);
int length = (int)ms.Length;
if (length > fullImageBytes.Length)
{
fullImageBytes = new byte[length];
}
ms.Read(fullImageBytes.AsSpan(0, length));
frame.FullImage = fullImageBytes.AsMemory(0, length);
}
catch (Exception ex)
{
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
Logger.Instance.Error(ex);
}
desktopImageTexture.Dispose();
desktopImageTexture = new Texture2D(mDevice, new Texture2DDescription()
{
CpuAccessFlags = CpuAccessFlags.Read,
BindFlags = BindFlags.None,
Format = Format.B8G8R8A8_UNorm,
Width = smallerTexture.Description.Width,
Height = smallerTexture.Description.Height,
OptionFlags = ResourceOptionFlags.None,
MipLevels = 1,
ArraySize = 1,
SampleDescription = { Count = 1, Quality = 0 },
Usage = ResourceUsage.Staging
});
}
}
}
byte[] regionImageBytes = Helper.EmptyArray;
private unsafe void ProcessFrameRegion(DesktopFrame frame, float configScale)
{
@@ -547,19 +646,6 @@ namespace cmonitor.server.client.reports.screen.sharpDX
}
}
private void ReleaseFrame()
{
try
{
mDeskDupl.ReleaseFrame();
}
catch (SharpDXException ex)
{
if (ex.ResultCode.Failure)
{
throw new Exception("Failed to release frame.");
}
}
}
}
}

View File

@@ -1,140 +0,0 @@
using System.Buffers;
using System.Drawing;
using System.Runtime.InteropServices;
namespace cmonitor.server.client.reports.screen
{
public sealed class GdiCapture
{
static ScreenClipInfo screenClipInfo = new ScreenClipInfo { X = 0, Y = 0, Scale = 1 };
public static void Clip(ScreenClipInfo _screenClipInfo)
{
screenClipInfo = _screenClipInfo;
}
public static bool IsClip()
{
return screenClipInfo.Scale != 0;
}
public static void CalcClip(int sourceWidth, int sourceHeight, out int left, out int top, out int width, out int height)
{
CalcClip(sourceWidth, sourceHeight, screenClipInfo.X, screenClipInfo.Y, screenClipInfo.Scale, out left, out top, out width, out height);
}
public static void CalcClip(int sourceWidth, int sourceHeight,int x,int y,float scale, out int left, out int top, out int width, out int height)
{
//缩放后宽高
int newSourceWidth = (int)(sourceWidth * screenClipInfo.Scale);
int newSourceHeight = (int)(sourceHeight * screenClipInfo.Scale);
//减去的宽高
int clipWidth = (int)((newSourceWidth - sourceWidth) * 1.0 / newSourceWidth * sourceWidth);
int clipHeight = (int)((newSourceHeight - sourceHeight) * 1.0 / newSourceHeight * sourceHeight);
//留下的宽高
width = sourceWidth - clipWidth;
height = sourceHeight - clipHeight;
float scaleX = screenClipInfo.X * 1.0f / sourceWidth;
float scaleY = screenClipInfo.Y * 1.0f / sourceHeight;
left = (int)(clipWidth * scaleX);
top = (int)(clipHeight * scaleY);
}
public static void Return(byte[] bytes)
{
ArrayPool<byte>.Shared.Return(bytes);
}
public static bool GetScale(out float x, out float y, out int sourceWidth, out int sourceHeight)
{
x = 1;
y = 1;
sourceWidth = 0;
sourceHeight = 0;
IntPtr hdc = GetDC(IntPtr.Zero);
if (hdc != IntPtr.Zero)
{
sourceWidth = GetDeviceCaps(hdc, DESKTOPHORZRES);
sourceHeight = GetDeviceCaps(hdc, DESKTOPVERTRES);
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
x = (sourceWidth * 1.0f / screenWidth);
y = (sourceHeight * 1.0f / screenHeight);
ReleaseDC(IntPtr.Zero, hdc);
return true;
}
return false;
}
public static bool GetNewSize(int sourceWidth, int sourceHeight, float scaleX, float scaleY, float configScale, out int width, out int height)
{
width = (int)(sourceWidth * 1.0 / scaleX * configScale);
height = (int)(sourceHeight * 1.0 / scaleY * configScale);
return true;
}
public static void DrawCursorIcon(Graphics g, int sourceWidth, int scaleX, int scaleY, float configScale)
{
if (OperatingSystem.IsWindows())
{
int curWidth = (int)(sourceWidth * configScale * configScale);
CURSORINFO pci;
pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
if (GetCursorInfo(out pci))
{
if (pci.flags == CURSOR_SHOWING)
{
var hdc1 = g.GetHdc();
DrawIconEx(hdc1, pci.ptScreenPos.x * scaleX, pci.ptScreenPos.y * scaleY, pci.hCursor, curWidth, curWidth, 0, IntPtr.Zero, DI_NORMAL);
g.ReleaseHdc();
}
}
}
}
private const int DESKTOPVERTRES = 117;
private const int DESKTOPHORZRES = 118;
private const int SM_CXSCREEN = 0;
private const int SM_CYSCREEN = 1;
[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr ptr);
[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
[DllImport("gdi32.dll", EntryPoint = "GetDeviceCaps", SetLastError = true)]
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
[DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
private static extern int GetSystemMetrics(int mVal);
[StructLayout(LayoutKind.Sequential)]
private struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public POINTAPI ptScreenPos;
}
[StructLayout(LayoutKind.Sequential)]
private struct POINTAPI
{
public int x;
public int y;
}
private const Int32 CURSOR_SHOWING = 0x0001;
private const Int32 DI_NORMAL = 0x0003;
[DllImport("user32.dll")]
private static extern bool GetCursorInfo(out CURSORINFO pci);
[DllImport("user32.dll", SetLastError = true)]
static extern bool DrawIconEx(IntPtr hdc, int xLeft, int yTop, IntPtr hIcon, int cxWidth, int cyHeight, int istepIfAniCur, IntPtr hbrFlickerFreeDraw, int diFlags);
}
}

View File

@@ -0,0 +1,136 @@
using System.Drawing.Imaging;
using System.Drawing;
using common.libs;
namespace cmonitor.server.client.reports.screen
{
public sealed class GdiDesktop
{
public GdiDesktop() { }
ScreenClipInfo screenClipInfo = new ScreenClipInfo { X = 0, Y = 0, Scale = 1 };
public void Clip(ScreenClipInfo _screenClipInfo)
{
screenClipInfo = _screenClipInfo;
}
public bool IsClip()
{
return screenClipInfo.Scale != 1;
}
public bool IsLockScreen()
{
return WinApi.Locked();
}
byte[] fullImageBytes = new byte[0];
public DesktopFrame GetLatestFrame(float configScale)
{
DesktopFrame frame = new DesktopFrame { FullImage = Helper.EmptyArray, MovedRegions = new MovedRegion[0], RegionImage = Helper.EmptyArray, UpdatedRegions = new Rectangle[0] };
if (OperatingSystem.IsWindows())
{
IntPtr hdc = WinApi.GetDC(IntPtr.Zero);
if (hdc == IntPtr.Zero) return frame;
GetSystemScale(out float scaleX, out float scaleY, out int sourceWidth, out int sourceHeight);
Rect sourceRect = new Rect(sourceWidth, sourceHeight);
CalcClip(sourceRect, out Rectangle clipRectangle);
GetNewSize(sourceRect, scaleX, scaleY, configScale, out Rect distRect);
using Bitmap image = new Bitmap(clipRectangle.Width, clipRectangle.Height);
using (Graphics g = Graphics.FromImage(image))
{
g.CopyFromScreen(clipRectangle.X, clipRectangle.Y, 0, 0, image.Size, CopyPixelOperation.SourceCopy);
g.Dispose();
}
WinApi.ReleaseDC(IntPtr.Zero, hdc);
Bitmap bmp = image;
if (clipRectangle.Width - distRect.Width > 50)
{
bmp = new Bitmap(distRect.Width, distRect.Height);
using Graphics graphic = Graphics.FromImage(bmp);
graphic.DrawImage(image, new System.Drawing.Rectangle(0, 0, distRect.Width, distRect.Height), 0, 0, clipRectangle.Width, clipRectangle.Height, GraphicsUnit.Pixel);
}
using Image image1 = bmp;
using MemoryStream ms = new MemoryStream();
image1.Save(ms, ImageFormat.Jpeg);
ms.Seek(0, SeekOrigin.Begin);
int length = (int)ms.Length;
if (length > fullImageBytes.Length)
{
fullImageBytes = new byte[length];
}
ms.Read(fullImageBytes.AsSpan(0, length));
frame.FullImage = fullImageBytes.AsMemory(0, length);
}
return frame;
}
private void CalcClip(Rect sourceRect, out Rectangle rectangle)
{
Scale scale = new Scale(screenClipInfo.X, screenClipInfo.Y, screenClipInfo.Scale);
CalcClip(sourceRect, scale, out rectangle);
}
private void CalcClip(Rect sourceRect, Scale scale, out Rectangle rectangle)
{
//缩放后宽高
int newSourceWidth = (int)(sourceRect.Width * scale.Value);
int newSourceHeight = (int)(sourceRect.Height * scale.Value);
//减去的宽高
int clipWidth = (int)((newSourceWidth - sourceRect.Width) * 1.0 / newSourceWidth * sourceRect.Width);
int clipHeight = (int)((newSourceHeight - sourceRect.Height) * 1.0 / newSourceHeight * sourceRect.Height);
//留下的宽高
int width = sourceRect.Width - clipWidth;
int height = sourceRect.Height - clipHeight;
float scaleX = scale.X * 1.0f / sourceRect.Width;
float scaleY = scale.Y * 1.0f / sourceRect.Height;
int left = (int)(clipWidth * scaleX);
int top = (int)(clipHeight * scaleY);
rectangle = new Rectangle(left, top, width, height);
}
private bool GetSystemScale(out float x, out float y, out int sourceWidth, out int sourceHeight)
{
x = 1;
y = 1;
sourceWidth = 0;
sourceHeight = 0;
IntPtr hdc = WinApi.GetDC(IntPtr.Zero);
if (hdc != IntPtr.Zero)
{
sourceWidth = WinApi.GetDeviceCaps(hdc, WinApi.DESKTOPHORZRES);
sourceHeight = WinApi.GetDeviceCaps(hdc, WinApi.DESKTOPVERTRES);
int screenWidth = WinApi.GetSystemMetrics(WinApi.SM_CXSCREEN);
int screenHeight = WinApi.GetSystemMetrics(WinApi.SM_CYSCREEN);
x = (sourceWidth * 1.0f / screenWidth);
y = (sourceHeight * 1.0f / screenHeight);
WinApi.ReleaseDC(IntPtr.Zero, hdc);
return true;
}
return false;
}
private bool GetNewSize(Rect sourceRect, float scaleX, float scaleY, float configScale, out Rect rect)
{
int width = (int)(sourceRect.Width * 1.0 / scaleX * configScale);
int height = (int)(sourceRect.Height * 1.0 / scaleY * configScale);
rect = new Rect(width, height);
return true;
}
}
}

View File

@@ -1,9 +1,7 @@
using cmonitor.server.service;
using common.libs;
using cmonitor.server.service.messengers.screen;
using System.Runtime.InteropServices;
using MemoryPack;
using cmonitor.server.client.reports.screen.sharpDX;
using System.Diagnostics;
namespace cmonitor.server.client.reports.screen
@@ -18,7 +16,8 @@ namespace cmonitor.server.client.reports.screen
private ScreenReportInfo report = new ScreenReportInfo();
private uint lastInput;
private readonly DesktopDuplicator desktopDuplicator;
private readonly DxgiDesktop dxgiDesktop;
private readonly GdiDesktop gdiDesktop;
public ScreenReport(ClientSignInState clientSignInState, MessengerSender messengerSender, Config config)
{
@@ -28,13 +27,15 @@ namespace cmonitor.server.client.reports.screen
if (config.IsCLient)
{
ScreenCaptureTask();
InitLastInputInfo();
WinApi.InitLastInputInfo();
dxgiDesktop = new DxgiDesktop(0);
gdiDesktop = new GdiDesktop();
}
desktopDuplicator = new DesktopDuplicator(0);
}
public object GetReports()
public object GetReports(ReportType reportType)
{
report.LT = GetLastInputInfo();
report.LT = WinApi.GetLastInputInfo();
if (report.LT < lastInput || report.LT - lastInput > 1000)
{
lastInput = report.LT;
@@ -44,7 +45,6 @@ namespace cmonitor.server.client.reports.screen
}
#region
private ScreenReportType screenReportType = ScreenReportType.None;
private long ticks = 0;
public void Full()
@@ -54,7 +54,9 @@ namespace cmonitor.server.client.reports.screen
}
public void Clip(ScreenClipInfo screenClipInfo)
{
GdiCapture.Clip(screenClipInfo);
ticks = DateTime.UtcNow.Ticks;
screenReportType = ScreenReportType.Full;
gdiDesktop.Clip(screenClipInfo);
}
public void Region()
{
@@ -73,10 +75,7 @@ namespace cmonitor.server.client.reports.screen
while (true)
{
int delayms = 0;
bool res = clientSignInState.Connected == true
&& screenReportType > ScreenReportType.None
&& (DateTime.UtcNow.Ticks - ticks) / TimeSpan.TicksPerMillisecond < 1000;
if (res)
if (clientSignInState.Connected == true && ((DateTime.UtcNow.Ticks - ticks) / TimeSpan.TicksPerMillisecond < 1000))
{
try
{
@@ -102,12 +101,25 @@ namespace cmonitor.server.client.reports.screen
}, TaskCreationOptions.LongRunning);
}
private async Task SendScreenCapture()
{
DesktopFrame frame = null;
if (gdiDesktop.IsClip()/*|| gdiDesktop.IsLockScreen()*/)
{
frame = gdiDesktop.GetLatestFrame(config.ScreenScale);
}
else if (screenReportType == ScreenReportType.Full)
{
//var sw = new Stopwatch();
//sw.Start();
DesktopFrame frame = desktopDuplicator.GetLatestFrame(screenReportType, config.ScreenScale);
frame = dxgiDesktop.GetLatestFullFrame(config.ScreenScale);
//sw.Stop();
// Console.WriteLine($"{frame.FullImage.Length}->{sw.ElapsedMilliseconds}");
//Console.WriteLine(sw.ElapsedMilliseconds);
}
else if (screenReportType == ScreenReportType.Region)
{
frame = dxgiDesktop.GetLatestRegionFrame(config.ScreenScale);
}
if (frame != null)
{
if (frame.FullImage.Length > 0)
@@ -128,47 +140,18 @@ namespace cmonitor.server.client.reports.screen
Payload = frame.RegionImage,
});
}
/*
if (frame.Updateds.Length > 0)
if (frame.UpdatedRegions.Length > 0)
{
await messengerSender.SendOnly(new MessageRequestWrap
{
Connection = clientSignInState.Connection,
MessengerId = (ushort)ScreenMessengerIds.Rectangles,
Payload = MemoryPackSerializer.Serialize(frame.Updateds),
Payload = MemoryPackSerializer.Serialize(frame.UpdatedRegions),
});
}
*/
}
}
#endregion
#region
private LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
private void InitLastInputInfo()
{
lastInputInfo.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));
}
private uint GetLastInputInfo()
{
bool res = GetLastInputInfo(ref lastInputInfo);
if (res)
{
return (uint)Environment.TickCount - lastInputInfo.dwTime;
}
return 0;
}
[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
[StructLayout(LayoutKind.Sequential)]
struct LASTINPUTINFO
{
public uint cbSize;
public uint dwTime;
}
#endregion
}
public sealed class ScreenReportInfo

View File

@@ -0,0 +1,204 @@
using System.Drawing;
using System.Runtime.InteropServices;
namespace cmonitor.server.client.reports.screen
{
public sealed class WinApi
{
public static void DrawCursorIcon(Graphics g, int sourceWidth, float scaleX, float scaleY, float configScale)
{
if (OperatingSystem.IsWindows())
{
int curWidth = (int)(sourceWidth * configScale * configScale);
CURSORINFO pci;
pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
if (GetCursorInfo(out pci))
{
if (pci.flags == CURSOR_SHOWING)
{
var hdc1 = g.GetHdc();
DrawIconEx(hdc1, (int)(pci.ptScreenPos.x * scaleX), (int)(pci.ptScreenPos.y * scaleY), pci.hCursor, curWidth, curWidth, 0, IntPtr.Zero, DI_NORMAL);
g.ReleaseHdc();
}
}
}
}
public static void DrawCursorIcon(Graphics g, float scaleX, float scaleY)
{
if (OperatingSystem.IsWindows())
{
CURSORINFO pci;
pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));
if (GetCursorInfo(out pci))
{
if (pci.flags == CURSOR_SHOWING)
{
using System.Drawing.Icon icon = System.Drawing.Icon.FromHandle(pci.hCursor);
g.DrawIcon(icon, new System.Drawing.Rectangle(new Point((int)(pci.ptScreenPos.x * scaleX), (int)(pci.ptScreenPos.y * scaleY)), icon.Size));
}
}
}
}
[StructLayout(LayoutKind.Sequential)]
private struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public POINTAPI ptScreenPos;
}
[StructLayout(LayoutKind.Sequential)]
private struct POINTAPI
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
public struct IconInfo
{
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
private const Int32 CURSOR_SHOWING = 0x0001;
private const Int32 DI_NORMAL = 0x0003;
[DllImport("user32.dll")]
private static extern bool GetCursorInfo(out CURSORINFO pci);
[DllImport("user32.dll")]
public static extern bool GetIconInfo(IntPtr hIcon, out IconInfo piconinfo);
[DllImport("user32.dll", SetLastError = true)]
static extern bool DrawIconEx(IntPtr hdc, int xLeft, int yTop, IntPtr hIcon, int cxWidth, int cyHeight, int istepIfAniCur, IntPtr hbrFlickerFreeDraw, int diFlags);
public const int DESKTOPVERTRES = 117;
public const int DESKTOPHORZRES = 118;
public const int SM_CXSCREEN = 0;
public const int SM_CYSCREEN = 1;
public const int SM_REMOTESESSION = 0x1000;
[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr ptr);
[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
[DllImport("gdi32.dll", EntryPoint = "GetDeviceCaps", SetLastError = true)]
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
[DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
public static extern int GetSystemMetrics(int mVal);
#region
private static LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
public static void InitLastInputInfo()
{
lastInputInfo.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO));
}
public static uint GetLastInputInfo()
{
bool res = GetLastInputInfo(ref lastInputInfo);
if (res)
{
return (uint)Environment.TickCount - lastInputInfo.dwTime;
}
return 0;
}
[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
[StructLayout(LayoutKind.Sequential)]
struct LASTINPUTINFO
{
public uint cbSize;
public uint dwTime;
}
#endregion
[DllImport("wtsapi32.dll")]
static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out IntPtr ppBuffer, out uint pBytesReturned);
[DllImport("wtsapi32.dll")]
static extern void WTSFreeMemory(IntPtr pMemory);
[StructLayout(LayoutKind.Sequential)]
struct WTSINFO
{
public int SessionId;
public int WinStationNameLen;
public string WinStationName;
public int State;
}
enum WTS_INFO_CLASS
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType,
WTSIdleTime,
WTSLogonTime,
WTSIncomingBytes,
WTSOutgoingBytes,
WTSIncomingFrames,
WTSOutgoingFrames,
WTSClientInfo,
WTSSessionInfo,
WTSConfigInfo,
WTSShadowInfo,
WTSValidConnectionTypes,
WTSRemoteAddressV4,
WTSRemoteAddressV6,
WTSIsRemoteSession
}
public static bool Locked()
{
IntPtr buffer = IntPtr.Zero;
uint bytesReturned = 0;
try
{
bool result = WTSQuerySessionInformation(IntPtr.Zero, -1, WTS_INFO_CLASS.WTSSessionInfo, out buffer, out bytesReturned);
if (result)
{
WTSINFO sessionInfo = (WTSINFO)Marshal.PtrToStructure(buffer, typeof(WTSINFO));
return sessionInfo.State == 0;
}
}
catch (Exception)
{
}
finally
{
if (buffer != IntPtr.Zero)
{
WTSFreeMemory(buffer);
}
}
return false;
}
}
}

View File

@@ -1,34 +0,0 @@
using System.Drawing;
namespace cmonitor.server.client.reports.screen.aforge
{
public abstract class BaseResizeFilter : BaseTransformationFilter
{
protected int newWidth;
protected int newHeight;
public int NewWidth
{
get { return newWidth; }
set { newWidth = Math.Max( 1, value ); }
}
public int NewHeight
{
get { return newHeight; }
set { newHeight = Math.Max( 1, value ); }
}
protected BaseResizeFilter( int newWidth, int newHeight )
{
this.newWidth = newWidth;
this.newHeight = newHeight;
}
protected override Size CalculateNewImageSize()
{
return new Size( newWidth, newHeight );
}
}
}

View File

@@ -1,124 +0,0 @@
using System.Drawing;
using System.Drawing.Imaging;
namespace cmonitor.server.client.reports.screen.aforge
{
public abstract class BaseTransformationFilter
{
public abstract Dictionary<PixelFormat, PixelFormat> FormatTranslations { get; }
public Bitmap Apply(Bitmap image,int x,int y,int width,int height)
{
if (OperatingSystem.IsWindows())
{
BitmapData srcData = image.LockBits(
new Rectangle(x, y, width, height),
ImageLockMode.ReadOnly, image.PixelFormat);
Bitmap dstImage = null;
try
{
dstImage = Apply(srcData);
if ((image.HorizontalResolution > 0) && (image.VerticalResolution > 0))
{
dstImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
}
}
finally
{
image.UnlockBits(srcData);
}
return dstImage;
}
return null;
}
public Bitmap Apply(BitmapData imageData)
{
if (OperatingSystem.IsWindows())
{
CheckSourceFormat(imageData.PixelFormat);
PixelFormat dstPixelFormat = FormatTranslations[imageData.PixelFormat];
Size newSize = CalculateNewImageSize();
Bitmap dstImage = (dstPixelFormat == PixelFormat.Format8bppIndexed) ?
cmonitor.server.client.reports.screen.aforge.Image.CreateGrayscaleImage(newSize.Width, newSize.Height) :
new Bitmap(newSize.Width, newSize.Height, dstPixelFormat);
BitmapData dstData = dstImage.LockBits(
new Rectangle(0, 0, newSize.Width, newSize.Height),
ImageLockMode.ReadWrite, dstPixelFormat);
try
{
ProcessFilter(new UnmanagedImage(imageData), new UnmanagedImage(dstData));
}
finally
{
dstImage.UnlockBits(dstData);
}
return dstImage;
}
return null;
}
public UnmanagedImage Apply(UnmanagedImage image)
{
if (OperatingSystem.IsWindows())
{
CheckSourceFormat(image.PixelFormat);
Size newSize = CalculateNewImageSize();
UnmanagedImage dstImage = UnmanagedImage.Create(newSize.Width, newSize.Height, FormatTranslations[image.PixelFormat]);
ProcessFilter(image, dstImage);
return dstImage;
}
return null;
}
public void Apply(UnmanagedImage sourceImage, UnmanagedImage destinationImage)
{
if (OperatingSystem.IsWindows())
{
CheckSourceFormat(sourceImage.PixelFormat);
if (destinationImage.PixelFormat != FormatTranslations[sourceImage.PixelFormat])
{
throw new Exception("Destination pixel format is specified incorrectly.");
}
Size newSize = CalculateNewImageSize();
if ((destinationImage.Width != newSize.Width) || (destinationImage.Height != newSize.Height))
{
throw new Exception("Destination image must have the size expected by the filter.");
}
ProcessFilter(sourceImage, destinationImage);
}
}
protected abstract System.Drawing.Size CalculateNewImageSize();
protected abstract unsafe void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData);
private void CheckSourceFormat(PixelFormat pixelFormat)
{
if (OperatingSystem.IsWindows())
{
if (!FormatTranslations.ContainsKey(pixelFormat))
throw new Exception("Source pixel format is not supported by the filter.");
}
}
}
}

View File

@@ -1,253 +0,0 @@
using System;
using System.Drawing;
namespace cmonitor.server.client.reports.screen.aforge
{
public class RGB
{
public const short R = 2;
public const short G = 1;
public const short B = 0;
public const short A = 3;
public byte Red;
public byte Green;
public byte Blue;
public byte Alpha;
public System.Drawing.Color Color
{
get { return Color.FromArgb( Alpha, Red, Green, Blue ); }
set
{
Red = value.R;
Green = value.G;
Blue = value.B;
Alpha = value.A;
}
}
public RGB( )
{
Red = 0;
Green = 0;
Blue = 0;
Alpha = 255;
}
public RGB( byte red, byte green, byte blue )
{
this.Red = red;
this.Green = green;
this.Blue = blue;
this.Alpha = 255;
}
public RGB( byte red, byte green, byte blue, byte alpha )
{
this.Red = red;
this.Green = green;
this.Blue = blue;
this.Alpha = alpha;
}
public RGB( System.Drawing.Color color )
{
this.Red = color.R;
this.Green = color.G;
this.Blue = color.B;
this.Alpha = color.A;
}
}
public class HSL
{
public int Hue;
public float Saturation;
public float Luminance;
public HSL( ) { }
public HSL( int hue, float saturation, float luminance )
{
this.Hue = hue;
this.Saturation = saturation;
this.Luminance = luminance;
}
public static void FromRGB( RGB rgb, HSL hsl )
{
float r = ( rgb.Red / 255.0f );
float g = ( rgb.Green / 255.0f );
float b = ( rgb.Blue / 255.0f );
float min = Math.Min( Math.Min( r, g ), b );
float max = Math.Max( Math.Max( r, g ), b );
float delta = max - min;
// get luminance value
hsl.Luminance = ( max + min ) / 2;
if ( delta == 0 )
{
// gray color
hsl.Hue = 0;
hsl.Saturation = 0.0f;
}
else
{
// get saturation value
hsl.Saturation = ( hsl.Luminance <= 0.5 ) ? ( delta / ( max + min ) ) : ( delta / ( 2 - max - min ) );
// get hue value
float hue;
if ( r == max )
{
hue = ( ( g - b ) / 6 ) / delta;
}
else if ( g == max )
{
hue = ( 1.0f / 3 ) + ( ( b - r ) / 6 ) / delta;
}
else
{
hue = ( 2.0f / 3 ) + ( ( r - g ) / 6 ) / delta;
}
// correct hue if needed
if ( hue < 0 )
hue += 1;
if ( hue > 1 )
hue -= 1;
hsl.Hue = (int) ( hue * 360 );
}
}
public static HSL FromRGB( RGB rgb )
{
HSL hsl = new HSL( );
FromRGB( rgb, hsl );
return hsl;
}
public static void ToRGB( HSL hsl, RGB rgb )
{
if ( hsl.Saturation == 0 )
{
// gray values
rgb.Red = rgb.Green = rgb.Blue = (byte) ( hsl.Luminance * 255 );
}
else
{
float v1, v2;
float hue = (float) hsl.Hue / 360;
v2 = ( hsl.Luminance < 0.5 ) ?
( hsl.Luminance * ( 1 + hsl.Saturation ) ) :
( ( hsl.Luminance + hsl.Saturation ) - ( hsl.Luminance * hsl.Saturation ) );
v1 = 2 * hsl.Luminance - v2;
rgb.Red = (byte) ( 255 * Hue_2_RGB( v1, v2, hue + ( 1.0f / 3 ) ) );
rgb.Green = (byte) ( 255 * Hue_2_RGB( v1, v2, hue ) );
rgb.Blue = (byte) ( 255 * Hue_2_RGB( v1, v2, hue - ( 1.0f / 3 ) ) );
}
rgb.Alpha = 255;
}
public RGB ToRGB( )
{
RGB rgb = new RGB( );
ToRGB( this, rgb );
return rgb;
}
#region Private members
// HSL to RGB helper routine
private static float Hue_2_RGB( float v1, float v2, float vH )
{
if ( vH < 0 )
vH += 1;
if ( vH > 1 )
vH -= 1;
if ( ( 6 * vH ) < 1 )
return ( v1 + ( v2 - v1 ) * 6 * vH );
if ( ( 2 * vH ) < 1 )
return v2;
if ( ( 3 * vH ) < 2 )
return ( v1 + ( v2 - v1 ) * ( ( 2.0f / 3 ) - vH ) * 6 );
return v1;
}
#endregion
}
public class YCbCr
{
public const short YIndex = 0;
public const short CbIndex = 1;
public const short CrIndex = 2;
public float Y;
public float Cb;
public float Cr;
public YCbCr( ) { }
public YCbCr( float y, float cb, float cr )
{
this.Y = Math.Max( 0.0f, Math.Min( 1.0f, y ) );
this.Cb = Math.Max( -0.5f, Math.Min( 0.5f, cb ) );
this.Cr = Math.Max( -0.5f, Math.Min( 0.5f, cr ) );
}
public static void FromRGB( RGB rgb, YCbCr ycbcr )
{
float r = (float) rgb.Red / 255;
float g = (float) rgb.Green / 255;
float b = (float) rgb.Blue / 255;
ycbcr.Y = (float) ( 0.2989 * r + 0.5866 * g + 0.1145 * b );
ycbcr.Cb = (float) ( -0.1687 * r - 0.3313 * g + 0.5000 * b );
ycbcr.Cr = (float) ( 0.5000 * r - 0.4184 * g - 0.0816 * b );
}
public static YCbCr FromRGB( RGB rgb )
{
YCbCr ycbcr = new YCbCr( );
FromRGB( rgb, ycbcr );
return ycbcr;
}
public static void ToRGB( YCbCr ycbcr, RGB rgb )
{
// don't warry about zeros. compiler will remove them
float r = Math.Max( 0.0f, Math.Min( 1.0f, (float) ( ycbcr.Y + 0.0000 * ycbcr.Cb + 1.4022 * ycbcr.Cr ) ) );
float g = Math.Max( 0.0f, Math.Min( 1.0f, (float) ( ycbcr.Y - 0.3456 * ycbcr.Cb - 0.7145 * ycbcr.Cr ) ) );
float b = Math.Max( 0.0f, Math.Min( 1.0f, (float) ( ycbcr.Y + 1.7710 * ycbcr.Cb + 0.0000 * ycbcr.Cr ) ) );
rgb.Red = (byte) ( r * 255 );
rgb.Green = (byte) ( g * 255 );
rgb.Blue = (byte) ( b * 255 );
rgb.Alpha = 255;
}
public RGB ToRGB( )
{
RGB rgb = new RGB( );
ToRGB( this, rgb );
return rgb;
}
}
}

View File

@@ -1,50 +0,0 @@
using System;
namespace cmonitor.server.client.reports.screen.aforge
{
[Serializable]
public struct DoublePoint
{
public double X;
public double Y;
public DoublePoint( double x, double y )
{
this.X = x;
this.Y = y;
}
public static bool operator ==( DoublePoint point1, DoublePoint point2 )
{
return ( ( point1.X == point2.X ) && ( point1.Y == point2.Y ) );
}
public static bool operator !=( DoublePoint point1, DoublePoint point2 )
{
return ( ( point1.X != point2.X ) || ( point1.Y != point2.Y ) );
}
public override bool Equals( object obj )
{
return ( obj is DoublePoint ) ? ( this == (DoublePoint) obj ) : false;
}
public override int GetHashCode( )
{
return X.GetHashCode( ) + Y.GetHashCode( );
}
public static explicit operator IntPoint( DoublePoint point )
{
return new IntPoint( (int) point.X, (int) point.Y );
}
public static explicit operator Point( DoublePoint point )
{
return new Point( (float) point.X, (float) point.Y );
}
}
}

View File

@@ -1,65 +0,0 @@
using System.Drawing;
using System.Drawing.Imaging;
namespace cmonitor.server.client.reports.screen.aforge
{
public static class Image
{
public static bool IsGrayscale(Bitmap image)
{
bool ret = false;
if (OperatingSystem.IsWindows())
{
if (image.PixelFormat == PixelFormat.Format8bppIndexed)
{
ret = true;
ColorPalette cp = image.Palette;
Color c;
for (int i = 0; i < 256; i++)
{
c = cp.Entries[i];
if ((c.R != i) || (c.G != i) || (c.B != i))
{
ret = false;
break;
}
}
}
}
return ret;
}
public static Bitmap CreateGrayscaleImage(int width, int height)
{
if (OperatingSystem.IsWindows())
{
Bitmap image = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
SetGrayscalePalette(image);
return image;
}
return null;
}
public static void SetGrayscalePalette(Bitmap image)
{
if (OperatingSystem.IsWindows())
{
if (image.PixelFormat != PixelFormat.Format8bppIndexed)
throw new Exception("Source image is not 8 bpp image.");
ColorPalette cp = image.Palette;
for (int i = 0; i < 256; i++)
{
cp.Entries[i] = Color.FromArgb(i, i, i);
}
image.Palette = cp;
}
}
public static int GetPixelFormatSize(PixelFormat pixfmt)
{
return ((int)pixfmt >> 8) & 0xFF;
}
}
}

View File

@@ -1,30 +0,0 @@
using System.Drawing;
namespace cmonitor.server.client.reports.screen.aforge
{
[Serializable]
public struct IntPoint
{
public int X;
public int Y;
public IntPoint(int x, int y)
{
this.X = x;
this.Y = y;
}
public static implicit operator Point(IntPoint point)
{
return new Point(point.X, point.Y);
}
public static implicit operator DoublePoint(IntPoint point)
{
return new DoublePoint(point.X, point.Y);
}
}
}

View File

@@ -1,139 +0,0 @@
using System;
namespace cmonitor.server.client.reports.screen.aforge
{
[Serializable]
public struct Point
{
public float X;
public float Y;
public Point( float x, float y )
{
this.X = x;
this.Y = y;
}
public float DistanceTo( Point anotherPoint )
{
float dx = X - anotherPoint.X;
float dy = Y - anotherPoint.Y;
return (float) System.Math.Sqrt( dx * dx + dy * dy );
}
public float SquaredDistanceTo( Point anotherPoint )
{
float dx = X - anotherPoint.X;
float dy = Y - anotherPoint.Y;
return dx * dx + dy * dy;
}
public static Point operator +( Point point1, Point point2 )
{
return new Point( point1.X + point2.X, point1.Y + point2.Y );
}
public static Point Add( Point point1, Point point2 )
{
return new Point( point1.X + point2.X, point1.Y + point2.Y );
}
public static Point operator -( Point point1, Point point2 )
{
return new Point( point1.X - point2.X, point1.Y - point2.Y );
}
public static Point Subtract( Point point1, Point point2 )
{
return new Point( point1.X - point2.X, point1.Y - point2.Y );
}
public static Point operator +( Point point, float valueToAdd )
{
return new Point( point.X + valueToAdd, point.Y + valueToAdd );
}
public static Point Add( Point point, float valueToAdd )
{
return new Point( point.X + valueToAdd, point.Y + valueToAdd );
}
public static Point operator -( Point point, float valueToSubtract )
{
return new Point( point.X - valueToSubtract, point.Y - valueToSubtract );
}
public static Point Subtract( Point point, float valueToSubtract )
{
return new Point( point.X - valueToSubtract, point.Y - valueToSubtract );
}
public static Point operator *( Point point, float factor )
{
return new Point( point.X * factor, point.Y * factor );
}
public static Point Multiply( Point point, float factor )
{
return new Point( point.X * factor, point.Y * factor );
}
public static Point operator /( Point point, float factor )
{
return new Point( point.X / factor, point.Y / factor );
}
public static Point Divide( Point point, float factor )
{
return new Point( point.X / factor, point.Y / factor );
}
public static bool operator ==( Point point1, Point point2 )
{
return ( ( point1.X == point2.X ) && ( point1.Y == point2.Y ) );
}
public static bool operator !=( Point point1, Point point2 )
{
return ( ( point1.X != point2.X ) || ( point1.Y != point2.Y ) );
}
public override bool Equals( object obj )
{
return ( obj is Point ) ? ( this == (Point) obj ) : false;
}
public override int GetHashCode( )
{
return X.GetHashCode( ) + Y.GetHashCode( );
}
public static explicit operator IntPoint( Point point )
{
return new IntPoint( (int) point.X, (int) point.Y );
}
public static implicit operator DoublePoint( Point point )
{
return new DoublePoint( point.X, point.Y );
}
public IntPoint Round( )
{
return new IntPoint( (int) Math.Round( X ), (int) Math.Round( Y ) );
}
public override string ToString( )
{
return string.Format( System.Globalization.CultureInfo.InvariantCulture, "{0}, {1}", X, Y );
}
public float EuclideanNorm( )
{
return (float) System.Math.Sqrt( X * X + Y * Y );
}
}
}

View File

@@ -1,98 +0,0 @@
using System.Drawing.Imaging;
namespace cmonitor.server.client.reports.screen.aforge
{
public class ResizeBilinear : BaseResizeFilter
{
private Dictionary<PixelFormat, PixelFormat> formatTranslations;
public override Dictionary<PixelFormat, PixelFormat> FormatTranslations
{
get { return formatTranslations; }
}
public ResizeBilinear( int newWidth, int newHeight ) :
base( newWidth, newHeight )
{
if (OperatingSystem.IsWindows())
{
formatTranslations = new Dictionary<PixelFormat, PixelFormat>();
formatTranslations[PixelFormat.Format8bppIndexed] = PixelFormat.Format8bppIndexed;
formatTranslations[PixelFormat.Format24bppRgb] = PixelFormat.Format24bppRgb;
formatTranslations[PixelFormat.Format32bppRgb] = PixelFormat.Format32bppRgb;
formatTranslations[PixelFormat.Format32bppArgb] = PixelFormat.Format32bppArgb;
}
}
protected override unsafe void ProcessFilter( UnmanagedImage sourceData, UnmanagedImage destinationData )
{
if (OperatingSystem.IsWindows())
{
// get source image size
int width = sourceData.Width;
int height = sourceData.Height;
int pixelSize = System.Drawing.Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;
int srcStride = sourceData.Stride;
int dstOffset = destinationData.Stride - pixelSize * newWidth;
double xFactor = (double)width / newWidth;
double yFactor = (double)height / newHeight;
// do the job
byte* src = (byte*)sourceData.ImageData.ToPointer();
byte* dst = (byte*)destinationData.ImageData.ToPointer();
// coordinates of source points
double ox, oy, dx1, dy1, dx2, dy2;
int ox1, oy1, ox2, oy2;
// width and height decreased by 1
int ymax = height - 1;
int xmax = width - 1;
// temporary pointers
byte* tp1, tp2;
byte* p1, p2, p3, p4;
// for each line
for (int y = 0; y < newHeight; y++)
{
// Y coordinates
oy = (double)y * yFactor;
oy1 = (int)oy;
oy2 = (oy1 == ymax) ? oy1 : oy1 + 1;
dy1 = oy - (double)oy1;
dy2 = 1.0 - dy1;
// get temp pointers
tp1 = src + oy1 * srcStride;
tp2 = src + oy2 * srcStride;
// for each pixel
for (int x = 0; x < newWidth; x++)
{
// X coordinates
ox = (double)x * xFactor;
ox1 = (int)ox;
ox2 = (ox1 == xmax) ? ox1 : ox1 + 1;
dx1 = ox - (double)ox1;
dx2 = 1.0 - dx1;
// get four points
p1 = tp1 + ox1 * pixelSize;
p2 = tp1 + ox2 * pixelSize;
p3 = tp2 + ox1 * pixelSize;
p4 = tp2 + ox2 * pixelSize;
// interpolate using 4 points
for (int i = 0; i < pixelSize; i++, dst++, p1++, p2++, p3++, p4++)
{
*dst = (byte)(
dy2 * (dx2 * (*p1) + dx1 * (*p2)) +
dy1 * (dx2 * (*p3) + dx1 * (*p4)));
}
}
dst += dstOffset;
}
}
}
}
}

View File

@@ -1,97 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace cmonitor.server.client.reports.screen.aforge
{
public static class SystemTools
{
public static IntPtr CopyUnmanagedMemory(IntPtr dst, IntPtr src, int count)
{
unsafe
{
CopyUnmanagedMemory((byte*)dst.ToPointer(), (byte*)src.ToPointer(), count);
}
return dst;
}
public static unsafe byte* CopyUnmanagedMemory(byte* dst, byte* src, int count)
{
#if !MONO
return memcpy(dst, src, count);
#else
int countUint = count >> 2;
int countByte = count & 3;
uint* dstUint = (uint*) dst;
uint* srcUint = (uint*) src;
while ( countUint-- != 0 )
{
*dstUint++ = *srcUint++;
}
byte* dstByte = (byte*) dstUint;
byte* srcByte = (byte*) srcUint;
while ( countByte-- != 0 )
{
*dstByte++ = *srcByte++;
}
return dst;
#endif
}
public static IntPtr SetUnmanagedMemory(IntPtr dst, int filler, int count)
{
unsafe
{
SetUnmanagedMemory((byte*)dst.ToPointer(), filler, count);
}
return dst;
}
public static unsafe byte* SetUnmanagedMemory(byte* dst, int filler, int count)
{
#if !MONO
return memset(dst, filler, count);
#else
int countUint = count >> 2;
int countByte = count & 3;
byte fillerByte = (byte) filler;
uint fiilerUint = (uint) filler | ( (uint) filler << 8 ) |
( (uint) filler << 16 );// |
//( (uint) filler << 24 );
uint* dstUint = (uint*) dst;
while ( countUint-- != 0 )
{
*dstUint++ = fiilerUint;
}
byte* dstByte = (byte*) dstUint;
while ( countByte-- != 0 )
{
*dstByte++ = fillerByte;
}
return dst;
#endif
}
#if !MONO
[DllImport("ntdll.dll", CallingConvention = CallingConvention.Cdecl)]
private static unsafe extern byte* memcpy(
byte* dst,
byte* src,
int count);
[DllImport("ntdll.dll", CallingConvention = CallingConvention.Cdecl)]
private static unsafe extern byte* memset(
byte* dst,
int filler,
int count);
#endif
}
}

View File

@@ -1,277 +0,0 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
namespace cmonitor.server.client.reports.screen.aforge
{
public class UnmanagedImage : IDisposable
{
private IntPtr imageData;
private int width, height;
private int stride;
private PixelFormat pixelFormat;
private bool mustBeDisposed = false;
public IntPtr ImageData
{
get { return imageData; }
}
public int Width
{
get { return width; }
}
public int Height
{
get { return height; }
}
public int Stride
{
get { return stride; }
}
public PixelFormat PixelFormat
{
get { return pixelFormat; }
}
public UnmanagedImage( IntPtr imageData, int width, int height, int stride, PixelFormat pixelFormat )
{
this.imageData = imageData;
this.width = width;
this.height = height;
this.stride = stride;
this.pixelFormat = pixelFormat;
}
public UnmanagedImage( BitmapData bitmapData )
{
if (OperatingSystem.IsWindows())
{
this.imageData = bitmapData.Scan0;
this.width = bitmapData.Width;
this.height = bitmapData.Height;
this.stride = bitmapData.Stride;
this.pixelFormat = bitmapData.PixelFormat;
}
}
~UnmanagedImage( )
{
Dispose( false );
}
public void Dispose( )
{
Dispose( true );
// remove me from the Finalization queue
GC.SuppressFinalize( this );
}
protected virtual void Dispose( bool disposing )
{
if ( disposing )
{
// dispose managed resources
}
// free image memory if the image was allocated using this class
if ( ( mustBeDisposed ) && ( imageData != IntPtr.Zero ) )
{
System.Runtime.InteropServices.Marshal.FreeHGlobal( imageData );
System.GC.RemoveMemoryPressure( stride * height );
imageData = IntPtr.Zero;
}
}
public static UnmanagedImage Create( int width, int height, PixelFormat pixelFormat )
{
if (OperatingSystem.IsWindows())
{
int bytesPerPixel = 0;
// calculate bytes per pixel
switch (pixelFormat)
{
case PixelFormat.Format8bppIndexed:
bytesPerPixel = 1;
break;
case PixelFormat.Format16bppGrayScale:
bytesPerPixel = 2;
break;
case PixelFormat.Format24bppRgb:
bytesPerPixel = 3;
break;
case PixelFormat.Format32bppRgb:
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
bytesPerPixel = 4;
break;
case PixelFormat.Format48bppRgb:
bytesPerPixel = 6;
break;
case PixelFormat.Format64bppArgb:
case PixelFormat.Format64bppPArgb:
bytesPerPixel = 8;
break;
default:
throw new Exception("Can not create image with specified pixel format.");
}
// check image size
if ((width <= 0) || (height <= 0))
{
throw new Exception("Invalid image size specified.");
}
// calculate stride
int stride = width * bytesPerPixel;
if (stride % 4 != 0)
{
stride += (4 - (stride % 4));
}
// allocate memory for the image
IntPtr imageData = System.Runtime.InteropServices.Marshal.AllocHGlobal(stride * height);
cmonitor.server.client.reports.screen.aforge.SystemTools.SetUnmanagedMemory(imageData, 0, stride * height);
System.GC.AddMemoryPressure(stride * height);
UnmanagedImage image = new UnmanagedImage(imageData, width, height, stride, pixelFormat);
image.mustBeDisposed = true;
return image;
}
return null;
}
public void SetPixel( IntPoint point, Color color )
{
SetPixel( point.X, point.Y, color );
}
public void SetPixel( int x, int y, Color color )
{
SetPixel( x, y, color.R, color.G, color.B, color.A );
}
public void SetPixel( int x, int y, byte value )
{
SetPixel( x, y, value, value, value, 255 );
}
private void SetPixel( int x, int y, byte r, byte g, byte b, byte a )
{
if (OperatingSystem.IsWindows())
{
if ((x >= 0) && (y >= 0) && (x < width) && (y < height))
{
unsafe
{
int pixelSize = Bitmap.GetPixelFormatSize(pixelFormat) / 8;
byte* ptr = (byte*)imageData.ToPointer() + y * stride + x * pixelSize;
ushort* ptr2 = (ushort*)ptr;
switch (pixelFormat)
{
case PixelFormat.Format8bppIndexed:
*ptr = (byte)(0.2125 * r + 0.7154 * g + 0.0721 * b);
break;
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
ptr[RGB.R] = r;
ptr[RGB.G] = g;
ptr[RGB.B] = b;
break;
case PixelFormat.Format32bppArgb:
ptr[RGB.R] = r;
ptr[RGB.G] = g;
ptr[RGB.B] = b;
ptr[RGB.A] = a;
break;
case PixelFormat.Format16bppGrayScale:
*ptr2 = (ushort)((ushort)(0.2125 * r + 0.7154 * g + 0.0721 * b) << 8);
break;
case PixelFormat.Format48bppRgb:
ptr2[RGB.R] = (ushort)(r << 8);
ptr2[RGB.G] = (ushort)(g << 8);
ptr2[RGB.B] = (ushort)(b << 8);
break;
case PixelFormat.Format64bppArgb:
ptr2[RGB.R] = (ushort)(r << 8);
ptr2[RGB.G] = (ushort)(g << 8);
ptr2[RGB.B] = (ushort)(b << 8);
ptr2[RGB.A] = (ushort)(a << 8);
break;
default:
throw new Exception("The pixel format is not supported: " + pixelFormat);
}
}
}
}
}
public Color GetPixel( IntPoint point )
{
return GetPixel( point.X, point.Y );
}
public Color GetPixel( int x, int y )
{
if (OperatingSystem.IsWindows())
{
if ((x < 0) || (y < 0))
{
throw new ArgumentOutOfRangeException("x", "The specified pixel coordinate is out of image's bounds.");
}
if ((x >= width) || (y >= height))
{
throw new ArgumentOutOfRangeException("y", "The specified pixel coordinate is out of image's bounds.");
}
Color color = new Color();
unsafe
{
int pixelSize = Bitmap.GetPixelFormatSize(pixelFormat) / 8;
byte* ptr = (byte*)imageData.ToPointer() + y * stride + x * pixelSize;
switch (pixelFormat)
{
case PixelFormat.Format8bppIndexed:
color = Color.FromArgb(*ptr, *ptr, *ptr);
break;
case PixelFormat.Format24bppRgb:
case PixelFormat.Format32bppRgb:
color = Color.FromArgb(ptr[RGB.R], ptr[RGB.G], ptr[RGB.B]);
break;
case PixelFormat.Format32bppArgb:
color = Color.FromArgb(ptr[RGB.A], ptr[RGB.R], ptr[RGB.G], ptr[RGB.B]);
break;
default:
throw new Exception("The pixel format is not supported: " + pixelFormat);
}
}
return color;
}
return new Color();
}
}
}

View File

@@ -10,6 +10,8 @@ namespace cmonitor.server.client.reports.share
private readonly Config config;
Dictionary<string, ShareItemInfo> dic = new Dictionary<string, ShareItemInfo>();
private bool updated = false;
public ShareReport(Config config)
{
this.config = config;
@@ -18,11 +20,12 @@ namespace cmonitor.server.client.reports.share
InitShare();
}
}
public object GetReports()
public object GetReports(ReportType reportType)
{
updated = false;
GetShare();
if (dic.Count == 0) return null;
return dic;
if ((dic.Count > 0 && updated) || reportType == ReportType.Full) return dic;
return null;
}
public bool GetShare(string key, out ShareItemInfo item)
{
@@ -66,6 +69,12 @@ namespace cmonitor.server.client.reports.share
{
val = Encoding.UTF8.GetString(span.Slice(2 + keyLen, valLen));
}
if(dic.TryGetValue(key,out ShareItemInfo item) == false || item.Value != val)
{
updated = true;
}
dic[key] = new ShareItemInfo
{
Index = index,

View File

@@ -14,9 +14,9 @@
ReportTask();
}
public object GetReports()
public object GetReports(ReportType reportType)
{
if(systemReportInfo.Cpu != lastCpu || systemReportInfo.Memory != lastMemory)
if(reportType == ReportType.Full || systemReportInfo.Cpu != lastCpu || systemReportInfo.Memory != lastMemory)
{
lastCpu = systemReportInfo.Cpu;
lastMemory = systemReportInfo.Memory;

View File

@@ -21,9 +21,9 @@ namespace cmonitor.server.client.reports.llock
}
}
public object GetReports()
public object GetReports(ReportType reportType)
{
if (report.Value != lastValue)
if (reportType == ReportType.Full || report.Value != lastValue)
{
lastValue = report.Value;
return report;

View File

@@ -16,7 +16,7 @@ namespace cmonitor.server.client.reports.volume
Init();
}
public object GetReports()
public object GetReports(ReportType reportType)
{
if (OperatingSystem.IsWindows())
{
@@ -24,7 +24,7 @@ namespace cmonitor.server.client.reports.volume
report.Mute = GetVolumeMute();
report.MasterPeak = GetMasterPeakValue();
}
if (report.Value != lastValue || report.Mute != lastMute || report.MasterPeak != lastMasterPeak)
if (reportType == ReportType.Full || report.Value != lastValue || report.Mute != lastMute || report.MasterPeak != lastMasterPeak)
{
lastValue = report.Value;
lastMute = report.Mute;

View File

@@ -18,13 +18,13 @@ namespace cmonitor.server.client.reports.llock
}
DateTime startTime = new DateTime(1970, 1, 1);
public object GetReports()
public object GetReports(ReportType reportType)
{
if (shareReport.GetShare(Name, out ShareItemInfo share) && string.IsNullOrWhiteSpace(share.Value) == false && long.TryParse(share.Value, out long time))
{
report.Value = (long)(DateTime.UtcNow.Subtract(startTime)).TotalMilliseconds - time < 1000;
}
if (report.Value != lastValue)
if (reportType == ReportType.Full || report.Value != lastValue)
{
lastValue = report.Value;
return report;

View File

@@ -20,7 +20,13 @@ namespace cmonitor.server.service.messengers.report
[MessengerId((ushort)ReportMessengerIds.Update)]
public void Update(IConnection connection)
{
reportTransfer.Update();
ReportType reportType = ReportType.Trim;
if(connection.ReceiveRequestWrap.Payload.Length > 0)
{
reportType = (ReportType)connection.ReceiveRequestWrap.Payload.Span[0];
}
reportTransfer.Update(reportType);
connection.Write(Helper.TrueArray);
}

View File

@@ -1,10 +1,7 @@
using cmonitor.server.api;
using cmonitor.server.client.reports.screen;
using cmonitor.server.client.reports.screen.sharpDX;
using cmonitor.server.service.messengers.sign;
using MemoryPack;
using MemoryPack.Compression;
using System;
namespace cmonitor.server.service.messengers.screen
{

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=0"><link rel="icon" href="/favicon.ico"><title>cmonitor.web</title><script defer="defer" src="/js/chunk-vendors.9b0dc62c.js"></script><script defer="defer" src="/js/app.4c3fbccb.js"></script><link href="/css/chunk-vendors.faad7142.css" rel="stylesheet"><link href="/css/app.9c6b579f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but cmonitor.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=0"><link rel="icon" href="/favicon.ico"><title>cmonitor.web</title><script defer="defer" src="/js/chunk-vendors.9b0dc62c.js"></script><script defer="defer" src="/js/app.28446d51.js"></script><link href="/css/chunk-vendors.faad7142.css" rel="stylesheet"><link href="/css/app.9c6b579f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but cmonitor.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -81,7 +81,7 @@ namespace llock.win
while (true)
{
WriteLLock();
Thread.Sleep(100);
Thread.Sleep(30);
}
}).Start();
}
@@ -89,10 +89,16 @@ namespace llock.win
MemoryMappedViewAccessor accessor2;
DateTime startTime = new DateTime(1970, 1, 1);
byte[] keyBytes = Encoding.UTF8.GetBytes("LLock");
long lastTime = 0;
private void WriteLLock()
{
long time = (long)(DateTime.UtcNow.Subtract(startTime)).TotalMilliseconds;
if(time - lastTime >= 300)
{
WriteMemory(this.shareIndex, keyBytes, Encoding.UTF8.GetBytes(time.ToString()));
lastTime = time;
}
}
private void WriteMemory(int index, byte[] key, byte[] value)
{

View File

@@ -28,60 +28,116 @@
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.username = new System.Windows.Forms.Label();
this.star5 = new System.Windows.Forms.PictureBox();
this.star4 = new System.Windows.Forms.PictureBox();
this.star3 = new System.Windows.Forms.PictureBox();
this.star2 = new System.Windows.Forms.PictureBox();
this.star1 = new System.Windows.Forms.PictureBox();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.pictureBox2 = new System.Windows.Forms.PictureBox();
this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.star5)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.star4)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.star3)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.star2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.star1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
this.SuspendLayout();
//
// username
//
this.username.Font = new System.Drawing.Font("宋体", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.username.ForeColor = System.Drawing.Color.Orange;
this.username.Location = new System.Drawing.Point(4, 5);
this.username.Name = "username";
this.username.Size = new System.Drawing.Size(171, 23);
this.username.TabIndex = 6;
this.username.Text = "label1";
this.username.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// star5
//
this.star5.Image = global::notify.win.Properties.Resources.star1;
this.star5.Location = new System.Drawing.Point(145, 31);
this.star5.Name = "star5";
this.star5.Size = new System.Drawing.Size(30, 30);
this.star5.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.star5.TabIndex = 5;
this.star5.TabStop = false;
//
// star4
//
this.star4.Image = global::notify.win.Properties.Resources.star1;
this.star4.Location = new System.Drawing.Point(110, 31);
this.star4.Name = "star4";
this.star4.Size = new System.Drawing.Size(30, 30);
this.star4.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.star4.TabIndex = 4;
this.star4.TabStop = false;
//
// star3
//
this.star3.Image = global::notify.win.Properties.Resources.star1;
this.star3.Location = new System.Drawing.Point(74, 31);
this.star3.Name = "star3";
this.star3.Size = new System.Drawing.Size(30, 30);
this.star3.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.star3.TabIndex = 3;
this.star3.TabStop = false;
//
// star2
//
this.star2.Image = global::notify.win.Properties.Resources.star1;
this.star2.Location = new System.Drawing.Point(38, 31);
this.star2.Name = "star2";
this.star2.Size = new System.Drawing.Size(30, 30);
this.star2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.star2.TabIndex = 2;
this.star2.TabStop = false;
//
// star1
//
this.star1.Image = global::notify.win.Properties.Resources.star1;
this.star1.Location = new System.Drawing.Point(3, 31);
this.star1.Name = "star1";
this.star1.Size = new System.Drawing.Size(30, 30);
this.star1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.star1.TabIndex = 1;
this.star1.TabStop = false;
//
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(55, 203);
this.pictureBox1.Image = global::notify.win.Properties.Resources._3;
this.pictureBox1.Location = new System.Drawing.Point(31, 66);
this.pictureBox1.Margin = new System.Windows.Forms.Padding(2);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(236, 250);
this.pictureBox1.Size = new System.Drawing.Size(118, 113);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// pictureBox2
//
this.pictureBox2.BackColor = System.Drawing.Color.Transparent;
this.pictureBox2.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox2.Image")));
this.pictureBox2.Location = new System.Drawing.Point(1, -7);
this.pictureBox2.Name = "pictureBox2";
this.pictureBox2.Size = new System.Drawing.Size(331, 271);
this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox2.TabIndex = 1;
this.pictureBox2.TabStop = false;
//
// label1
//
this.label1.BackColor = System.Drawing.Color.Gray;
this.label1.Font = new System.Drawing.Font("微软雅黑", 11F, System.Drawing.FontStyle.Bold);
this.label1.Location = new System.Drawing.Point(67, 108);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(200, 121);
this.label1.TabIndex = 2;
this.label1.Text = "恭喜地方发鬼地方获得【五星点评】";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 24F);
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(333, 450);
this.Controls.Add(this.label1);
this.Controls.Add(this.pictureBox2);
this.ClientSize = new System.Drawing.Size(179, 179);
this.Controls.Add(this.username);
this.Controls.Add(this.star5);
this.Controls.Add(this.star4);
this.Controls.Add(this.star3);
this.Controls.Add(this.star2);
this.Controls.Add(this.star1);
this.Controls.Add(this.pictureBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
this.Name = "Form1";
this.Text = "广播";
this.Load += new System.EventHandler(this.OnLoad);
((System.ComponentModel.ISupportInitialize)(this.star5)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.star4)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.star3)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.star2)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.star1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit();
this.ResumeLayout(false);
}
@@ -89,8 +145,12 @@
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.PictureBox pictureBox2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.PictureBox star1;
private System.Windows.Forms.PictureBox star2;
private System.Windows.Forms.PictureBox star3;
private System.Windows.Forms.PictureBox star4;
private System.Windows.Forms.PictureBox star5;
private System.Windows.Forms.Label username;
}
}

View File

@@ -3,12 +3,14 @@ using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
namespace notify.win
{
public partial class Form1 : Form
{
protected override bool ShowWithoutActivation => true;
protected override CreateParams CreateParams
{
get
@@ -24,10 +26,12 @@ namespace notify.win
private int speed;
private string msg;
public Form1(int speed, string msg)
private int star;
public Form1(int speed, string msg,int star)
{
this.speed = speed;
this.msg = msg;
this.star = Math.Min(star,5);
InitializeComponent();
this.AllowTransparency = true;
@@ -37,12 +41,24 @@ namespace notify.win
this.TopMost = true;
this.ShowInTaskbar = false;
label1.BackColor = Color.FromArgb(255, 248, 153);
label1.ForeColor = Color.Green;
//username.BackColor = Color.FromArgb(255, 248, 153);
//username.ForeColor = Color.LightGreen;
}
private void OnLoad(object sender, EventArgs e)
{
PictureBox[] stars = new PictureBox[] { star1, star2, star3, star4, star5 };
for (int i = 0; i < 5; i++)
{
stars[i].Image = global::notify.win.Properties.Resources.star2;
}
for (int i = 0; i < star; i++)
{
stars[i].Image = global::notify.win.Properties.Resources.star1;
}
Bitmap[] images = new Bitmap[] { Properties.Resources._0, Properties.Resources._1, Properties.Resources._2, Properties.Resources._3, Properties.Resources._4, Properties.Resources._5 };
pictureBox1.Image = images[new Random().Next(0,6)];
this.FormBorderStyle = FormBorderStyle.None;
//将窗口置顶
SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
@@ -62,7 +78,7 @@ namespace notify.win
int width = this.Width;
int height = this.Height;
label1.Text = this.msg;
username.Text = this.msg;
Task.Run(() =>
{

File diff suppressed because it is too large Load Diff

View File

@@ -14,10 +14,17 @@ namespace notify.win
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
int speed = int.Parse(args[0]);
string msg = args[1];
int speed = 1;
string msg = "少年郎秃头呀";
int star = 1;
if(args.Length > 1)
{
speed = int.Parse(args[0]);
msg = args[1];
star = int.Parse(args[2]);
}
Application.Run(new Form1(speed,msg));
Application.Run(new Form1(speed,msg, star));
}
}
}

View File

@@ -3,47 +3,42 @@
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能导致不正确的行为,如果
// 重新生成代码,则所做更改将丢失。
// 对此文件的更改可能导致不正确的行为,并且如果
// 重新生成代码,这些更改将丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace notify.win.Properties
{
namespace notify.win.Properties {
using System;
/// <summary>
/// 强类型资源类,用于查找本地化字符串等。
/// 一个强类型资源类,用于查找本地化字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存 ResourceManager 实例。
/// 返回此类使用的缓存 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("notify.win.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
@@ -56,16 +51,103 @@ namespace notify.win.Properties
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set
{
set {
resourceCulture = value;
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap _0 {
get {
object obj = ResourceManager.GetObject("0", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap _1 {
get {
object obj = ResourceManager.GetObject("1", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap _2 {
get {
object obj = ResourceManager.GetObject("2", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap _3 {
get {
object obj = ResourceManager.GetObject("3", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap _4 {
get {
object obj = ResourceManager.GetObject("4", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap _5 {
get {
object obj = ResourceManager.GetObject("5", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap notify {
get {
object obj = ResourceManager.GetObject("notify", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap star1 {
get {
object obj = ResourceManager.GetObject("star1", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap star2 {
get {
object obj = ResourceManager.GetObject("star2", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@@ -46,7 +46,7 @@
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,6 +60,7 @@
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
@@ -68,9 +69,10 @@
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
@@ -85,9 +87,10 @@
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
@@ -109,9 +112,37 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\1.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="star1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\star1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\2.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="star2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\star2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="notify" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\notify.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="0" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\0.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="3" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\3.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="4" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\4.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="5" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\5.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

BIN
notify.win/Resources/0.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

BIN
notify.win/Resources/1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

BIN
notify.win/Resources/2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
notify.win/Resources/3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

BIN
notify.win/Resources/4.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
notify.win/Resources/5.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -65,6 +65,7 @@
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
@@ -79,5 +80,32 @@
<ItemGroup>
<EmbeddedResource Include="App.config" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\star1.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\star2.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\notify.gif" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\1.gif" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\2.gif" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\0.gif" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\3.gif" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\4.gif" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\5.gif" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -96,7 +96,6 @@ namespace wallpaper.win
pictureBox1.ImageLocation = imgUrl;
this.Dock = DockStyle.Fill;
this.ShowInTaskbar = false;
this.WindowState = FormWindowState.Maximized;
this.FormBorderStyle = FormBorderStyle.None;
hook.Start();
@@ -104,6 +103,8 @@ namespace wallpaper.win
Find();
Init();
this.WindowState = FormWindowState.Maximized;
IntPtr oldprogramIntPtr = programIntPtr;
new Thread(() =>
{
@@ -122,6 +123,7 @@ namespace wallpaper.win
}).Start();
mmf2 = MemoryMappedFile.CreateOrOpen(this.shareMkey, this.shareMLength);
accessor2 = mmf2.CreateViewAccessor();
WriteKeyBoard("init");
@@ -168,10 +170,16 @@ namespace wallpaper.win
{
WriteMemory(this.shareKeyBoardIndex, keyBytes, emptyArray);
}
long lastTime = 0;
private void WriteWallpaper()
{
long time = (long)(DateTime.UtcNow.Subtract(startTime)).TotalMilliseconds;
if(time- lastTime >= 300)
{
WriteMemory(this.shareWallpaperIndex, wallpaperBytes, Encoding.UTF8.GetBytes(time.ToString()));
lastTime = time;
}
}
private void WriteMemory(int index, byte[] key, byte[] value)
{

View File

@@ -18,11 +18,19 @@ namespace wallpaper.win
Environment.Exit(1);
}
string imgUrl = arg[0];
string shareMkey = arg[1];
int shareMLength = int.Parse(arg[2]);
int shareKeyBoardIndex = int.Parse(arg[3]);
int shareWallpaperIndex = int.Parse(arg[4]);
string imgUrl = string.Empty;
string shareMkey = "test";
int shareMLength = 2550;
int shareKeyBoardIndex = 0;
int shareWallpaperIndex = 1;
if (arg.Length > 0)
{
imgUrl = arg[0];
shareMkey = arg[1];
shareMLength = int.Parse(arg[2]);
shareKeyBoardIndex = int.Parse(arg[3]);
shareWallpaperIndex = int.Parse(arg[4]);
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1(imgUrl, shareMkey, shareMLength, shareKeyBoardIndex, shareWallpaperIndex));