WPF 讓視窗激活作為前臺最上層視窗的方法

来源:https://www.cnblogs.com/lindexi/archive/2020/04/22/12749671.html
-Advertisement-
Play Games

在 WPF 中,如果想要使用代碼控制,讓某個視窗作為當前用戶的輸入的邏輯焦點的視窗,也就是在當前用戶活動的視窗的最上層視窗,預設使用 Activate 方法,通過這個方法在大部分設備都可以做到激活視窗 ...


在 WPF 中,如果想要使用代碼控制,讓某個視窗作為當前用戶的輸入的邏輯焦點的視窗,也就是在當前用戶活動的視窗的最上層視窗,預設使用 Activate 方法,通過這個方法在大部分設備都可以做到激活視窗

但是在一些特殊的設備上,使用下麵代碼調起視窗只是在任務欄閃爍圖標,而沒有讓視窗放在最上層

window.Show();
window.Activate();

在大部分設備上,通過 Show 和 Activate 組合可以讓視窗作為當前用戶活動的,即使視窗之前是最小化或隱藏,都可以通過 Show 的方法顯示

但是某些設備視窗被蓋在其他的視窗的下麵,此時的視窗的 window.IsActive 還是 true 但是調用 Activate 不會讓視窗放在上層

我在網上看到好多小伙伴調用了 SetForegroundWindow 方法,其實現在 WPF 是開源的,可以看到 Window 的 Activate 方法是這樣寫

        public bool Activate()
        {
            // this call ends up throwing an exception if Activate
            // is not allowed
            VerifyApiSupported();
            VerifyContextAndObjectState();
            VerifyHwndCreateShowState();

            // Adding check for IsCompositionTargetInvalid
            if (IsSourceWindowNull || IsCompositionTargetInvalid)
            {
                return false;
            }

            return UnsafeNativeMethods.SetForegroundWindow(new HandleRef(null, CriticalHandle));
        }

源代碼請看 github

也就是調用 SetForegroundWindow 和調用 Activate 方法是差不多的,如果調用 Activate 應該調用 SetForegroundWindow 也差不多

通過大佬的 SetForegroundWindow的正確用法 - 子塢 - 博客園 可以瞭解到,需要按照以下步驟

    1.得到視窗句柄FindWindow 
    2.切換鍵盤輸入焦點AttachThreadInput 
    3.顯示視窗ShowWindow(有些視窗被最小化/隱藏了) 
    4.更改視窗的Zorder,SetWindowPos使之最上,為了不影響後續視窗的Zorder,改完之後,再還原 
    5.最後SetForegroundWindow 

在 WPF 中對應的更改視窗的順序使用的是 Topmost 屬性,同時設置順序需要做一定小的更改

在 WPF 中通過 c# - Bring a window to the front in WPF - Stack Overflow 可以瞭解到如何用 AttachThreadInput 方法

整個代碼請看下麵,具體的 win32 方法我就沒有寫出來了,請小伙伴自己添加

        private static void SetWindowToForegroundWithAttachThreadInput(Window window)
        {
            var interopHelper = new WindowInteropHelper(window);
            var thisWindowThreadId = Win32.User32.GetWindowThreadProcessId(interopHelper.Handle, IntPtr.Zero);
            var currentForegroundWindow = Win32.User32.GetForegroundWindow();
            var currentForegroundWindowThreadId = Win32.User32.GetWindowThreadProcessId(currentForegroundWindow, IntPtr.Zero);

            // [c# - Bring a window to the front in WPF - Stack Overflow](https://stackoverflow.com/questions/257587/bring-a-window-to-the-front-in-wpf )
            // [SetForegroundWindow的正確用法 - 子塢 - 博客園](https://www.cnblogs.com/ziwuge/archive/2012/01/06/2315342.html )
            /*
                 1.得到視窗句柄FindWindow 
                2.切換鍵盤輸入焦點AttachThreadInput 
                3.顯示視窗ShowWindow(有些視窗被最小化/隱藏了) 
                4.更改視窗的Zorder,SetWindowPos使之最上,為了不影響後續視窗的Zorder,改完之後,再還原 
                5.最後SetForegroundWindow 
             */
            Win32.User32.AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, true);

            window.Show();
            window.Activate();
            // 去掉和其他線程的輸入鏈接
            Win32.User32.AttachThreadInput(currentForegroundWindowThreadId, thisWindowThreadId, false);

            // 用於踢掉其他的在上層的視窗
            window.Topmost = true;
            window.Topmost = false;

我測試了幾個原本沒有讓視窗放在上層的設備,使用上面的代碼可以設置,但是我不瞭解設置上面代碼可能的坑是什麼

附帶 walterlv 的測試工具,可以用來拿到當前的 GetForegroundWindow 是哪個

walterlv 的工具

另外少君小伙伴寫了一個有趣的庫,裡面封裝了很多 win32 的方法,請看 kkwpsv lsjutil


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 實現一個基於動態代理的 AOP Intro 上次看基於動態代理的 AOP 框架實現,立了一個 Flag, 自己寫一個簡單的 AOP 實現示例,今天過來填坑了 目前的實現是基於 Emit 來做的,後面有時間再寫一個基於 Roslyn 來實現的示例 效果演示 演示代碼: 切麵邏輯定義: 測試服務定義 測 ...
  • 後端:asp.net core web api + EF Core 前端:VUE + Element-UI+ Node環境的後臺管理系統 資料庫:SQL Server2017 伺服器:阿裡雲伺服器 線上地址:http://www.wangjk.wang 賬號:admin 密碼:123 API文檔地址 ...
  • 數組類型 在 C 中,數組實際上是對象,數組是一種數據結構,它包含若幹相同類型的變數。 數組概述 數組具有以下屬性: 數組可以是 "一維" 、 "多維" 或 "交錯" 的。 數值數組元素的預設值設置為零,而引用元素的預設值設置為 null。 交錯數組是數組的數組,因此其元素是引用類型並初始化為 nu ...
  • 劍指Offer題目,求數值的整數次方,題目描述,給定一個double類型的浮點數base和int類型的整數exponent。求base的exponent次方。保證base和exponent不同時為0。包括遞歸,整數的快速冪等多種解法 ...
  • 場景 有時會遇到使用枚舉類型的時候。 比如傳遞過來一個int的list,要根據這個list將對應的chekbox選中。 首先新建一個類KillComponents public enum KillComponents { /// <summary> /// 上霧化器 /// </summary> S ...
  • 昨天有朋友在公眾號發消息說看不懂await,async執行流,其實看不懂太正常了,因為你沒經過社會的毒打,沒吃過牢飯就不知道自由有多重要,沒生過病就不知道健康有多重要,沒用過ContinueWith就不知道await,async有多重要,下麵我舉兩個案例佐證一下? 一:案例一 【嵌套下的非同步】 寫了 ...
  • 在較早隨筆《微信小程式結合後臺數據管理實現商品數據的動態展示、維護》中介紹過使用小程式實現商品的展示,其實基於對應的介面,我們使用H5頁面來開發基於公眾號的商品展示和支付,也是產不多的原理,不過H5頁面和小程式的界面處理代碼有一些差異吧了,整體的實現思路倒是差不多的。本篇隨筆介紹基於H5頁面的開發,... ...
  • .netcore3.1在iis中發佈需要安裝 Hosting Bundle和 ASP.NET Core Runtime 3.1.2,但安裝了hosting宿主之後其他站點就會掛掉,不可訪問。 解決方案:1、停止IIS2、修改 C:\Windows\System32\inetsrv\config\ap ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...