我期待在程序中添加一个鼠标位置检查模块。
UI有两个Textbox
来打印X和Y。它应该异步打印光标位置。
我尝试了BeginInvoke
/ Invoke
,Thread.isBackgroud = true
,BackgroundWorker
,但这些方法都没有帮助。
Thread / BackgroundWorker不断发生
跨线程错误(符合预期),
和BeginInvoke
/ Invoke
的异步问题:UI线程不断消亡。
我还尝试了mousemove
事件,但是该事件有效,但是当光标超出窗体边界时,位置跟踪就会停止。
delegate void MP();
private void tracktoggle() {
MP mp = printMousePosition;
BeginInvoke(mp); // Or Invoke(mp);
}
private void printMousePosition() {
while(true) {
this.Xtext.Text = Mouseposition.X.ToString();
this.Ytext.Text = Mouseposition.Y.ToString();
}
}
此代码将UI线程保留在块上。
private async void tracktoggle() {
Task T = new Task(() => { printMousePosition(); });
await T;
}
private void printMousePosition() {
while(true) {
this.Xtext.Text = Mouseposition.X.ToString();
this.Ytext.Text = Mouseposition.Y.ToString();
}
}
这是带有异步/等待的代码。不阻止UI线程,但文本框未更新。 我以为BeginInvoke是Invoke的异步版本:(不起作用
想要异步打印鼠标位置而不会阻塞UI线程。
答案 0 :(得分:0)
我发现最好的解决方案是使用user32.dll设置WindowsHook。
[DllImport("user32.dll", CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
///On the Code 14 is low level mouse hooking id
HookID = SetWindowsHookEx(14, MouseEventFunc, (IntPtr)0, 0/*should be 0, cause we are trying to make global hook);
private void int MouseEventFunc(int nCode, IntPtr w, IntPtr l) {
{
this.MouseX.Text = MousePosition.X.ToString();
this.MouseY.Text = MousePosition.Y.ToString();
return CallNextHookEx(HookID, nCode, w, l);
}
此代码段很好地获取/更新了TextBox。
任何人对此问题都有疑问,请尝试此解决方案