private static IntPtr MessageCallback(int nCode, IntPtr wParam, ref WinApi.MSG lParam) { if (nCode == 0 && lParam.message == WinApi.WM_DROPFILES) { IntPtr hDrop = lParam.wParam; uint num = WinApi.DragQueryFile(hDrop, 0xFFFFFFFF, null, 0); string[] files = new string[num]; uint bufferSize = 1024; StringBuilder path = new StringBuilder((int)bufferSize); for (uint i = 0; i < num; i++) { //uint size = WinApi.DragQueryFile(hDrop, i, path, bufferSize); WinApi.DragQueryFile(hDrop, i, path, bufferSize); files[i] = path.ToString(); path.Length = 0; } WinApi.DragFinish(hDrop); IntPtr hwnd = lParam.hwnd; if (hwnd != IntPtr.Zero) { int instanceCount = 0; // 存在するインスタンス内を検索 foreach (UniWinApi uniwin in instances) { // 該当するウィンドウであった場合 if (uniwin.hWnd == hwnd) { // ファイルドロップ時のイベントを実行 if (uniwin.OnFilesDropped != null) { uniwin.OnFilesDropped(files); } instanceCount++; } } // もしインスタンスが見つからなければおかしいのでログ出力 if (instanceCount < 1) { Debug.Log("File dropped, but no UniWinApi instances were found."); } } } return(WinApi.CallNextHookEx(IntPtr.Zero, nCode, wParam, ref lParam)); }
protected override bool HandleHookEvent(IntPtr wParam, IntPtr lParam) { WinApi.MSG nc = (WinApi.MSG)Marshal.PtrToStructure(lParam, typeof(WinApi.MSG)); if (GetMessage == null) { return(false); } if (_messagesToIntercept.Contains(nc.message)) { bool handled; GetMessage(nc, out handled); return(handled); } return(false); }
public override int Wait(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout) { if (!_pumpMessages) { return(WaitHelper(waitHandles, waitAll, millisecondsTimeout)); } if (waitHandles == null || (uint)waitHandles.Length is var count && count == 0) { throw new ArgumentNullException(); } var timeout = millisecondsTimeout; // wait for all? if (waitAll && count > 1) { // more: https://tinyurl.com/Apartments-and-Pumping, search for "mutex" throw new NotSupportedException("WaitAll for multiple handles on a STA thread is not supported."); } else { // optimization: a quick check with a zero timeout var nativeResult = WinApi.WaitForMultipleObjects( count, waitHandles, bWaitAll: false, dwMilliseconds: 0); if (IsNativeWaitSuccessful(count, nativeResult, out var managedResult)) { return(managedResult); } // proceed to pumping // track timeout if not infinite var startTickCount = Environment.TickCount; var remainingTimeout = (int)timeout; // the core loop var msg = new WinApi.MSG(); while (true) { // MsgWaitForMultipleObjectsEx with MWMO_INPUTAVAILABLE returns, // even if there's a message already seen but not removed in the message queue nativeResult = WinApi.MsgWaitForMultipleObjectsEx( count, waitHandles, (uint)remainingTimeout, WinApi.QS_ALLINPUT, WinApi.MWMO_INPUTAVAILABLE); if (IsNativeWaitSuccessful(count, nativeResult, out managedResult) || managedResult == WaitHandle.WaitTimeout) { return(managedResult); } // there is a message, pump and dispatch it if (WinApi.PeekMessage(out msg, IntPtr.Zero, 0, 0, WinApi.PM_REMOVE)) { WinApi.TranslateMessage(ref msg); WinApi.DispatchMessage(ref msg); } // check the timeout if (remainingTimeout != Timeout.Infinite) { // Environment.TickCount is expected to wrap correctly even when runs continuously var lapse = unchecked (Environment.TickCount - startTickCount); remainingTimeout = Math.Max(timeout - lapse, 0); if (remainingTimeout <= 0) { return(WaitHandle.WaitTimeout); } } } } }