示例#1
0
文件: Triggers.cs 项目: alexfordc/Au
        ITriggers _Get(TriggerType e)
        {
            int i = (int)e;
            var t = _t[i];

            if (t == null)
            {
                switch (e)
                {
                case TriggerType.Hotkey: t = new HotkeyTriggers(this); break;

                case TriggerType.Autotext: t = new AutotextTriggers(this); break;

                case TriggerType.Mouse: t = new MouseTriggers(this); break;

                case TriggerType.Window: t = new WindowTriggers(this); break;

                default: Debug.Assert(false); break;
                }
                _t[i] = t;
            }
            return(t);
        }
示例#2
0
文件: Triggers.cs 项目: alexfordc/Au
        /// <summary>
        /// Makes triggers alive.
        /// </summary>
        /// <remarks>
        /// This function monitors hotkeys, activated windows and other events. When an event matches an added trigger, launches the thrigger's action, which runs in other thread by default.
        /// Does not return immediately. Runs until this process is terminated or <see cref="Stop"/> called.
        /// </remarks>
        /// <example>See <see cref="ActionTriggers"/>.</example>
        /// <exception cref="InvalidOperationException">Already running.</exception>
        /// <exception cref="AuException">Something failed.</exception>
        public unsafe void Run()
        {
            //ADebug.PrintLoadedAssemblies(true, true, true);

            ThrowIfRunning_();

            //bool haveTriggers = false;
            HooksThread.UsedEvents hookEvents = 0;
            _windowTriggers = null;
            for (int i = 0; i < _t.Length; i++)
            {
                var t = _t[i];
                if (t == null || !t.HasTriggers)
                {
                    continue;
                }
                //haveTriggers = true;
                switch ((TriggerType)i)
                {
                case TriggerType.Hotkey: hookEvents |= HooksThread.UsedEvents.Keyboard; break;

                case TriggerType.Autotext: hookEvents |= HooksThread.UsedEvents.Keyboard | HooksThread.UsedEvents.Mouse; break;

                case TriggerType.Mouse: hookEvents |= (t as MouseTriggers).UsedHookEvents_; break;

                case TriggerType.Window: _windowTriggers = t as WindowTriggers; break;
                }
            }
            //AOutput.Write(haveTriggers, (uint)llHooks);
            //if(!haveTriggers) return; //no. The message loop may be used for toolbars etc.

            if (!s_wasRun)
            {
                s_wasRun = true;
                AWnd.More.RegisterWindowClass(c_cn);
            }
            _wMsg             = AWnd.More.CreateMessageOnlyWindow(_WndProc, c_cn);
            _mainThreadId     = AThread.NativeId;
            _winTimerPeriod   = 0;
            _winTimerLastTime = 0;

            if (hookEvents != 0)
            {
                //prevent big delay later on first LL hook event while hook proc waits
                if (!s_wasKM)
                {
                    s_wasKM = true;
                    ThreadPool.QueueUserWorkItem(_ => {
                        try {
                            //using var p1 = APerf.Create();
                            new AWnd.Finder("*a").IsMatch(AWnd.GetWnd.Root);               //if used window scopes etc
                            _ = AHookWin.LowLevelHooksTimeout;                             //slow JIT of registry functions
                            Util.AJit.Compile(typeof(ActionTriggers), nameof(_WndProc), nameof(_KeyMouseEvent));
                            Util.AJit.Compile(typeof(TriggerHookContext), nameof(TriggerHookContext.InitContext), nameof(TriggerHookContext.PerfEnd), nameof(TriggerHookContext.PerfWarn));
                            Util.AJit.Compile(typeof(ActionTrigger), nameof(ActionTrigger.MatchScopeWindowAndFunc));
                            Util.AJit.Compile(typeof(HotkeyTriggers), nameof(HotkeyTriggers.HookProc));
                            AutotextTriggers.JitCompile();
                            MouseTriggers.JitCompile();
                        }
                        catch (Exception ex) { ADebug.Print(ex); }
                    });
                }

                _thc = new TriggerHookContext(this);

                _ht = new HooksThread(hookEvents, _wMsg);
            }

            try {
                _evStop = Api.CreateEvent(false);
                _StartStopAll(true);
                IntPtr h = _evStop;
                _Wait(&h, 1);
            }
            finally {
                if (hookEvents != 0)
                {
                    _ht.Dispose(); _ht = null;
                }
                Api.DestroyWindow(_wMsg); _wMsg = default;
                Stopping?.Invoke(this, EventArgs.Empty);
                _evStop.Dispose();
                _StartStopAll(false);
                _mainThreadId = 0;
                _threads?.Dispose(); _threads = null;
            }

            void _StartStopAll(bool start)
            {
                foreach (var t in _t)
                {
                    if (t?.HasTriggers ?? false)
                    {
                        t.StartStop(start);
                    }
                }
            }
        }