Exemple #1
0
    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));
    }
Exemple #2
0
 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);
                            }
                        }
                    }
                }
            }