/// <summary> /// 最前面ウィンドウと、そのメニューや右クリックメニューウィンドウ群のRectリストを作成 /// </summary> /// <returns></returns> private List <Rect> MakeForeWinndwWithMenuWindowRectList() { List <Rect> result = new(); //Foregroundのハンドル取得 IntPtr fore = API.GetForegroundWindow(); var infoFore = GetWindowRectAndText(fore); //ForegroundのPopupハンドルとRect取得 IntPtr popup = API.GetWindow(fore, API.GETWINDOW_CMD.GW_ENABLEDPOPUP); Rect popupRect = GetWindowRect(popup); var infoPop = GetWindowRectAndText(popup);//確認用 //Popupが存在する(Rectが0じゃない)場合 if (popupRect != new Rect(0, 0, 0, 0)) { //PopupのNEXT(下にあるウィンドウハンドル)を収集 List <IntPtr> pops = GetCmdWindows(popup, API.GETWINDOW_CMD.GW_HWNDNEXT, LOOP_LIMIT); var infoPops = GetWindowRectAndTexts(pops);//確認用 //必要なRectだけを選別 result = SelectRects(pops); ////Textを持つウィンドウ以降を除去 ////残ったウィンドウのRect取得 ////ドロップシャドウウィンドウのRectを除去 ////前後のRectが重なっているところまで選択して、以降は除外 //GetForegroundwindowの見た目通りのRectを追加 result.Add(GetWindowRectMitame(fore)); } //Popupが存在しない(Rectが0)場合 else { //GetForegroundwindowの見た目通りのRectを追加 Rect foreRect = GetWindowRectMitame(fore); result.Add(foreRect); //マウスカーソル下のウィンドウハンドル取得、これを基準にする API.GetCursorPos(out API.POINT cursorP); IntPtr cursor = API.WindowFromPoint(cursorP); //Rect cursorRect = GetWindowRectMitame(cursor); //カーソル下のウィンドウRectとForegroundのRect重なり判定 //関係あるウィンドウなら、Textがない and Rectが重なっている //重なりはメニューウィンドウ全域と重なっていればおk判定にする List <Rect> rs = new(); if (GetWindowText(cursor) == "") { //基準の上下それぞれのウィンドウハンドル取得 List <IntPtr> prev = GetCmdWindows(cursor, API.GETWINDOW_CMD.GW_HWNDPREV, LOOP_LIMIT); //上 List <IntPtr> next = GetCmdWindows(cursor, API.GETWINDOW_CMD.GW_HWNDNEXT, LOOP_LIMIT); //下 //必要なRectだけを選別 List <Rect> rsPrev = SelectRects(prev); List <Rect> rsNext = SelectRects(next); //前後のRectリストを統合 rs = rsPrev.Union(rsNext).ToList(); } //重なり判定はForegroundのRectと、それ以外のRectを結合したRectで判定する //Rectの結合はGeometryGroupを使う GeometryGroup gg = new(); for (int i = 0; i < rs.Count; i++) { gg.Children.Add(new RectangleGeometry(rs[i])); } //重なり判定、重なっていたらForegroundのRect+それ以外のRect if (IsOverlapping(gg, new RectangleGeometry(foreRect))) { result = result.Union(rs).ToList(); } //重なっていない場合はメニューウィンドウは開かれていないと判定して //ForegroundのウィンドウRectだけでいい } return(result); }
//ウィンドウハンドルからRECT取得 private static API.RECT GetWindowAPIRECT(IntPtr hWnd) { _ = API.GetWindowRect(hWnd, out API.RECT re); return(re); }
//アプリのウィンドウが非アクティブ状態でも任意のキーの入力を感知、WPFでグローバルホットキーの登録 //https://gogowaten.hatenablog.com/entry/2020/12/11/132125 private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { //ホットキーの登録解除 _ = API.UnregisterHotKey(MyWindowHandle, HOTKEY_ID1); ComponentDispatcher.ThreadPreprocessMessage -= ComponentDispatcher_ThreadPreprocessMessage; }
//ウィンドウハンドルからRect取得 private Rect GetWindowRect(IntPtr hWnd) { _ = API.GetWindowRect(hWnd, out API.RECT re); return(MyConverterApiRectToRect(re)); }