동일한 문제가 발생해도 동일한 코드를 사용하여 Windows 트레이 응용 프로그램에서 실행되는 this question과 매우 유사한 코드가 있습니다. 그것은 모두 파이어 폭스, 크롬, 윈도우 익스플로러와 같은 고전적인 윈도우 응용 프로그램에서 잘 작동합니다. 그러나 마우스 포커스가 Edge 나 Calendar 또는 Mail과 같은 UWP 응용 프로그램에 도착하면 스크롤이 지저분 해지고 수십 번의 스크롤이 수행 된 후 내 응용 프로그램이 멈 춥니 다. 작업 관리자 (권한 거부)에서 종료 할 수도 없기 때문에이 동작은 매우 재현 가능합니다.Windows10에서 SendInput을 사용하여 스크롤 명령 보내기 UWP 응용 프로그램
여기 질문에서 코드를 붙여 넣을 수 있습니다 :
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace EnableMacScrolling
{
class InterceptMouse
{
const int INPUT_MOUSE = 0;
const int MOUSEEVENTF_WHEEL = 0x0800;
const int WH_MOUSE_LL = 14;
private static LowLevelMouseProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
public static void Main()
{
_hookID = SetHook(_proc);
if (_hookID == null)
{
MessageBox.Show("SetWindowsHookEx Failed");
return;
}
Application.Run();
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelMouseProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_MOUSE_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && MouseMessages.WM_MOUSEWHEEL == (MouseMessages)wParam)
{
MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
Console.WriteLine(hookStruct.mouseData);
if (hookStruct.flags != -1) //prevents recursive call to self
{
INPUT input;
input = new INPUT();
input.type = INPUT_MOUSE;
input.mi.dx = 0;
input.mi.dy = 0;
input.mi.dwFlags = MOUSEEVENTF_WHEEL;
input.mi.time = 0;
input.mi.dwExtraInfo = 0;
input.mi.mouseData = -(hookStruct.mouseData >> 16);
try
{
SendInput(1, ref input, Marshal.SizeOf(input));
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
}
return (IntPtr)1;
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
private enum MouseMessages
{
WM_MOUSEWHEEL = 0x020A
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public int mouseData;
public int flags;
public int time;
public IntPtr dwExtraInfo;
}
public struct INPUT
{
public int type;
public MOUSEINPUT mi;
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public uint dwFlags;
public int time;
public int dwExtraInfo;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("User32.dll", SetLastError = true)]
public static extern int SendInput(int nInputs, ref INPUT pInputs, int cbSize);
} }
그것이 내가 여기 창에서이 문제를 다루고있어 가능한가요? 무슨 일이 일어나고 있는지 어떻게 알 수 있나?
업데이트 : 좀 더 쉽게/재생 문제를 보여주기 위해 C++로 테스트 Win32 응용 프로그램을 만들었습니다
. 이 문제는 SendCommand에서 발생합니다. 고전적인 응용 프로그램이 포커스를 맞춘 상태에서 실행될 때 문제가 없습니다. 그러나 UWP 응용 프로그램이 초점을 맞추는 동안 실행되거나 Windows 시작/시작 메뉴로 인해 호출 응용 프로그램 (내 응용 프로그램)이 멈추고 창이 다시 시작될 때까지 멈추게됩니다.
이 문제에 대한 효과적인 해결 방법/솔루션은 후크 콜백을 처리하는 스레드에서 다른 스레드에서 SendCommand 호출을 수행하는 것입니다. SendCommand를 실행하고 후크 콜백에서 돌아 오는 스레드를 즉시 시작하면 원하는 동작이 생성되고 아무런 문제가 발생하지 않습니다.
나는 이것을 알고 있습니다. 내 응용 프로그램은 UWP가 아니며 고전적인 데스크톱 응용 프로그램입니다. – Vasil
이 문제는 SetWindowsHookEx의 32/64 비트 문제와 관련된 문제 일 수 있습니다. 두 번째 스레드를 만들고 해당 스레드의 컨텍스트에서 SetWindowsHookEx를 실행하여 문제를 해결할 수 있습니다. 32/64 및 메시지 펌프에 대한 설명은 https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85)를 참조하십시오.aspx – hatchet
C++ 샘플 앱은 어디에 있습니까? –