WPF與Win32互操作


一、WPF如何使用HWND

        當您創建WPF Window時,WPF會創建頂級HWND,並使用HwndSource將Window及其WPF內容放入HWND中。應用程序中其余的WPF內容共享此單個HWND。不過,菜單、組合框下拉列表和其他彈出窗口例外。 這些元素創建它們自己的頂級窗口,這正是 WPF 菜單能跳出包含它的窗口 HWND 之外的原因。

二、HwndSource類

        一個HwndSource實現Win32窗口可以包含WPF內容。在窗口中的WPF內容是可安排的,可測量的,和可渲染的;是可交互式輸入的。因為HwndSource是專被設計來與Win32進行交互的,這個類展示了底層的Win32的特點。您可以使用這個類執行以下操作:

  • 指定窗口樣式、窗口類樣式和擴展窗口樣式。
  • 在窗口程序的鈎子中添加處理函數。
  • 提供窗口句柄(HWND)。
  • 銷毀窗口。

         HwndSource類被設計來用於處理一般的互操作,並不是被設計成一個包裝管理HWND的角色。一般來說,它不提供用於管理窗口或檢查屬性狀態的托管方法。相反,該HwndSource類可以通過Handle屬性訪問Win32窗口句柄(HWND),可以通過PInvoke Win32 API技術操作窗口。
1 創建
        HwndSource只能在構造時被指定。創建一個HwndSource,首先要創建一個HwndSourceParameters結構並用所需的參數填充它。這些參數包括以下內容:

  • 類、窗口和擴展的窗口樣式。您必須在窗口被創建前使用PInvoke去改變樣式。並非所有樣式都可以在創建窗口后更改。更改窗口樣式之前請參考win32文檔。
  • 窗口的初始位置。
  • 窗口的初始大小,包括是否指定尺寸或以WPF內容大小的確定窗口的大小。
  • 父窗口。
  • HwndSourceHook包括窗口的處理函數鏈。如果在構建時指定鈎子,它將接收窗口的所有消息。你可以使用AddHook后創建窗口添加一個鈎子。
  • 透明度設置。

2 對象生存周期
        HwndSource是正規的公共語言運行庫(CLR)對象,其生命周期是由垃圾收集器管理。因為HwndSource代表非托管資源,所以HwndSource實現IDisposable接口。如果從所有者線程調用,同步調用處理立即破壞win32窗口。如果從另一個線程調用,win32窗口將異步銷毀。在互操作的代碼中顯式調用Dispose可能對某些互操作場景是必要的。
3 窗口處理函數
        HwndSource類實現了它自己的窗口處理函數。此窗口處理函數用於處理重要的窗口消息,如與布局、呈現和輸入相關的消息。不過,您也可以在鈎子上添加自己的處理函數。你可以在構造時,通過設置HwndSourceParameters.HwndSourceHook屬性,在鈎子中指定自己的處理函數,或者你也可以使用AddHook和RemoveHook在窗口創建之后添加和刪除鈎子中的處理函數。

三、HwndSource類

        該例子中在鈎子中擴展處理函數。

// 在Window類中
protected overried void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);
    // 獲取窗體句柄
    IntPtr hwnd = new WindowInteropHelper(this).Handle;
    // 獲取HwndSource對象
    HwndSource hwndSource = HwndSource.FromHwnd(hwnd);
    // 向鈎子中添加處理程序
    if(hwndSource != null)
        hwndSource.AddHook(WndProc);
}

private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wideParam, IntPtr longParam, ref bool handled)
{
    swicth(msg)
    {
        // 對特定消息進行處理
    }
    return IntPtr.Zero;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM