超碰人人人人人,色婷婷综合久久久久中文一区二区,国产-第1页-浮力影院,欧美老妇另类久久久久久

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C# 窗口過程消息處理 WndProc

freeflydom
2025年4月7日 16:50 本文熱度 95

在 WinForm 中一般采用重寫 WndProc 的方法對(duì)窗口或控件接受到的指定消息進(jìn)行處理

示例:禁止通過關(guān)閉按鈕或其他發(fā)送 WM_CLOSE 消息的途徑關(guān)閉窗口

protected override void WndProc(ref Message m)

{

   const int WM_CLOSE = 0x0010;

   if(m.Msg == WM_CLOSE)

   {

       // MessageBox.Show("禁止關(guān)閉此窗口");

       return;

   }

   base.WndProc(ref m);

}

Control 類中還有個(gè) DefWndProc 為默認(rèn)的窗口過程

WPF HwndSource

WPF 僅本機(jī)窗口或 HwndHost 嵌入控件擁有句柄,可通過 HwndSource 添加消息處理

示例:禁止通過關(guān)閉按鈕或其他發(fā)送 WM_CLOSE 消息的途徑關(guān)閉窗口

HwndSource source = null;



protected override void OnSourceInitialized(EventArgs e)

{

   base.OnSourceInitialized(e);

   IntPtr handle = new WindowInteropHelper(this).Handle;

   source = HwndSource.FromHandle(handle);

   source.AddHook(WndProc);

}



protected override void OnClosed(EventArgs e)

{

   source?.RemoveHook(WndProc);

   base.OnClosed(e);

}



private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)

{

   const int WM_CLOSE = 0x0010;

   if(msg == WM_CLOSE)

   {

       // MessageBox.Show("禁止關(guān)閉此窗口");

       handled = true; // 標(biāo)記為已處理

   }

   return IntPtr.Zero;

}

WinForm IMessageFilter

? 注意:1.消息過濾器對(duì)于特定線程是唯一的;2.使用消息過濾器可能會(huì)降低程序性能

IMessageFilter 接口允許程序在將消息調(diào)度到控件或窗口之前捕獲消息進(jìn)行預(yù)處理

IMessageFilter 的 PreFilterMessage 與 Control 的 WndProc 接收到的消息是一個(gè)交集關(guān)系,應(yīng)用程序接收到的消息來自系統(tǒng)消息隊(duì)列,相對(duì)來說更全,但會(huì)有部分消息會(huì)直接發(fā)送到窗口或控件而不進(jìn)入系統(tǒng)消息隊(duì)列

實(shí)現(xiàn) IMessageFilter 接口實(shí)例可對(duì)整個(gè)線程消息循環(huán)進(jìn)行預(yù)處理,并根據(jù) m.HWnd 獲取消息傳入的窗口或控件句柄

示例:截獲程序鼠標(biāo)懸浮消息,窗口標(biāo)題顯示當(dāng)前懸浮控件名

static class Program

{

   [STAThread]

   static void Main()

   {

       Application.EnableVisualStyles();

       Application.SetCompatibleTextRenderingDefault(false);

       var filter = new SampleMsgFilter();

       Application.AddMessageFilter(filter); // 添加到消息泵

       Application.Run(new MainForm());

       Application.RemoveMessageFilter(filter); // 從消息泵移除

   }

}



sealed class SampleMsgFilter : IMessageFilter

{

   public bool PreFilterMessage(ref Message m)

   {

       const int WM_MOUSEHOVER = 0x02A1;

       if(m.Msg == WM_MOUSEHOVER && Control.FromHandle(m.HWnd) is Control ctr)

       {

           ctr.FindForm().Text = ctr.Name;

           return true; // 過濾消息不繼續(xù)派發(fā)

       }

       return false; // 允許消息派發(fā)到下一個(gè)過濾器或控件

   }

}

WinForm NativeWindow

NativeWindow 是 IWin32Window 的低級(jí)封裝,并且和 WinForm Control 一樣擁有 WndProc 和 DefWndProc 方法,故同樣可通過重寫 WndProc 方法處理消息

