<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      C# 窗口過程消息處理 WndProc

      WinForm WndProc

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

      示例:禁止通過關閉按鈕或其他發送 WM_CLOSE 消息的途徑關閉窗口
      protected override void WndProc(ref Message m)
      {
          const int WM_CLOSE = 0x0010;
          if(m.Msg == WM_CLOSE)
          {
              // MessageBox.Show("禁止關閉此窗口");
              return;
          }
          base.WndProc(ref m);
      }
      

      Control 類中還有個 DefWndProc 為默認的窗口過程

      WPF HwndSource

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

      示例:禁止通過關閉按鈕或其他發送 WM_CLOSE 消息的途徑關閉窗口
      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("禁止關閉此窗口");
              handled = true; // 標記為已處理
          }
          return IntPtr.Zero;
      }
      

      WinForm IMessageFilter

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

      IMessageFilter 接口允許程序在將消息調度到控件或窗口之前捕獲消息進行預處理

      IMessageFilter 的 PreFilterMessage 與 Control 的 WndProc 接收到的消息是一個交集關系,應用程序接收到的消息來自系統消息隊列,相對來說更全,但會有部分消息會直接發送到窗口或控件而不進入系統消息隊列

      實現 IMessageFilter 接口實例可對整個線程消息循環進行預處理,并根據 m.HWnd 獲取消息傳入的窗口或控件句柄

      示例:截獲程序鼠標懸浮消息,窗口標題顯示當前懸浮控件名
      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; // 過濾消息不繼續派發
              }
              return false; // 允許消息派發到下一個過濾器或控件
          }
      }
      

      WinForm NativeWindow

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

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

      附加到其他窗口

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

      這里提供一個靜態輔助類,借助 NativeWindow 簡化附加窗口消息過程處理操作
      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) // 窗口銷毀時移除所有 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">消息處理過程移除回調</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);
                  }
              }
          }
      }
      
      posted @ 2025-04-01 09:04  藍點lilac  閱讀(1221)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 激情综合网五月婷婷| 久久国产精品77777| 无码抽搐高潮喷水流白浆| 一区二区三区四区高清自拍| 高清破外女出血AV毛片| 娇小萝被两个黑人用半米长| 国精品午夜福利视频不卡| 亚洲精品动漫一区二区三| jk白丝喷浆| 欧美人与动牲猛交A欧美精品 | 久久综合国产色美利坚| 亚洲国产综合精品2020| 亚洲一本二区偷拍精品| 国产麻豆精品一区二区三区v视界| 免费人妻无码不卡中文18禁| 亚洲一区二区av观看| 香蕉乱码成人久久天堂爱| 久章草在线毛片视频播放| 成人综合婷婷国产精品久久蜜臀| 麻豆果冻国产剧情av在线播放| 黑森林福利视频导航| 少妇被粗大的猛烈进出69影院一| 国产丝袜在线精品丝袜不卡| 野花社区www视频日本| 国产亚洲精品综合99久久| 欧美熟妇乱子伦XX视频| 托克托县| 国产成人精品无人区一区| 国产高潮视频在线观看| 人人人澡人人肉久久精品| 漂亮的人妻不敢呻吟被中出| 亚洲日本高清一区二区三区| 亚洲高潮喷水无码AV电影| 久久国产精品亚洲精品99| 91密桃精品国产91久久| 影视先锋av资源噜噜| 中文字幕99国产精品| 日本污视频在线观看| 18禁无遮拦无码国产在线播放| 精选国产av精选一区二区三区| 国产福利萌白酱在线观看视频 |