예제 #1
0
        void TaskFunc() {
            var lastStatus = new IMEStatusInfo();
            var currentStatus = new IMEStatusInfo();
            var lastChangeTime = DateTime.MinValue;

            while (!_lockObject.CancelTokenSource.IsCancellationRequested) {
                var now = DateTime.Now;
                lastStatus = currentStatus;
                updateIMEStatusInfo(ref currentStatus);

                bool somethingChanged = !currentStatus.Equals(lastStatus);
                bool windowMoving = (currentStatus.ClientBounds != lastStatus.ClientBounds);

                lock (_lockObject) {
                    if (_lockObject.SettingChanged) {
                        cacheSettings();
                        somethingChanged = true;
                    }
                    _lockObject.IMEStatusInfo = currentStatus;
                    _lockObject.LastChecked = now;
                }

                if (somethingChanged) {
                    lastChangeTime = now;
#if DEBUG
                    Log.I(currentStatus.ToString());
#endif
                    raiseUpdatedEvent();
                }
                
                if (windowMoving) {
                    Thread.Sleep(20);
                }
                else if (now - lastChangeTime < new TimeSpan(0, 10, 0)) {
                    Thread.Sleep(100);
                }
                else {
                    Thread.Sleep(1000);
                }
            }
            Log.I("Monitoring task is going to exit...");
        }
예제 #2
0
        void updateIMEStatusInfo(ref IMEStatusInfo status) {
            // 【C#,WinAPI】バックグラウンドで現在のIME状態を取得 - 行き当たりばったり
            // http://sturnus.hateblo.jp/entry/2014/05/10/234603
            GUITHREADINFO gti = new GUITHREADINFO();
            gti.cbSize = Marshal.SizeOf(gti);

            if (WinApi.GetGUIThreadInfo(0, ref gti) != 0) {
                bool windowVisible = WinApi.IsWindowVisible(gti.hwndActive);

                bool windowSwitched = (status.WindowHandle != gti.hwndActive);
                bool focusSwitched = (status.ClientHandle != gti.hwndFocus);

                if (windowSwitched) {
                    status.WindowText = WinApi.GetWindowText(gti.hwndActive);
                    try {
                        status.ExecutableFileName = WinApi.GetExecutableFileNameFromWindowHandle(gti.hwndActive);
                    }
                    catch {
                        status.ExecutableFileName = string.Empty;
                    }
                }

                if (focusSwitched) {
                    status.ClientClassName = WinApi.GetClassName(gti.hwndFocus);
                }

                if (windowVisible) {
                    IntPtr hWndIME = WinApi.ImmGetDefaultIMEWnd(gti.hwndFocus);
                    status.IMEEnabled = (WinApi.SendMessage(hWndIME, 0x283, 0x5, 0) != 0);
                    status.ClientBounds = WinApi.GetWindowRect(gti.hwndFocus);
                }

                if (windowSwitched || focusSwitched) {
                    // 無視リストに当たった場合は無かったことにする
                    bool ignored = false;
                    foreach (var regex in _cachedIgnoreList) {
                        if (regex.IsMatch(status.ExecutableFileName) || 
                            regex.IsMatch(status.WindowText) || 
                            regex.IsMatch(status.ClientClassName)) {

                            ignored = true;
                            break;
                        }
                    }
                    status.Ignored = ignored;
                }

                status.WindowHandle = gti.hwndActive;
                status.ClientHandle = gti.hwndFocus;
                status.WindowVisible = windowVisible;
            }
        }
예제 #3
0
        private void updateBorder()
        {
            var imeInfo = _monitor.IMEStatus;
            _lastImeStatus = imeInfo;

            if (imeInfo.WindowHandle == this.Handle || !imeInfo.WindowVisible || imeInfo.Ignored) {
                this.Opacity = 0f;
                setTopMost(false);
            }
            else {
                var borderWidth = imeInfo.IMEEnabled ?
                    _settings.ImeOnBorderStyle.Width :
                    _settings.ImeOffBorderStyle.Width;

                Rectangle windowRect = imeInfo.ClientBounds;
                windowRect.Inflate(borderWidth, borderWidth);

                // スクリーン外にはみ出た部分を押し込む
                Rectangle screenRect = Screen.FromHandle(imeInfo.ClientHandle).Bounds;
                {
                    int left = windowRect.X;
                    int top = windowRect.Y;
                    int right = windowRect.Right;
                    int bottom = windowRect.Bottom;
                    if (left < screenRect.X) left = screenRect.X;
                    if (top < screenRect.Y) top = screenRect.Y;
                    if (right > screenRect.Right) right = screenRect.Right;
                    if (bottom > screenRect.Bottom) bottom = screenRect.Bottom;
                    windowRect = Rectangle.FromLTRB(left, top, right, bottom);
                }

                if (this.Size == windowRect.Size) {
                    this.Location = windowRect.Location;
                }
                else {
                    var path = new System.Drawing.Drawing2D.GraphicsPath();
                    var w = windowRect.Width;
                    var h = windowRect.Height;
                    var border2x = borderWidth * 2;
                    path.AddPie(0, 0, border2x, border2x, 180, 90);
                    path.AddPie(w - border2x, 0, border2x, border2x, 270, 90);
                    path.AddPie(0, h - border2x, border2x, border2x, 90, 90);
                    path.AddPie(w - border2x, h - border2x, border2x, border2x, 0, 90);
                    path.AddRectangle(new Rectangle(0, borderWidth, borderWidth, h - border2x));
                    path.AddRectangle(new Rectangle(borderWidth, 0, w - border2x, borderWidth));
                    path.AddRectangle(new Rectangle(w - borderWidth, borderWidth, borderWidth, h - border2x));
                    path.AddRectangle(new Rectangle(borderWidth, h - borderWidth, w - border2x, borderWidth));
                    this.Region = new Region(path);
                    this.Bounds = windowRect;
                }

                this.BackColor = imeInfo.IMEEnabled ?
                    _settings.ImeOnBorderStyle.GetColor() :
                    _settings.ImeOffBorderStyle.GetColor();
                this.Opacity = imeInfo.IMEEnabled ?
                    _settings.ImeOnBorderStyle.Opacity :
                    _settings.ImeOffBorderStyle.Opacity;
                setTopMost(true);
            }
        }