可以通過 CreateHandle(new CreateParams()) 創(chuàng)建沒有 UI 的僅消息循環(huán)的窗口。比如托盤圖標(biāo)類 NotifyIcon 內(nèi)部會(huì)創(chuàng)建一個(gè) NativeWindow 用來接收任務(wù)欄創(chuàng)建消息 WM_TASKBARCREATED ("TaskbarCreated"),在資源管理器崩潰重啟后重新創(chuàng)建圖標(biāo)。

附加到其他窗口

由于 WinForm Control WndProc 是密封的,處理消息時(shí)必須繼承類型并重寫,需要單獨(dú)進(jìn)行消息處理的窗口或控件較多時(shí),對(duì)原代碼具有很大的侵入性;而 IMessageFilter 是針對(duì)整個(gè)應(yīng)用程序的消息循環(huán),官方文檔說使用消息過濾器很可能會(huì)降低程序性能;相對(duì)來說,由于 HwndSource AddHook 和 RemoveHook 不是密封的,WPF 程序可以在不侵入原代碼的條件下處理窗口消息,在可復(fù)用性上面反而還具有優(yōu)勢(shì)。但如果仔細(xì)看看 NativeWindow 源代碼,會(huì)發(fā)現(xiàn)它內(nèi)部調(diào)用了 SetWindowLong GWL_WNDPROC (窗口子類化),可以通過 AssignHandle 附加到任意窗口或控件進(jìn)行消息處理,這個(gè)窗口不限制類型,甚至可以附加到其他程序窗口。

這里提供一個(gè)靜態(tài)輔助類,借助 NativeWindow 簡(jiǎn)化附加窗口消息過程處理操作

using System;

using System.Collections.Generic;

using System.Windows.Forms;



namespace Wondershare.WinTool.Helpers

{

 public delegate bool HookProc(ref Message m);



   public static class MessageHooker

   {

       sealed class HookWindow : NativeWindow

       {

           List<KeyValuePair<HookProc, Action>> hooks;



           public HookWindow(IntPtr hWnd)

           {

               AssignHandle(hWnd);

           }



           public void AddHookProc(HookProc hook, Action removedHandler)

           {

               if (hooks == null)

               {

                   hooks = new List<KeyValuePair<HookProc, Action>>();

               }

               hooks.Insert(0, new KeyValuePair<HookProc, Action>(hook, removedHandler));

           }



           public void RemoveHookProc(HookProc hook)

           {

               if (hooks != null)

               {

                   for (int i = hooks.Count - 1; i >= 0; i--)

                   {

                       if (hooks[i].Key == hook)

                       {

                           hooks[i].Value?.Invoke();

                           hooks.RemoveAt(i);

                       }

                   }

               }

           }



           protected override void WndProc(ref Message m)

           {

               if (hooks != null)

               {

                   foreach (var hook in hooks)

                   {

                       if (hook.Key(ref m)) return;

                   }

                   const int WM_NCDESTORY = 0x0082;

                   if (m.Msg == WM_NCDESTROY) // 窗口銷毀時(shí)移除所有 hook

                   {

                       for (int i = hooks.Count - 1; i >= 0; i--)

                       {

                           hooks[i].Value?.Invoke();

                       }

                       hooks = null;

                   }

                   base.WndProc(ref m);

               }

           }

       }



       /// <summary>附加消息處理過程到窗口</summary>

       /// <param name="handle">需要附加消息處理過程的窗口句柄</param>

       /// <param name="hook">消息處理過程</param>

       /// <param name="removedHandler">消息處理過程移除回調(diào)</param>

       public static void AddHook(IntPtr handle, HookProc hook, Action removedHandler = null)

       {

           if (!(NativeWindow.FromHandle(handle) is HookWindow window))

           {

               window = new HookWindow(handle);

           }

           window.AddHookProc(hook, removedHandler);

       }



       /// <summary>從窗口移除附加的消息處理過程</summary>

       /// <param name="handle">需要移除消息處理過程的窗口句柄</param>

       /// <param name="hook">消息處理過程</param>

       public static void RemoveHook(IntPtr handle, HookProc hook)

       {

           if (NativeWindow.FromHandle(handle) is HookWindow window)

           {

               window.RemoveHookProc(hook);

           }

       }

   }

}

該文章在 2025/4/7 16:51:04 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved