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..."); }
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; } }
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); } }