이제 WPF로 바꿔보세요 (13)

클릭 투과 ON/OFF 기능 추가



아이콘 모드로 표시할 때, 초라든지 아날로그 시계등의 이미지만을 Window화해 화면에 냅니다. 앱에는 Window 투명 설정이 있습니다 (Window Opacity 사용). 원래 수수함 기능 툴이므로, 투명하게 눈에 띄지 않는 표시로 할 수 있다고 하는 의도입니다만, 어차피라면 설정으로 클릭 이벤트를 투명하게 하는 편이 좋다고 생각하고, 그래서 방법을 검색하면 Qiita내의 페이지에 고마운 기술이 있었습니다 「→ WPF에서 오버레이 표시
클릭 투과로 하면 당연히 대상 Window상의 컨트롤 조작을 할 수 없게 되므로, NotifyIcon상의 컨텍스트 메뉴에서 ON/OFF 전환 가능하게.



메인 윈도우 히라키파키 없음 → 계속 Win 핸들러 값은 변하지 않기 때문에, 최초로 글로벌하게 클릭수신과 무시의 각각의 값을 보존해 둡니다.
Window의 TOPOMOST도 변경 가능하게 하고 있으므로, 컨텍스트 메뉴에서의 클릭 투과의 ON/OFF의 판정시에는 TOPPMOST값도 고려해 스위치 하고 있습니다.

    public class G
    {
        //・・・略
        public static int catch_extendStyle;    //拡張WINDOW イベント受け用の保存変数
        public static int through_extendStyle;  //      イベント透過用の保存変数
    }

//・・・中略・・・
        //Icon mode Ignore click event
        protected const int GWL_EXSTYLE = (-20);
        protected const int WS_EX_TRANSPARENT   = 0x00000020; //透過時の値
        protected const int WS_EX_TOPMOST       = 0x00000008; //topmost時の値
        [DllImport("user32")]
        protected static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32")]
        protected static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwLong);
//・・・中略・・・
        protected override void OnSourceInitialized(EventArgs e)
        {
            //Icon Mode時のクリックEventの受け・スルー切り替え

            base.OnSourceInitialized(e);

            //WindowHandle(Win32) を取得
            var handle = new WindowInteropHelper(this).Handle;
            //クリックをキャッチする場合の値を算出して保存
            int extendStyle = GetWindowLong(handle, GWL_EXSTYLE);
            G.catch_extendStyle = extendStyle;
            //クリックをスルーする場合の値を算出して保存
            extendStyle |= WS_EX_TRANSPARENT; //フラグの追加
            G.through_extendStyle = extendStyle;
            //初期はキャッチで設定
            SetWindowLong(handle, GWL_EXSTYLE, G.catch_extendStyle);

        }
//・・・中略・・・
        private void NotifyIcon_MenuItem_Click(object sender, RoutedEventArgs e)
        {
            //ノティファイアイコン上でのコンテキストメニュー全般の処理
            MenuItem selectedItem = (MenuItem)sender;
            switch (selectedItem.Tag.ToString())
            {
                case "0":   //show/hide
                   //・・・中略・・・
                case "8":   //Icon Mode click ignore on/off
                    if (G.MODE == 2)    //ICONモードの場合のみ許可
                    {
                        var handle = new WindowInteropHelper(this).Handle;
                        int extendStyle = GetWindowLong(handle, GWL_EXSTYLE);
                        if (this.Topmost == false)
                        {
                            extendStyle ^= WS_EX_TOPMOST;  //TopMostでない場合はその分の値を減算
                        }
                        if (extendStyle == G.catch_extendStyle)
                        {
                            SetWindowLong(handle, GWL_EXSTYLE, G.through_extendStyle);
                            this.IgnoreEvent.IsChecked = true;
                        }
                        else
                        {
                            SetWindowLong(handle, GWL_EXSTYLE, G.catch_extendStyle);
                            this.IgnoreEvent.IsChecked = false;
                        }
                    }
                    else this.IgnoreEvent.IsChecked = false;
                    break;
                  //・・・中略・・・
            }
        }


이런 느낌이 듭니다.
(클릭수+TOPMOST→클릭 무시→TOPMOST 해제→클릭수로 변화시키고 있습니다)



시보 알림 표시



이런 느낌의 체재로 구현.

좋은 웹페이지 즐겨찾기