이제 WPF로 바꿔보세요 (13)
11068 단어 VisualStudioVisualBasicC#WPF
클릭 투과 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 해제→클릭수로 변화시키고 있습니다)
시보 알림 표시
이런 느낌의 체재로 구현.
Reference
이 문제에 관하여(이제 WPF로 바꿔보세요 (13)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Insetrect/items/bbff192e04b6a4bf60d1
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
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;
//・・・中略・・・
}
}
Reference
이 문제에 관하여(이제 WPF로 바꿔보세요 (13)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Insetrect/items/bbff192e04b6a4bf60d1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)