日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C# 消息处理学习总结

發布時間:2025/4/14 C# 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# 消息处理学习总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

C# 收發和處理自定義的WINDOWS消息

http://blog.sina.com.cn/s/blog_45eaa01a01013zbs.html


  為了程序啟動后自動執行主函數,在Form1_Load中直接執行啟動函數,可能造成沒有


反應。當然,在Form1_Load中加入較長時間(比如2秒)的定時器,在定時器函數中關閉


定時器(僅需要執行一次),再執行主函數會好些,但是我們不知道初始話的精確時間,這


樣的方法也存在危險。
  我們知道WINDOWS應用程序是靠消息驅動的,最好的方法就是在Form1_Load中發送


消息,自己截獲消息后,才開始執行比較安全。下面分3步說明相關的方法步驟。
?
一、創建一個 C# 項目,并選擇 Windows 應用程序,名稱默認


WindowsFormsApplication1
?
  為了簡單,所有項目都按默認值處理。


二、添加處理Windows 消息的方法,即重載 DefWndProc方法
  點選菜單[視圖]->[對象瀏覽器],打開對象瀏覽窗口(有的可能在[其他窗口]),在其中找


到自己應用程序名WindowsFormsApplication1(一般在最下部),展開它并選中基類型Form


,這時在右邊的窗口列出所有Form類的成員函數,你也可以更改本窗口上邊的[對象瀏覽器


設置],從中勾選更多選項,以便出現更多的函數,如圖所示:
protected override void DefWndProc(ref System.Windows.Forms.Message m)


  我們選中DefWndProc(ref System.Windows.Forms.Message),此時在下面窗口會顯


示完整的函數protected override void DefWndProc(ref?


System.Windows.Forms.Message m),我們右擊這行說明字符串,點選復制將其復制下來


。轉到窗口Form1.cs,粘貼到Form1類里面,注意前面的override關鍵字,適當修改就可以


處理自定義消息了。
  protected override void DefWndProc(ref System.Windows.Forms.Message m)
  {
   ? switch (m.Msg)
    {
    ? ?case USER+1:
    ? ? //string message = string.Format("收到自己消息的參數:{0},{1}", m.WParam,?


m.LParam);
      //處理啟動 函數MessageBox.Show(message);//顯示一個消息框
      StartProcess();
       ?break;
     default:
      ? ?base.DefWndProc(ref m);//一定要調用基類函數,以便系統處理其它消息。
       break;
   ? ?}
  }
三、引入發送消息的函數
  我們需要PostMessage發送自定義消息,所以用如下語句引用它:
  [DllImport("user32.dll")]
  public static extern void PostMessage(IntPtr hWnd, int msg, int wParam, int?


lParam);
  自定義消息號一般開始于0x0400,也定義一個常量 public const int USER = 0x0400;
這樣就可以在Form1_Load中發送消息,以便自動開始執行程序。
  private void Form1_Load(object sender, EventArgs e)
  {
   ? //Thread.Sleep(100); //等待100毫秒
   ? PostMessage(this.Handle, USER + 1, 168, 51898);
  }
四 引用關鍵字的命名空間
  對于上面的關鍵字DllImport,字符要正確,大小寫也要正確,此時是黑色字體,還不認


識,那就需要引用它的命名空間,方法如下,使用鼠標右擊關鍵字DllImport,——解析—


—點選using System.Runtime.InteropServices ,即將所用的命名空間using?


System.Runtime.InteropServices;加入到項目中,關鍵字DllImport的字體變成綠色。


五 完整代碼如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
? ? public partial class Form1 : Form
? ? {
? ? ? ? public const int USER = 0x0400;//用戶自定義消息的開始數值
?
? ? ? ? [DllImport("user32.dll")]
? ? ? ? public static extern void PostMessage(IntPtr hWnd, int msg, int wParam, int?


lParam);


? ? ? ? public Form1()
? ? ? ? {
? ? ? ? ? ? InitializeComponent();
? ? ? ? }
? ? ? ? private void Form1_Load(object sender, EventArgs e)
? ? ? ? {
? ? ? ? ? ? //Thread.Sleep(100); //等待100毫秒
? ? ? ? ? ? PostMessage(this.Handle, USER + 1, 168, 51898);
? ? ? ? }
? ? ? ? private void StartProcess()
? ? ? ? {
? ? ? ? ? ? MessageBox.Show("具備條件,可以正常運行了!");
? ? ? ? }
? ? ? ? protected override void DefWndProc(ref System.Windows.Forms.Message m)
? ? ? ? {
? ? ? ? ? ? switch (m.Msg)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? case USER+1:
? ? ? ? ? ? ? ? ? ? //string message = string.Format("收到自己消息的參數:{0},{1}",?


m.WParam, m.LParam);
? ? ? ? ? ? ? ? ? ? StartProcess();
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? base.DefWndProc(ref m);//一定要調用基類函數,以便系統處理其它消息。
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
六 有關的圖片
? ?點此查看有關 的圖片
C# <wbr>收發和處理自定義的WINDOWS消息
1.建立項目的圖片


C# <wbr>收發和處理自定義的WINDOWS消息
2.彈出對象瀏覽器的圖片


C# <wbr>收發和處理自定義的WINDOWS消息
3.選擇基類型Form的圖片說明


C# <wbr>收發和處理自定義的WINDOWS消息
4.對象瀏覽器設置的圖片說明


C# <wbr>收發和處理自定義的WINDOWS消息
5.加入重載方法DefWndProc的圖片說明


C# <wbr>收發和處理自定義的WINDOWS消息
6.引用關鍵字命名空間的圖片說明
?
==更多可以參考網上內容==
==1==
?c# Windows消息列表
http://www.beijibear.com/index.php?aid=139
==2==
「C#:windows消息大全-詳細-有解釋」
http://www.mox.cc/018e4d33b5bc0402-ddec43ad9d5cedd0.htm
==3==
c# Windows消息處理過程探究
http://blog.csdn.net/jjjfox/article/details/7360378
 
一、消息概述
? ? Windows下應用程序的執行是通過消息驅動的。消息是整個應用程序的工作引擎,我們


需要理解掌握編程語言是如何封裝消息的原理。
1 什么是消息(Message)
? ? 消息就是通知和命令。在.NET框架類庫中的System.Windows.Forms命名空間中微軟采


用面對對象的方式重新定義了Message。新的消息(Message)結構的公共部分屬性基本與早


期的一樣,不過它是面對對象的。
? ? 公共屬性:
? ? HWnd ? ?獲取或設定消息的處理函數
? ? Msg ? ? 獲取或設定消息的ID號
? ? Lparam ?指定消息的LParam字段
? ? Wparam ?指定消息的WParam字段
? ? Result ?指定為響應消息處理函數而向OS系統返回的值
2 消息驅動的過程
? ?所有的外部事件,如鍵盤輸入、鼠標移動、按動鼠標都由OS系統轉換成相應的消息發送到


應用程序的消息隊列。每個應用程序都有一段相應的程序代碼來檢索、分發這些消息到對應


的窗體,然后由窗體的處理函數來處理。
二、C#中的消息的封裝
? ? C#對消息重新進行了面對對象的封裝,在C#中消息被封裝成了事件。
? ? System.Windows.Forms.Application類具有用于啟動和停止應用程序和線程以及處理


Windows消息的方法。
? ? 調用Run以啟動當前線程上的應用程序消息循環,并可以選擇使其窗體可見。
? ? 調用Exit或ExitThread來停止消息循環。
? ? C#中用Application類來處理消息的接收和發送的。消息的循環是由它負責的。
? ? 從本質上來講,每個窗體一般都對應一個窗體過程處理函數。那么,C#的一個Form實例(


相當于一個窗體)收到消息后是如何處理消息的?其實,這個問題的分析也就是展示了C#的


消息封裝原理。
三、C#中消息的工作流程:
? 1、 Application類有一個AddMessageFilter的靜態方法,通過它我們可以添加消息篩選器


,以便在向目標傳遞Windows消息時,檢視這些消息。
? ? ? ?使用消息篩選器來防止引發特定事件,或在將某事件傳遞給事件處理程序之前使用消息


篩選器對其執行特殊操作。
? ? ?我們必須提供IMessageFilter接口的一個實現,然后才可以使用消息篩選器。
? 2、 C#中的消息被Application類從應用程序消息隊列中取出,如果有消息篩選器,先執行


消息篩選, 然后分發到消息對應的窗體。
? ? ? 1)窗體對象的第一個響應函數是窗口過程函數,即對象中的protected override void?


WndProc(ref System.Windows.Forms.Message e)方法。
? ? ? 2)再根據消息的類型調用默認的消息響應函數(如OnMouseDown)
? ? ? ? 3)再根據用戶自定義的事件處理函數,按訂閱順序分別執行(如


Form1_MouseDown1)。
?
四、示例:


namespace WindowsApplication27
{
? ? partial class Form1
? ? {
? ? ? ? ///
? ? ? ? /// 必需的設計器變量。
? ? ? ? ///
? ? ? ? private System.ComponentModel.IContainer components = null;
? ? ? ? ///
? ? ? ? /// 清理所有正在使用的資源。
? ? ? ? ///
? ? ? ? /// 如果應釋放托管資源,為 true;否則為 false。
? ? ? ? protected override void Dispose(bool disposing)
? ? ? ? {
? ? ? ? ? ? if (disposing && (components != null))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? components.Dispose();
? ? ? ? ? ? }
? ? ? ? ? ? base.Dispose(disposing);
? ? ? ? }
? ? ? ? #region Windows 窗體設計器生成的代碼
? ? ? ? ///
? ? ? ? /// 設計器支持所需的方法 - 不要
? ? ? ? /// 使用代碼編輯器修改此方法的內容。
? ? ? ? ///
? ? ? ? private void InitializeComponent()
? ? ? ? {
? ? ? ? ? ? this.SuspendLayout();
? ? ? ? ? ? //
? ? ? ? ? ? // Form1
? ? ? ? ? ? //
? ? ? ? ? ? this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
? ? ? ? ? ? this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
? ? ? ? ? ? this.ClientSize = new System.Drawing.Size(292, 266);
? ? ? ? ? ? this.Name = "Form1";
? ? ? ? ? ? this.Text = "Form1";
? ? ? ? ? ? //這里訂閱了事件
? ? ? ? ? ? this.MouseDown += new System.Windows.Forms.MouseEventHandler


(this.Form1_MouseDown);
? ? ? ? ? ? this.ResumeLayout(false);
? ? ? ? }
? ? ? ? #endregion
? ? }
}
?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication27
{ ? ??
? ? public partial class Form1 : Form
? ? {
? ? ? ? public Form1()
? ? ? ? {
? ? ? ? ? ? InitializeComponent();
? ? ? ? ? ? Application.AddMessageFilter((new msgFilter()));
? ? ? ? }
? ? ? ? private void Form1_MouseDown(object sender, MouseEventArgs e)
? ? ? ? {
? ? ? ? ? ? MessageBox.Show("3");
? ? ? ? }
? ? ? ? protected override void OnMouseDown(MouseEventArgs e)
? ? ? ? {
? ? ? ? ? ? MessageBox.Show("2");
? ? ? ? ? ? base.OnMouseDown(e);
? ? ? ? }


? ? ? ? protected override void WndProc(ref Message m)
? ? ? ? {
? ? ? ? ? ? //MouseDown Msg Id
? ? ? ? ? ? if (m.Msg==0x0201)
? ? ? ? ? ? ? ? MessageBox.Show("1");
? ? ? ? ? ? base.WndProc(ref m);
? ? ? ? }
? ? }
? ? public class msgFilter : IMessageFilter
? ? {
? ? ? ? public bool PreFilterMessage(ref Message m)
? ? ? ? {
? ? ? ? ? ? if (m.Msg == 0x0201)
? ? ? ? ? ? ? ? MessageBox.Show("0");
? ? ? ? ? ? return false;
? ? ? ? }
? ? }
? ? static class Program
? ? {
? ? ? ? ///
? ? ? ? /// 應用程序的主入口點。
? ? ? ? ///
? ? ? ? [STAThread]
? ? ? ? static void Main()
? ? ? ? {
? ? ? ? ? ? Application.EnableVisualStyles();
? ? ? ? ? ? Application.SetCompatibleTextRenderingDefault(false);
? ? ? ? ? ? Application.Run(new Form1());
? ? ? ? }
? ? }
}
========

C#中消息處理機制(事件與委托)

http://blog.sina.com.cn/s/blog_87a692aa0101q8pl.html


編寫過Windows桌面應用程序的人都知道,微軟的Windows操作系統與應用程序之間的通


信絕大部分是基于消息循環機制的。在VC++中,程序使用GetMessage,


TranslateMessage,DispatchMessage語句從消息隊列中獲取消息,轉換消息并且將消息


分發到目標窗口的過程函數,并由過程函數對不同的Windows消息進行分別處理。
當你將開發平臺轉向C#的時候,由于C#對消息進行了面向對象的封裝,消息被封裝成了事


件,使我們對消息傳送機制的理解蒙上了一層迷霧,下面我們就從實際的代碼著手,抽絲剝


繭,逐步了解C# WinForm中的消息處理機制.當我們新建一個WinForm程序后在


Program.cs中我們看到Application.Run(new Form1());Application類具有用于啟動和停止


應用程序和線程以及處理Windows消息的方法。通過此語句,當前線程上開始運行標準應用


程序消息循環,并使指定窗口可見,消息循環被封裝進了Application類的Run()靜態方法中


。程序結束時調用Exit或者ExitThread來停止消息循環,程序也就隨之終止?! ∥覀優?


Form1窗體中創建鼠標點擊事件MyClick,程序自動為我們增加一些代碼。


this.MouseClick+=new System.Windows.Forms.MouseEventHandler(this.MyClick);上


面this.MouseClick是C#中定義的鼠標單擊事件。它被定義為: public event?


MouseEventHandler MouseClick;而MouseEventHandler的定義是public delegate void?


MouseEventHandler(object sender, MouseEventArgs e);該語句定義了一個名為


MouseEventHandler的委托,那什么是委托呢?  委托類型可以理解成在C++中的函數


指針,但不同的是,委托是完全面向對象的,同時封裝了對象的實例和方法。本質上,委托


把一個實例和該實例上的方法函數封裝成一個可調用的實體,它是面向對象的、安全的.我們


可以把第一句代碼理解成為this.MouseClick事件添加了一個指向MyClick處理函數的函數指


針。C#中事件的處理方法需要使用委托類型對事件進行注冊.當然,你也可以再次調用這句語


句對事件添加另一個處理函數如MyClick2,這些對該事件的處理會形成處理函數列表。則在


程序運行過程中點擊鼠標后在完成MyClick函數后會繼續運行MyClick2函數。
由上我們可以大致猜測其封裝過程:  
Application類將對象發送過來的消息從應用程序消息隊列中提取出來后,分發到相應的窗體


,并轉換成事件。NET框架定義了一個特殊的類型(Delegate委托),該類型提供函數指針的


功能。這樣,委托就等效于一個類型安全的函數指針或一個回調函數。C#中通過Delegate委


托機制將事件與響應函數的函數地址關聯起來,并形成一種函數指針列表,當消息到來的時


候,即可通過這些函數指針列表逐一調用這些響應函數。我們通過以下方法自定義一個事件


觸發,來驗證我們以上的猜測。我們通過手動添加代碼來實現自定義的代理事件(同VC++


中的自定義消息)?
1、聲明事件委托。此處int para僅是方便實驗,代表所需要的參數列表,但要注意參數列表


需要和第3步的參數列表相統一。 public delegate void MyEventHandler(int para);
?2、聲明事件,event 關鍵字用于在發行者類中聲明事件,委托MyEventHandler作為事件


的類型。 public event MyEventHandler MyEvent;
3、添加事件的處理程序(響應事件的方法)。 public void OnMyEvent(int para) {?


MessageBox.Show(""事件觸發,參數為:""+para); }
?4、將指定的事件處理程序邦定到要處理的事件上(訂閱事件),注意,此語句需要寫在程序


執行語句中,如Form_Lord函數內。 this.MyEvent += new MyEventHandler


(OnMyEvent);
?5、觸發事件(調用事件的觸發方法)。 MyEvent(3);?
?6、通過事件委托的回調,執行我們需要的事件處理程序。彈出消息框“事件觸發,參數


為:3”。
?以上實驗可以得出結論,C#中的消息通過Application轉換成事件以后,通過以上6個步驟完


成了事件與處理程序之間的對應關系,在用戶觸發事件以后,相應的時間處理程序得到準確


執行。也可通過以上方法,增加用戶自定義事件。
========

c#消息處理 ?

http://blog.163.com/zhouchunping_99/blog/static/78379988201052914755764/


一、消息概述?


? ? ?Windows下應用程序的執行是通過消息驅動的。消息是整個應用程序的工作引擎,我們


需要理解掌握我們使用的編程語言是如何封裝消息的原理。?


1 什么是消息(Message)?


? ? ?消息就是通知和命令。在.NET框架類庫中的System.Windows.Forms命名空間中微軟采


用面對對象的方式重新定義了Message。新的消息(Message)結構的公共部分屬性基本與早


期的一樣,不過它是面對對象的。?
? ? ?公共屬性:?


? ? ?HWnd ? ? 獲取或設定消息的處理函數?
? ? ?Msg ? ? ?獲取或設定消息的ID號?
? ? ?Lparam ? 指定消息的LParam字段?
? ? ?Wparam ? 指定消息的WParam字段?
? ? ?Result ? 指定為響應消息處理函數而向OS系統返回的值?


2 消息驅動的過程?


? ? ?所有的外部事件,如鍵盤輸入、鼠標移動、按動鼠標都由OS系統轉換成相應的消息發送


到應用程序的消息隊列。每個應用程序都有一段相應的程序代碼來檢索、分發這些消息到對


應的窗體,然后由窗體的處理函數來處理。?


二、C#中的消息的封裝?


? ? ?C#對消息重新進行了面對對象的封裝,在C#中消息被封裝成了事件。?
? ? ?System.Windows.Forms.Application類具有用于啟動和停止應用程序和線程以及處理


Windows消息的方法。?
? ? ?調用Run以啟動當前線程上的應用程序消息循環,并可以選擇使其窗體可見。?
? ? ?調用Exit或ExitThread來停止消息循環。?
? ? ?C#中用Application類來處理消息的接收和發送的。消息的循環是由它負責的。
? ? ?從本質上來講,每個窗體一般都對應一個窗體過程處理函數。那么,C#的一個Form實例


(相當于一個窗體)收到消息后是如何處理消息的?其實,這個問題的分析也就是展示了C#的


消息封裝原理。?


? ? ?實現鼠標左鍵按下的消息的響應(WM_LBUTTONDOWN)?


? ? ?this.MouseDown += new System.Windows.Forms.MouseEventHandler


(this.Form1_MouseDown1);?
? ? ?this.MouseDown += new System.Windows.Forms.MouseEventHandler


(this.Form1_MouseDown2);?


? ? ?private void Form1_MouseDown1(object sender,?


System.Windows.Forms.MouseEventArgs e)?
? ? ?{?
? ? ? ? ?if(e.Button==System.Windows.Forms.MouseButtons.Left)?
? ? ? ?System.Windows.Forms.MessageBox.Show("消息被Form1_MouseDown1函數響應


");?
? ? ?}?


? ? ?private void Form1_MouseDown2(object sender,?


System.Windows.Forms.MouseEventArgs e)?
? ? ?{?
? ? ? if(e.Button==System.Windows.Forms.MouseButtons.Left)?
? ? ? ?System.Windows.Forms.MessageBox.Show("消息被Form1_MouseDown2函數響應


");?
? ? ?}?
? ? ?
? ? ?上面this.MouseDown是C#中的一個事件。它的定義如下:?


? ? ?public event MouseEventHandler MouseDown;?
? ? ?
? ? ?而MouseEventHandler的定義為:?


? ? ?public delegate void MouseEventHandler( object sender,MouseEventArgs e);?


? ? ?實際上,上面定義了一個委托類型MouseEventHandler。委托了啟用了其它編程語言中


的函數指針的解決方案。與C++的函數指針不同,委托是完全面向對象的,同時封裝了對象


實例和方法。本質上,委托把一個實例和該實例上的方法函數封裝成一個可調用的實體,它


是面對對象的、安全的。?


? ? ?我們可以把?
? ? ?this.MouseDown += new System.Windows.Forms.MouseEventHandler


(this.Form1_MouseDown1);?
? ? ?這條語句看成向this.MouseDown添加一個函數指針。?


? ? ?事件是對象發送的消息,以發送信號通知操作的發生。引發(觸發)事件的對象叫做事件發


送方。捕獲事件并對事件作出響應的對象叫做事件接收方。在事件通訊中,事件發送方類并


不知道哪個對象或方法將接收到(處理)它引發的事件。所需要的是在發送方和接收方之間存


在一個媒介(類似指針的機制)。.NET框架定義了一個特殊的類型(Delegate委托),該類型提


供函數指針的功能。這樣,委托就等效于一個類型安全的函數指針或一個回調函數。?


? ? ?前面我們向this.MouseDown事件添加了兩個委托。?
? ? ?this.MouseDown += new System.Windows.Forms.MouseEventHandler


(this.Form1_MouseDown1);?
? ? ?this.MouseDown += new System.Windows.Forms.MouseEventHandler


(this.Form1_MouseDown2);?
? ? ?結果,我們的兩個函數Form1_MouseDown1、Form1_MouseDown2在我們單擊鼠標


左鍵的時候都會被調用,而且調用的順序和我們添加委托的順序一致。?


? ? ?WM_LBUTTONDOWN消息首先被Application類從應用程序消息隊列中取出,然后分發


到相應的窗體。窗體使用MouseDown事件中的函數指針調用已經添加的響應函數。所以C#


中的事件字段實質上是一個函數指針列表,用來維護一些消息到達時的響應函數的地址。 ? ??


三、結論?


? ? ?C#中消息的工作流程:?


? ? ?C#中的消息被Application類從應用程序消息隊列中取出,然后分發到消息對應的窗體,


窗體對象的第一個響應函數是對象中的protected override void WndProc(ref?


System.Windows.Forms.Message e)方法。?
? ? ?它再根據消息的類型調用默認的消息響應函數(如OnMouseDown),默認的響應函數然


后根據對象的事件字段(如this.MouseDown )中的函數指針列表,調用用戶所加入的響應函


數(如Form1_MouseDown1和Form1_MouseDown2),而且調用順序和用戶添加順序一致


。?


四、再回首Application類?


? ? ?Application類有一個AddMessageFilter的靜態方法,通過它我們可以添加消息篩選器,


以便在向目標傳遞Windows消息時,檢視這些消息。?
? ? ?使用消息篩選器來防止引發特定事件,或在將某事件傳遞給事件處理程序之前使用消息篩


選器對其執行特殊操作。我們必須提供IMessageFilter接口的一個實現,然后才可以使用消


息篩選器。以下的示范代碼將演示在消息發往窗體前我們如何攔截它。我們攔截的同樣是


WM_LBUTTONDOWN消息。?


using System;?
using System.Drawing;?
using System.Collections;?
using System.ComponentModel;?
using System.Windows.Forms;?
using System.Data;?


namespace MessageMech3?
{?
? ? ?//實現消息過濾器接口?
? ? public class CLButtonDownFilter : IMessageFilter?
? ? {?
? ? ? ?public bool PreFilterMessage(ref Message m)?
? ? ? ?{?
? ? ? ? ? if (m.Msg==0x0201)// WM_LBUTTONDOWN?
? ? ? ? ? {?
? ? ? ? ? ? ?System.Windows.Forms.MessageBox.Show("App中鼠標左鍵按下");?
? ? ? ? ? ? ?//返回值為true, 表示消息已被處理,不要再往后傳遞,因此消息被截獲?
? ? ? ? ? ? ?//返回值為false,表示消息未被處理,需要再往后傳遞,因此消息未被截獲?
? ? ? ? ? ? ?return true;?
? ? ? ? ? }?
? ? ? ? ? return false;?
? ? ? ?}?
? ? }?


? ? /// <summary>?
? ? /// Summary description for WinForm.?
? ? /// </summary>?
? ? public class WinForm : System.Windows.Forms.Form?
? ? {?
? ? ? ?/// <summary>?
? ? ? ?/// Required designer variable.?
? ? ? ?/// </summary>?
? ? ? ?private System.Windows.Forms.Label label1;?
? ? ? ?private System.ComponentModel.Container components = null;?


? ? ? ?public WinForm()?
? ? ? ?{?
? ? ? ? ? //?
? ? ? ? ? // Required for Windows Form Designer support?
? ? ? ? ? //?
? ? ? ? ? InitializeComponent();?


? ? ? ? ? //?
? ? ? ? ? // TODO: Add any constructor code after InitializeComponent call?
? ? ? ? ? //?
? ? ? ? ? //安裝自己的過濾器?
? ? ? ? ? CLButtonDownFilter MyFilter=new CLButtonDownFilter();?
? ? ? ? ? System.Windows.Forms.Application.AddMessageFilter(MyFilter);?
? ? ? ?}?


? ? ? ?/// <summary>?
? ? ? ?/// Clean up any resources being used.?
? ? ? ?/// </summary>?
? ? ? ?protected override void Dispose (bool disposing)?
? ? ? ?{?
? ? ? ? ? if (disposing)?
? ? ? ? ? {?
? ? ? ? ? ? ?if (components != null)?
? ? ? ? ? ? ?{?
? ? ? ? ? ? ? ? components.Dispose();?
? ? ? ? ? ? ?}?
? ? ? ? ? }?
? ? ? ? ? base.Dispose(disposing);?
? ? ? ?}?


? ? ? ?#region Windows Form Designer generated code?
? ? ? ?/// <summary>?
? ? ? ?/// Required method for Designer support - do not modify?
? ? ? ?/// the contents of this method with the code editor.?
? ? ? ?/// </summary>?
? ? ? ?private void InitializeComponent()?
? ? ? ?{?
? ? ? ? ? this.label1 = new System.Windows.Forms.Label();?
? ? ? ? ? this.SuspendLayout();?
? ? ? ? ? //?
? ? ? ? ? // label1?
? ? ? ? ? //?
? ? ? ? ? this.label1.BackColor = System.Drawing.Color.Transparent;?
? ? ? ? ? this.label1.Dock = System.Windows.Forms.DockStyle.Top;?
? ? ? ? ? this.label1.ForeColor = System.Drawing.Color.DarkViolet;?
? ? ? ? ? this.label1.Name = "label1";?
? ? ? ? ? this.label1.Size = new System.Drawing.Size(440, 32);?
? ? ? ? ? this.label1.TabIndex = 0;?
? ? ? ? ? this.label1.Text = "演示如何在App對象中處理消息,請點鼠標左鍵";?
? ? ? ? ? this.label1.TextAlign = System.Drawing.ContentAlignment.BottomCenter;?
? ? ? ? ? //?
? ? ? ? ? // Form1?
? ? ? ? ? //?
? ? ? ? ? this.AutoScaleBaseSize = new System.Drawing.Size(7, 22);?
? ? ? ? ? this.BackColor = System.Drawing.Color.WhiteSmoke;?
? ? ? ? ? this.ClientSize = new System.Drawing.Size(440, 273);?
? ? ? ? ? this.Controls.AddRange(new System.Windows.Forms.Control[] {this.label1});
? ? ? ? ? this.Font = new System.Drawing.Font("華文行楷", 15F,?


System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,?


((System.Byte)(134)));?
? ? ? ? ? this.Name = "WinForm";?
? ? ? ? ? this.Text = "WinForm";?


? ? ? ? ? //消息響應函數的調用順序和添加委托的順序一致?
? ? ? ? ? //即:以下命令將先調用Form1_MouseDown1再調用Form1_MouseDown2?


? ? ? ? ? //通過委托添加自己的鼠標按鍵消息響應函數1?
? ? ? ? ? this.MouseDown += new System.Windows.Forms.MouseEventHandler


(this.Form1_MouseDown1);?
? ? ? ? ? //通過委托添加自己的鼠標按鍵消息響應函數2?
? ? ? ? ? this.MouseDown += new System.Windows.Forms.MouseEventHandler


(this.Form1_MouseDown2);?


? ? ? ? ? this.ResumeLayout(false);?
? ? ? ?}?
? ? ? ?#endregion?


? ? ? ?/// <summary>?
? ? ? ?/// 應用程序的主入口點。?
? ? ? ?/// </summary>?
? ? ? ?[STAThread]?
? ? ? ?static void Main()?
? ? ? ?{?
? ? ? ? ? Application.Run(new WinForm()); //啟動當前Form線程上的應用程序消息循環?
? ? ? ?}?


? ? ? ?//要點1?
? ? ? ?// 通過C#提供的事件接口添加自己的鼠標按鍵事件的響應函數?
? ? ? ?//?
? ? ? ?private void Form1_MouseDown1(object sender,?


System.Windows.Forms.MouseEventArgs e)?
? ? ? ?{?
? ? ? ? ? ?if(e.Button==System.Windows.Forms.MouseButtons.Left)?
? ? ? ? ? ? ?System.Windows.Forms.MessageBox.Show("消息被Form1_MouseDown1函數


響應");?


? ? ? ?}?
? ? ? ?private void Form1_MouseDown2(object sender,?


System.Windows.Forms.MouseEventArgs e)?
? ? ? ?{?
? ? ? ? ? if(e.Button==System.Windows.Forms.MouseButtons.Left)?
? ? ? ? ? ? ?System.Windows.Forms.MessageBox.Show("消息被Form1_MouseDown2函數


響應");?


? ? ? ?}?
? ? ? ?//要點2?
? ? ? ?//通過覆蓋基類的事件引發函數攔截消息?
? ? ? ?//?
? ? ? ?protected override ? void OnMouseDown( MouseEventArgs e)?
? ? ? ?{?
? ? ? ? ? if(e.Button==System.Windows.Forms.MouseButtons.Left)?
? ? ? ? ? ? ?System.Windows.Forms.MessageBox.Show("消息被OnMouseDown函數響應");?


? ? ? ? ? //如果需要截獲消息,可將base.OnMouseDown(e);語句注釋掉?
? ? ? ? ? base.OnMouseDown(e);?
? ? ? ?}?
? ? ? ?//要點3?
? ? ? ?//通過覆蓋基類的窗體函數攔截消息?
? ? ? ?//?
? ? ? ?protected override void WndProc(ref System.Windows.Forms.Message e)?
? ? ? ?{?
? ? ? ? ? //如果需要截獲消息,?
? ? ? ? ? //if(e.Msg==0x0201)// WM_LBUTTONDOWN?
? ? ? ? ? // ? ?System.Windows.Forms.MessageBox.Show("消息被WndProc函數響應");?
? ? ? ? ? //else?
? ? ? ? ? // ? ?base.WndProc(ref e);?


? ? ? ? ? //不需要截獲消息則為?
? ? ? ? ? if(e.Msg==0x0201)// WM_LBUTTONDOWN?
? ? ? ? ? ? ?System.Windows.Forms.MessageBox.Show("消息被WndProc函數響應");?
? ? ? ? ? base.WndProc(ref e);?
? ? ? ?}?


? ? }?
}?


? ? ?以上代碼我們首先用類CLButtonDownFilter實現了IMessageFilter接口,在WinForm初


始化的時候我們安裝了消息篩選器。程序實際執行的時候,在點擊鼠標左鍵的時候,程序僅


僅會彈出一個"App中鼠標左鍵按下"的消息框。因為我們在消息發往窗體前攔截了它,所以


窗體將接收不到WM_LBUTTONDOWN消息。?
? ? ?如果我們把?
? ? ? ? ? ? ??
? ? ? ? ? ? ? if (m.Msg==0x0201)// WM_LBUTTONDOWN?
? ? ? ? ? {?
? ? ? ? ? ? ?System.Windows.Forms.MessageBox.Show("App中鼠標左鍵按下");?
? ? ? ? ? ? ?return true;?
? ? ? ? ? }?
? ? ?改成?


? ? ? ? ? ? ? if (m.Msg==0x0201)// WM_LBUTTONDOWN?
? ? ? ? ? {?
? ? ? ? ? ? ?System.Windows.Forms.MessageBox.Show("App中鼠標左鍵按下");?
? ? ? ? ? ? ?return false;?
? ? ? ? ? }?
? ? ?那么,我們在Application類處理消息后,消息將繼續發往窗體。窗體的函數將可以處理


此消息。程序執行效果是順序彈出5個消息框。?
? ? ?1:<<App中鼠標左鍵按下>>?
? ? ?2:<<消息被WndProc函數響應>>?
? ? ?3:<<消息被OnMouseDown函數響應>>?
? ? ?4:<<消息被Form1_MouseDown1函數響應>>?
? ? ?5:<<消息被Form1_MouseDown2函數響應>>


其實本文中已經說的挺詳細的.彈出的對話框只是為了讓你更直觀的看出導致的結果.?


先定義沒過濾時的效果.?
this.MouseDown += new System.Windows.Forms.MouseEventHandler


(this.Form1_MouseDown1);?
private void Form1_MouseDown1(object sender,?


System.Windows.Forms.MouseEventArgs e)?
{?
if (e.Button == System.Windows.Forms.MouseButtons.Left)?
MessageBox.Show("消息被Form1_MouseDown1函數響應");?
}?
主要有兩種方法過濾實現過濾?
第一種:?
protected override void WndProc(ref Message m)?
{?
if (m.Msg == 0x0201)?
return;?
else?
base.WndProc(ref m);?
}?
第二種?
不重寫WndProc?


//實現消息過濾器接口?
public class CLButtonDownFilter : IMessageFilter?
{?
public bool PreFilterMessage(ref Message m)?
{?
if (m.Msg == 0x0201)// WM_LBUTTONDOWN?
{?
//返回值為true, 表示消息已被處理,不要再往后傳遞,因此消息被截獲?
//返回值為false,表示消息未被處理,需要再往后傳遞,因此消息未被截獲?
return true;?
}?
return false;?
}?
}?


CLButtonDownFilter MyFilter = new CLButtonDownFilter();?
System.Windows.Forms.Application.AddMessageFilter(MyFilter);
========

c# Windows消息處理過程探究



http://blog.csdn.net/jjjfox/article/details/7360378
一、消息概述


? ? Windows下應用程序的執行是通過消息驅動的。消息是整個應用程序的工作引擎,我們


需要理解掌握編程語言是如何封裝消息的原理。?


1 什么是消息(Message)?


? ? 消息就是通知和命令。在.NET框架類庫中的System.Windows.Forms命名空間中微軟采


用面對對象的方式重新定義了Message。新的消息(Message)結構的公共部分屬性基本與早


期的一樣,不過它是面對對象的。?
? ? 公共屬性:?


? ? HWnd ? ?獲取或設定消息的處理函數?
? ? Msg ? ? 獲取或設定消息的ID號?
? ? Lparam ?指定消息的LParam字段?
? ? Wparam ?指定消息的WParam字段?
? ? Result ?指定為響應消息處理函數而向OS系統返回的值?


2 消息驅動的過程?


? ?所有的外部事件,如鍵盤輸入、鼠標移動、按動鼠標都由OS系統轉換成相應的消息發送到


應用程序的消息隊列。每個應用程序都有一段相應的程序代碼來檢索、分發這些消息到對應


的窗體,然后由窗體的處理函數來處理。


二、C#中的消息的封裝?


? ? C#對消息重新進行了面對對象的封裝,在C#中消息被封裝成了事件。?
? ? System.Windows.Forms.Application類具有用于啟動和停止應用程序和線程以及處理


Windows消息的方法。?
? ? 調用Run以啟動當前線程上的應用程序消息循環,并可以選擇使其窗體可見。?
? ? 調用Exit或ExitThread來停止消息循環。?
? ? C#中用Application類來處理消息的接收和發送的。消息的循環是由它負責的。?
? ? 從本質上來講,每個窗體一般都對應一個窗體過程處理函數。那么,C#的一個Form實例(


相當于一個窗體)收到消息后是如何處理消息的?其實,這個問題的分析也就是展示了C#的


消息封裝原理。?


?三、C#中消息的工作流程:?


? 1、 Application類有一個AddMessageFilter的靜態方法,通過它我們可以添加消息篩選器


,以便在向目標傳遞Windows消息時,檢視這些消息。?
? ? ? ?使用消息篩選器來防止引發特定事件,或在將某事件傳遞給事件處理程序之前使用消息


篩選器對其執行特殊操作。


? ? ?我們必須提供IMessageFilter接口的一個實現,然后才可以使用消息篩選器。


? 2、 C#中的消息被Application類從應用程序消息隊列中取出,如果有消息篩選器,先執行


消息篩選, 然后分發到消息對應的窗體。


? ? ? 1)窗體對象的第一個響應函數是窗口過程函數,即對象中的protected override void?


WndProc(ref System.Windows.Forms.Message e)方法。


? ? ? 2)再根據消息的類型調用默認的消息響應函數(如OnMouseDown)


? ? ? ? 3)再根據用戶自定義的事件處理函數,按訂閱順序分別執行(如


Form1_MouseDown1)。?


四、示例:
namespace WindowsApplication27
{
? ? partial class Form1
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 必需的設計器變量。
? ? ? ? /// </summary>
? ? ? ? private System.ComponentModel.IContainer components = null;


? ? ? ? /// <summary>
? ? ? ? /// 清理所有正在使用的資源。
? ? ? ? /// </summary>
? ? ? ? /// <param name="disposing">如果應釋放托管資源,為 true;否則為 false。


</param>
? ? ? ? protected override void Dispose(bool disposing)
? ? ? ? {
? ? ? ? ? ? if (disposing && (components != null))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? components.Dispose();
? ? ? ? ? ? }
? ? ? ? ? ? base.Dispose(disposing);
? ? ? ? }


? ? ? ? #region Windows 窗體設計器生成的代碼


? ? ? ? /// <summary>
? ? ? ? /// 設計器支持所需的方法 - 不要
? ? ? ? /// 使用代碼編輯器修改此方法的內容。
? ? ? ? /// </summary>
? ? ? ? private void InitializeComponent()
? ? ? ? {
? ? ? ? ? ? this.SuspendLayout();
? ? ? ? ? ? //?
? ? ? ? ? ? // Form1
? ? ? ? ? ? //?
? ? ? ? ? ? this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
? ? ? ? ? ? this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
? ? ? ? ? ? this.ClientSize = new System.Drawing.Size(292, 266);
? ? ? ? ? ? this.Name = "Form1";
? ? ? ? ? ? this.Text = "Form1";


? ? ? ? ? ? //這里訂閱了事件
? ? ? ? ? ? this.MouseDown += new System.Windows.Forms.MouseEventHandler


(this.Form1_MouseDown);
? ? ? ? ? ? this.ResumeLayout(false);


? ? ? ? }


? ? ? ? #endregion


? ? }
}


using System;


using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;


namespace WindowsApplication27
{ ? ? ??
? ? public partial class Form1 : Form
? ? {
? ? ? ? public Form1()
? ? ? ? {
? ? ? ? ? ? InitializeComponent();


? ? ? ? ? ? Application.AddMessageFilter((new msgFilter()));
? ? ? ? }


? ? ? ? private void Form1_MouseDown(object sender, MouseEventArgs e)
? ? ? ? {
? ? ? ? ? ? MessageBox.Show("3");
? ? ? ? }
? ? ? ? protected override void OnMouseDown(MouseEventArgs e)
? ? ? ? {
? ? ? ? ? ? MessageBox.Show("2");
? ? ? ? ? ? base.OnMouseDown(e);
? ? ? ? }


? ? ? ? protected override void WndProc(ref Message m)
? ? ? ? {
? ? ? ? ? ? //MouseDown Msg Id
? ? ? ? ? ? if (m.Msg==0x0201)
? ? ? ? ? ? ? ? MessageBox.Show("1");
? ? ? ? ? ? base.WndProc(ref m);
? ? ? ? }
? ? }


? ? public class msgFilter : IMessageFilter
? ? {
? ? ? ? public bool PreFilterMessage(ref Message m)
? ? ? ? {


? ? ? ? ? ? if (m.Msg == 0x0201)
? ? ? ? ? ? ? ? MessageBox.Show("0");
? ? ? ? ? ? return false;
? ? ? ? }
? ? }
? ? static class Program
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 應用程序的主入口點。
? ? ? ? /// </summary>
? ? ? ? [STAThread]
? ? ? ? static void Main()
? ? ? ? {
? ? ? ? ? ? Application.EnableVisualStyles();
? ? ? ? ? ? Application.SetCompatibleTextRenderingDefault(false);
? ? ? ? ? ? Application.Run(new Form1());
? ? ? ? }
? ? }
}
========

C#委托與事件、消息、WndProc用法

http://blog.csdn.net/suncherrydream/article/details/8088338


c#用委托來實現事件通知機制。委托相當與c++函數指針。整個過程涉及一個呼叫者,一個


被呼叫者,還有就是這個委托。


- 實現步驟
有以下幾步: 1. 申明委托, 2.定義呼叫者和調用的函數, 3.定義被呼叫者和具體實現的函數(


被調用的函數)


1.申明委托 ,在包里或者類里,public
?public delegate void PlayGame(Object sender, EventArgs e);?
2.定義呼叫者(類LetsGame)和調用委托的函數,在呼叫者里要有委托的實例(呼叫者扔出


一個委托,被呼叫者給這個委托賦值)
class LetsGame{?
? ? public event PlayGame theGame;?
? ? public void startPlay(EventArgs e){?
? ? ? ? if(theGame != null){?
? ? ? ? theGame(this,e);?
? ? }?
}


3. 定義被呼叫者(類MS)和具體實現的函數(被調用的函數),也就是concrete class的實


現或者叫函數指針實例。打個比方,在一個叫MS的類中實現.MS中對呼叫者中委托的實例進


行賦值.
class MS {
? ? public MS(LetsGame lg) {
? ? ? ? lg.theGame += new PlayGame(MSPlayGame);
? ? }
? ? public void MSPlayGame(Object sender, EventArgs e){?
? ? ? ? Console.WriteLine("Who laughs the last who wins");?
? ? }?
}


這樣當調用LetsGame.startPlay的時候就會調用MS.MSPlayGame.


?
- 實際應用
對照一下c#的GUI事件處理或者asp.NET的web控件事件處理,能幫我們更好的理解委托和事


件.大家一定很熟悉asp.Net里下面的代碼
private void InitializeComponent()
{ ? ?
? ??
? ? this.Button1.Click += new System.EventHandler(this.Button1_Click);
? ??
}


?
private void Button1_Click(object sender, System.EventArgs e)
{
? ? //do sth
}


這就是用委托來實現事件.你可能發現我們并沒有給它聲明委托對象并通過event關鍵字來引


用該委托對象,那是因為asp.net早就幫我們做好了該項工作,其委托對象是


System.EventHandler. Button1相當于上面的LetsGame的實例,是呼叫者,Button1_Click是


被呼叫方法.當你click Button1后,Button1就會調用Button1_Click.




-雜項
我覺得這種機制和design pattern里的observer很類似,我們完全可以用observer來達到同樣


的效果,但是用委托更靈活,不需要定義一個interface然后所有的concrete class都實現某個方


法,函數指針(委托)更靈活.


還有,委托不一定非要和事件一起用,單獨用的時候就是函數指針.




-------------------------------------------------------------------------------
WndProc(ref Message m)
protected override void WndProc(ref Message m)?
{?
? ? const int WM_SYSCOMMAND = 0x0112;?
? ? const int SC_CLOSE = 0xF060;?
? ? if (m.Msg == WM_SYSCOMMAND && (int) m.WParam == SC_CLOSE)?
? ? {?
? ? ? ? // 屏蔽傳入的消息事件?
? ? ? ? this.WindowState = FormWindowState.Minimized;?
? ? ? ? return;?
? ? ?}?
? ? base.WndProc(ref m);?
}


protected override void WndProc(ref ? ?Message m)
{
? ? ?const int WM_SYSCOMMAND = 0x0112;
? ? ?const int SC_CLOSE = 0xF060;
? ? ?const int SC_MINIMIZE = 0xF020;
? ? ?if (m.Msg == WM_SYSCOMMAND && ((int)m.WParam == SC_MINIMIZE ||?


(int)m.WParam == SC_CLOSE))
? ? ?{
? ? ? ? ?//最小化到系統欄?
? ? ? ? ?this.Hide();
? ? ? ? ?return;
? ? ?}
? ? ?base.WndProc(ref ? ?m);
}


----------------------------------------------
不規則窗體拖動


using System.Runtime.InteropServices;


[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll")]
public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int?


lParam);
public const int WM_SYSCOMMAND = 0x0112;
public const int SC_MOVE = 0xF010;
public const int HTCAPTION = 0x0002;


public void ShapedForm_MouseDown(object sender, MouseEventArgs e)?
{?
ReleaseCapture();
SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
}


-------------------------------------------------------------------
protected override void WndProc(ref Message m)
? {
? //攔截窗體最小化按鈕消息,調用隱藏動畫并隱藏窗體
? if (m.Msg == (int)hyFrameWork.win32Api.Enum.WinMsg.WM_SYSCOMMAND)
? {
? if (m.WParam.ToInt32() == (int)


hyFrameWork.win32Api.Enum.ECNCSysCommandConstants.SC_MINIMIZE)
? {
? formShowControl(false);
? return;
? }
? }
? base.WndProc(ref m);
? }
? -------------------------------------------
? 大體的消息說明,你自己看吧?
WM_NULL = $0000;?
WM_CREATE = $0001;?
應用程序創建一個窗口?
WM_DESTROY = $0002;?
一個窗口被銷毀?
WM_MOVE = $0003;?
移動一個窗口?
WM_SIZE = $0005;?
改變一個窗口的大小?
WM_ACTIVATE = $0006;?
一個窗口被激活或失去激活狀態;?
WM_SETFOCUS = $0007;?
獲得焦點后?
WM_KILLFOCUS = $0008;?
失去焦點?
WM_ENABLE = $000A;?
改變enable狀態?
WM_SETREDRAW = $000B;?
設置窗口是否能重畫?
WM_SETTEXT = $000C;?
應用程序發送此消息來設置一個窗口的文本?
WM_GETTEXT = $000D;?
應用程序發送此消息來復制對應窗口的文本到緩沖區?
WM_GETTEXTLENGTH = $000E;?
得到與一個窗口有關的文本的長度(不包含空字符)?
WM_PAINT = $000F;?
要求一個窗口重畫自己?
WM_CLOSE = $0010;?
當一個窗口或應用程序要關閉時發送一個信號?
WM_QUERYENDSESSION = $0011;?
當用戶選擇結束對話框或程序自己調用ExitWindows函數?
WM_QUIT = $0012;?
用來結束程序運行或當程序調用postquitmessage函數?
WM_QUERYOPEN = $0013;?
當用戶窗口恢復以前的大小位置時,把此消息發送給某個圖標?
WM_ERASEBKGND = $0014;?
當窗口背景必須被擦除時(例在窗口改變大小時)?
WM_SYSCOLORCHANGE = $0015;?
當系統顏色改變時,發送此消息給所有頂級窗口?
WM_ENDSESSION = $0016;?
當系統進程發出WM_QUERYENDSESSION消息后,此消息發送給應用程序,?
通知它對話是否結束?
WM_SYSTEMERROR = $0017;?
WM_SHOWWINDOW = $0018;?
當隱藏或顯示窗口是發送此消息給這個窗口?
WM_ACTIVATEAPP = $001C;?
發此消息給應用程序哪個窗口是激活的,哪個是非激活的;?
WM_FONTCHANGE = $001D;?
當系統的字體資源庫變化時發送此消息給所有頂級窗口?
WM_TIMECHANGE = $001E;?
當系統的時間變化時發送此消息給所有頂級窗口?
WM_CANCELMODE = $001F;?
發送此消息來取消某種正在進行的摸態(操作)?
WM_SETCURSOR = $0020;?
如果鼠標引起光標在某個窗口中移動且鼠標輸入沒有被捕獲時,就發消息給某個窗口?
WM_MOUSEACTIVATE = $0021;?
當光標在某個非激活的窗口中而用戶正按著鼠標的某個鍵發送此消息給當前窗口?
WM_CHILDACTIVATE = $0022;?
發送此消息給MDI子窗口當用戶點擊此窗口的標題欄,或當窗口被激活,移動,改變大小?
WM_QUEUESYNC = $0023;?
此消息由基于計算機的訓練程序發送,通過WH_JOURNALPALYBACK的hook程序?
分離出用戶輸入消息?
WM_GETMINMAXINFO = $0024;?
此消息發送給窗口當它將要改變大小或位置;?
WM_PAINTICON = $0026;?
發送給最小化窗口當它圖標將要被重畫?
WM_ICONERASEBKGND = $0027;?
此消息發送給某個最小化窗口,僅當它在畫圖標前它的背景必須被重畫?
WM_NEXTDLGCTL = $0028;?
發送此消息給一個對話框程序去更改焦點位置?
WM_SPOOLERSTATUS = $002A;?
每當打印管理列隊增加或減少一條作業時發出此消息?
WM_DRAWITEM = $002B;?
當button,combobox,listbox,menu的可視外觀改變時發送?
此消息給這些空件的所有者?
WM_MEASUREITEM = $002C;?
當button, combo box, list box, list view control, or menu item 被創建時?
發送此消息給控件的所有者?
WM_DELETEITEM = $002D;?
當the list box 或 combo box 被銷毀 或 當 某些項被刪除通過LB_DELETESTRING,?


LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT 消息?
WM_VKEYTOITEM = $002E;?
此消息有一個LBS_WANTKEYBOARDINPUT風格的發出給它的所有者來響應


WM_KEYDOWN消息?
WM_CHARTOITEM = $002F;?
此消息由一個LBS_WANTKEYBOARDINPUT風格的列表框發送給他的所有者來響應


WM_CHAR消息?
WM_SETFONT = $0030;?
當繪制文本時程序發送此消息得到控件要用的顏色?
WM_GETFONT = $0031;?
應用程序發送此消息得到當前控件繪制文本的字體?
WM_SETHOTKEY = $0032;?
應用程序發送此消息讓一個窗口與一個熱鍵相關連?
WM_GETHOTKEY = $0033;?
應用程序發送此消息來判斷熱鍵與某個窗口是否有關聯?
WM_QUERYDRAGICON = $0037;?
此消息發送給最小化窗口,當此窗口將要被拖放而它的類中沒有定義圖標,應用程序能?
返回一個圖標或光標的句柄,當用戶拖放圖標時系統顯示這個圖標或光標?
WM_COMPAREITEM = $0039;?
發送此消息來判定combobox或listbox新增加的項的相對位置?
WM_GETOBJECT = $003D;?
WM_COMPACTING = $0041;?
顯示內存已經很少了?
WM_WINDOWPOSCHANGING = $0046;?
發送此消息給那個窗口的大小和位置將要被改變時,來調用setwindowpos函數或其它窗口


管理函數?
WM_WINDOWPOSCHANGED = $0047;?
發送此消息給那個窗口的大小和位置已經被改變時,來調用setwindowpos函數或其它窗口


管理函數?
WM_POWER = $0048;(適用于16位的windows)?
當系統將要進入暫停狀態時發送此消息?
WM_COPYDATA = $004A;?
當一個應用程序傳遞數據給另一個應用程序時發送此消息?
WM_CANCELJOURNAL = $004B;?
當某個用戶取消程序日志激活狀態,提交此消息給程序?
WM_NOTIFY = $004E;?
當某個控件的某個事件已經發生或這個控件需要得到一些信息時,發送此消息給它的父窗口?
WM_INPUTLANGCHANGEREQUEST = $0050;?
當用戶選擇某種輸入語言,或輸入語言的熱鍵改變?
WM_INPUTLANGCHANGE = $0051;?
當平臺現場已經被改變后發送此消息給受影響的最頂級窗口?
WM_TCARD = $0052;?
當程序已經初始化windows幫助例程時發送此消息給應用程序?
WM_HELP = $0053;?
此消息顯示用戶按下了F1,如果某個菜單是激活的,就發送此消息個此窗口關聯的菜單,否


則就?
發送給有焦點的窗口,如果當前都沒有焦點,就把此消息發送給當前激活的窗口?
WM_USERCHANGED = $0054;?
當用戶已經登入或退出后發送此消息給所有的窗口,當用戶登入或退出時系統更新用戶的具


體?
設置信息,在用戶更新設置時系統馬上發送此消息;?
WM_NOTIFYFORMAT = $0055;?
公用控件,自定義控件和他們的父窗口通過此消息來判斷控件是使用ANSI還是UNICODE結


構?
在WM_NOTIFY消息,使用此控件能使某個控件與它的父控件之間進行相互通信?
WM_CONTEXTMENU = $007B;?
當用戶某個窗口中點擊了一下右鍵就發送此消息給這個窗口?
WM_STYLECHANGING = $007C;?
當調用SETWINDOWLONG函數將要改變一個或多個 窗口的風格時發送此消息給那個窗口?
WM_STYLECHANGED = $007D;?
當調用SETWINDOWLONG函數一個或多個 窗口的風格后發送此消息給那個窗口?
WM_DISPLAYCHANGE = $007E;?
當顯示器的分辨率改變后發送此消息給所有的窗口?
WM_GETICON = $007F;?
此消息發送給某個窗口來返回與某個窗口有關連的大圖標或小圖標的句柄;?
WM_SETICON = $0080;?
程序發送此消息讓一個新的大圖標或小圖標與某個窗口關聯;?
WM_NCCREATE = $0081;?
當某個窗口第一次被創建時,此消息在WM_CREATE消息發送前發送;?
WM_NCDESTROY = $0082;?
此消息通知某個窗口,非客戶區正在銷毀?
WM_NCCALCSIZE = $0083;?
當某個窗口的客戶區域必須被核算時發送此消息?
WM_NCHITTEST = $0084;//移動鼠標,按住或釋放鼠標時發生?
WM_NCPAINT = $0085;?
程序發送此消息給某個窗口當它(窗口)的框架必須被繪制時;?
WM_NCACTIVATE = $0086;?
此消息發送給某個窗口 僅當它的非客戶區需要被改變來顯示是激活還是非激活狀態;?
WM_GETDLGCODE = $0087;?
發送此消息給某個與對話框程序關聯的控件,widdows控制方位鍵和TAB鍵使輸入進入此控


件?
通過響應WM_GETDLGCODE消息,應用程序可以把他當成一個特殊的輸入控件并能處理它?
WM_NCMOUSEMOVE = $00A0;?
當光標在一個窗口的非客戶區內移動時發送此消息給這個窗口 //非客戶區為:窗體的標題欄


及窗?
的邊框體?
WM_NCLBUTTONDOWN = $00A1;?
當光標在一個窗口的非客戶區同時按下鼠標左鍵時提交此消息?
WM_NCLBUTTONUP = $00A2;?
當用戶釋放鼠標左鍵同時光標某個窗口在非客戶區十發送此消息;?
WM_NCLBUTTONDBLCLK = $00A3;?
當用戶雙擊鼠標左鍵同時光標某個窗口在非客戶區十發送此消息?
WM_NCRBUTTONDOWN = $00A4;?
當用戶按下鼠標右鍵同時光標又在窗口的非客戶區時發送此消息?
WM_NCRBUTTONUP = $00A5;?
當用戶釋放鼠標右鍵同時光標又在窗口的非客戶區時發送此消息?
WM_NCRBUTTONDBLCLK = $00A6;?
當用戶雙擊鼠標右鍵同時光標某個窗口在非客戶區十發送此消息?
WM_NCMBUTTONDOWN = $00A7;?
當用戶按下鼠標中鍵同時光標又在窗口的非客戶區時發送此消息?
WM_NCMBUTTONUP = $00A8;?
當用戶釋放鼠標中鍵同時光標又在窗口的非客戶區時發送此消息?
WM_NCMBUTTONDBLCLK = $00A9;?
當用戶雙擊鼠標中鍵同時光標又在窗口的非客戶區時發送此消息?
WM_KEYFIRST = $0100;?
WM_KEYDOWN = $0100;?
//按下一個鍵?
WM_KEYUP = $0101;?
//釋放一個鍵?
WM_CHAR = $0102;?
//按下某鍵,并已發出WM_KEYDOWN, WM_KEYUP消息?
WM_DEADCHAR = $0103;?
當用translatemessage函數翻譯WM_KEYUP消息時發送此消息給擁有焦點的窗口?
WM_SYSKEYDOWN = $0104;?
當用戶按住ALT鍵同時按下其它鍵時提交此消息給擁有焦點的窗口;?
WM_SYSKEYUP = $0105;?
當用戶釋放一個鍵同時ALT 鍵還按著時提交此消息給擁有焦點的窗口?
WM_SYSCHAR = $0106;?
當WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函數翻譯后提交此消息給擁有焦點的


窗口?
WM_SYSDEADCHAR = $0107;?
當WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函數翻譯后發送此消息給擁有焦點的


窗口?
WM_KEYLAST = $0108;?
WM_INITDIALOG = $0110;?
在一個對話框程序被顯示前發送此消息給它,通常用此消息初始化控件和執行其它任務?
WM_COMMAND = $0111;?
當用戶選擇一條菜單命令項或當某個控件發送一條消息給它的父窗口,一個快捷鍵被翻譯?
WM_SYSCOMMAND = $0112;?
當用戶選擇窗口菜單的一條命令或當用戶選擇最大化或最小化時那個窗口會收到此消息?
WM_TIMER = $0113; //發生了定時器事件?
WM_HSCROLL = $0114;?
當一個窗口標準水平滾動條產生一個滾動事件時發送此消息給那個窗口,也發送給擁有它的


控件?
WM_VSCROLL = $0115;?
當一個窗口標準垂直滾動條產生一個滾動事件時發送此消息給那個窗口也,發送給擁有它的


控件 WM_INITMENU = $0116;?
當一個菜單將要被激活時發送此消息,它發生在用戶菜單條中的某項或按下某個菜單鍵,它


允許?
程序在顯示前更改菜單?
WM_INITMENUPOPUP = $0117;?
當一個下拉菜單或子菜單將要被激活時發送此消息,它允許程序在它顯示前更改菜單,而不


要?
改變全部?
WM_MENUSELECT = $011F;?
當用戶選擇一條菜單項時發送此消息給菜單的所有者(一般是窗口)?
WM_MENUCHAR = $0120;?
當菜單已被激活用戶按下了某個鍵(不同于加速鍵),發送此消息給菜單的所有者;?
WM_ENTERIDLE = $0121;?
當一個模態對話框或菜單進入空載狀態時發送此消息給它的所有者,一個模態對話框或菜單


進入空載狀態就是在處理完一條或幾條先前的消息后沒有消息它的列隊中等待?
WM_MENURBUTTONUP = $0122;?
WM_MENUDRAG = $0123;?
WM_MENUGETOBJECT = $0124;?
WM_UNINITMENUPOPUP = $0125;?
WM_MENUCOMMAND = $0126;?
WM_CHANGEUISTATE = $0127;?
WM_UPDATEUISTATE = $0128;?
WM_QUERYUISTATE = $0129;?
WM_CTLCOLORMSGBOX = $0132;?
在windows繪制消息框前發送此消息給消息框的所有者窗口,通過響應這條消息,所有者窗


口可以?
通過使用給定的相關顯示設備的句柄來設置消息框的文本和背景顏色?
WM_CTLCOLOREDIT = $0133;?
當一個編輯型控件將要被繪制時發送此消息給它的父窗口;通過響應這條消息,所有者窗口


可以?
通過使用給定的相關顯示設備的句柄來設置編輯框的文本和背景顏色?
WM_CTLCOLORLISTBOX = $0134;?
當一個列表框控件將要被繪制前發送此消息給它的父窗口;通過響應這條消息,所有者窗口


可以?
通過使用給定的相關顯示設備的句柄來設置列表框的文本和背景顏色?
WM_CTLCOLORBTN = $0135;?
當一個按鈕控件將要被繪制時發送此消息給它的父窗口;通過響應這條消息,所有者窗口可


以?
通過使用給定的相關顯示設備的句柄來設置按紐的文本和背景顏色?
WM_CTLCOLORDLG = $0136;?
當一個對話框控件將要被繪制前發送此消息給它的父窗口;通過響應這條消息,所有者窗口


可以?
通過使用給定的相關顯示設備的句柄來設置對話框的文本背景顏色?
WM_CTLCOLORSCROLLBAR= $0137;?
當一個滾動條控件將要被繪制時發送此消息給它的父窗口;通過響應這條消息,所有者窗口


可以?
通過使用給定的相關顯示設備的句柄來設置滾動條的背景顏色?
WM_CTLCOLORSTATIC = $0138;?
當一個靜態控件將要被繪制時發送此消息給它的父窗口;通過響應這條消息,所有者窗口可


以?
通過使用給定的相關顯示設備的句柄來設置靜態控件的文本和背景顏色?
WM_MOUSEFIRST = $0200;?
WM_MOUSEMOVE = $0200;?
// 移動鼠標?
WM_LBUTTONDOWN = $0201;?
//按下鼠標左鍵?
WM_LBUTTONUP = $0202;?
//釋放鼠標左鍵?
WM_LBUTTONDBLCLK = $0203;?
//雙擊鼠標左鍵?
WM_RBUTTONDOWN = $0204;?
//按下鼠標右鍵?
WM_RBUTTONUP = $0205;?
//釋放鼠標右鍵?
WM_RBUTTONDBLCLK = $0206;?
//雙擊鼠標右鍵?
WM_MBUTTONDOWN = $0207;?
//按下鼠標中鍵?
WM_MBUTTONUP = $0208;?
//釋放鼠標中鍵?
WM_MBUTTONDBLCLK = $0209;?
//雙擊鼠標中鍵?
WM_MOUSEWHEEL = $020A;?
當鼠標輪子轉動時發送此消息個當前有焦點的控件?
WM_MOUSELAST = $020A;?
WM_PARENTNOTIFY = $0210;?
當MDI子窗口被創建或被銷毀,或用戶按了一下鼠標鍵而光標在子窗口上時發送此消息給它


的父窗口?
WM_ENTERMENULOOP = $0211;?
發送此消息通知應用程序的主窗口that已經進入了菜單循環模式?
WM_EXITMENULOOP = $0212;?
發送此消息通知應用程序的主窗口that已退出了菜單循環模式?
WM_NEXTMENU = $0213;?
WM_SIZING = 532;?
當用戶正在調整窗口大小時發送此消息給窗口;通過此消息應用程序可以監視窗口大小和位


置?
也可以修改他們?
WM_CAPTURECHANGED = 533;?
發送此消息 給窗口當它失去捕獲的鼠標時;?
WM_MOVING = 534;?
當用戶在移動窗口時發送此消息,通過此消息應用程序可以監視窗口大小和位置?
也可以修改他們;?
WM_POWERBROADCAST = 536;?
此消息發送給應用程序來通知它有關電源管理事件;?
WM_DEVICECHANGE = 537;?
當設備的硬件配置改變時發送此消息給應用程序或設備驅動程序?
WM_IME_STARTCOMPOSITION = $010D;?
WM_IME_ENDCOMPOSITION = $010E;?
WM_IME_COMPOSITION = $010F;?
WM_IME_KEYLAST = $010F;?
WM_IME_SETCONTEXT = $0281;?
WM_IME_NOTIFY = $0282;?
WM_IME_CONTROL = $0283;?
WM_IME_COMPOSITIONFULL = $0284;?
WM_IME_SELECT = $0285;?
WM_IME_CHAR = $0286;?
WM_IME_REQUEST = $0288;?
WM_IME_KEYDOWN = $0290;?
WM_IME_KEYUP = $0291;?
WM_MDICREATE = $0220;?
應用程序發送此消息給多文檔的客戶窗口來創建一個MDI 子窗口?
WM_MDIDESTROY = $0221;?
應用程序發送此消息給多文檔的客戶窗口來關閉一個MDI 子窗口?
WM_MDIACTIVATE = $0222;?
應用程序發送此消息給多文檔的客戶窗口通知客戶窗口激活另一個MDI子窗口,當客戶窗口


收到?
此消息后,它發出WM_MDIACTIVE消息給MDI子窗口(未激活)激活它;?
WM_MDIRESTORE = $0223;?
程序 發送此消息給MDI客戶窗口讓子窗口從最大最小化恢復到原來大小?
WM_MDINEXT = $0224;?
程序 發送此消息給MDI客戶窗口激活下一個或前一個窗口?
WM_MDIMAXIMIZE = $0225;?
程序發送此消息給MDI客戶窗口來最大化一個MDI子窗口;?
WM_MDITILE = $0226;?
程序 發送此消息給MDI客戶窗口以平鋪方式重新排列所有MDI子窗口?
WM_MDICASCADE = $0227;?
程序 發送此消息給MDI客戶窗口以層疊方式重新排列所有MDI子窗口?
WM_MDIICONARRANGE = $0228;?
程序 發送此消息給MDI客戶窗口重新排列所有最小化的MDI子窗口?
WM_MDIGETACTIVE = $0229;?
程序 發送此消息給MDI客戶窗口來找到激活的子窗口的句柄?
WM_MDISETMENU = $0230;?
程序 發送此消息給MDI客戶窗口用MDI菜單代替子窗口的菜單?
WM_ENTERSIZEMOVE = $0231;?
WM_EXITSIZEMOVE = $0232;?
WM_DROPFILES = $0233;?
WM_MDIREFRESHMENU = $0234;?
WM_MOUSEHOVER = $02A1;?
WM_MOUSELEAVE = $02A3;?
WM_CUT = $0300;?
程序發送此消息給一個編輯框或combobox來刪除當前選擇的文本?
WM_COPY = $0301;?
程序發送此消息給一個編輯框或combobox來復制當前選擇的文本到剪貼板?
WM_PASTE = $0302;?
程序發送此消息給editcontrol或combobox從剪貼板中得到數據?
WM_CLEAR = $0303;?
程序發送此消息給editcontrol或combobox清除當前選擇的內容;?
WM_UNDO = $0304;?
程序發送此消息給editcontrol或combobox撤消最后一次操作?
WM_RENDERFORMAT = $0305;


WM_RENDERALLFORMATS = $0306;?
WM_DESTROYCLIPBOARD = $0307;?
當調用ENPTYCLIPBOARD函數時 發送此消息給剪貼板的所有者?
WM_DRAWCLIPBOARD = $0308;?
當剪貼板的內容變化時發送此消息給剪貼板觀察鏈的第一個窗口;它允許用剪貼板觀察窗口


來?
顯示剪貼板的新內容;?
WM_PAINTCLIPBOARD = $0309;?
當剪貼板包含CF_OWNERDIPLAY格式的數據并且剪貼板觀察窗口的客戶區需要重畫;?
WM_VSCROLLCLIPBOARD = $030A;?
WM_SIZECLIPBOARD = $030B;?
當剪貼板包含CF_OWNERDIPLAY格式的數據并且剪貼板觀察窗口的客戶區域的大小已經改


變是此消息通過剪貼板觀察窗口發送給剪貼板的所有者;?
WM_ASKCBFORMATNAME = $030C;?
通過剪貼板觀察窗口發送此消息給剪貼板的所有者來請求一個CF_OWNERDISPLAY格式的剪


貼板的名字?
WM_CHANGECBCHAIN = $030D;?
當一個窗口從剪貼板觀察鏈中移去時發送此消息給剪貼板觀察鏈的第一個窗口;?
WM_HSCROLLCLIPBOARD = $030E;?
此消息通過一個剪貼板觀察窗口發送給剪貼板的所有者 ;它發生在當剪貼板包含


CFOWNERDISPALY格式的數據并且有個事件在剪貼板觀察窗的水平滾動條上;所有者應滾


動剪貼板圖象并更新滾動條的值;?
WM_QUERYNEWPALETTE = $030F;?
此消息發送給將要收到焦點的窗口,此消息能使窗口在收到焦點時同時有機會實現他的邏輯


調色板?
WM_PALETTEISCHANGING= $0310;?
當一個應用程序正要實現它的邏輯調色板時發此消息通知所有的應用程序?
WM_PALETTECHANGED = $0311;?
此消息在一個擁有焦點的窗口實現它的邏輯調色板后發送此消息給所有頂級并重疊的窗口,


以此?
來改變系統調色板?
WM_HOTKEY = $0312;?
當用戶按下由REGISTERHOTKEY函數注冊的熱鍵時提交此消息?
WM_PRINT = 791;?
應用程序發送此消息僅當WINDOWS或其它應用程序發出一個請求要求繪制一個應用程序的


一部分;?
WM_PRINTCLIENT = 792;?
WM_HANDHELDFIRST = 856;?
WM_HANDHELDLAST = 863;?
WM_PENWINFIRST = $0380;?
WM_PENWINLAST = $038F;?
WM_COALESCE_FIRST = $0390;?
WM_COALESCE_LAST = $039F;?
WM_DDE_FIRST = $03E0;?
WM_DDE_INITIATE = WM_DDE_FIRST + 0;?
一個DDE客戶程序提交此消息開始一個與服務器程序的會話來響應那個指定的程序和主題名


;?
WM_DDE_TERMINATE = WM_DDE_FIRST + 1;?
一個DDE應用程序(無論是客戶還是服務器)提交此消息來終止一個會話;?
WM_DDE_ADVISE = WM_DDE_FIRST + 2;?
一個DDE客戶程序提交此消息給一個DDE服務程序來請求服務器每當數據項改變時更新它
WM_DDE_UNADVISE = WM_DDE_FIRST + 3;?
一個DDE客戶程序通過此消息通知一個DDE服務程序不更新指定的項或一個特殊的剪貼板格


式的項?
WM_DDE_ACK = WM_DDE_FIRST + 4;?
此消息通知一個DDE(動態數據交換)程序已收到并正在處理WM_DDE_POKE,?


WM_DDE_EXECUTE, WM_DDE_DATA, WM_DDE_ADVISE, WM_DDE_UNADVISE, or?


WM_DDE_INITIAT消息?
WM_DDE_DATA = WM_DDE_FIRST + 5;?
一個DDE服務程序提交此消息給DDE客戶程序來傳遞個一數據項給客戶或通知客戶的一條可


用數據項?
WM_DDE_REQUEST = WM_DDE_FIRST + 6;?
一個DDE客戶程序提交此消息給一個DDE服務程序來請求一個數據項的值;?
WM_DDE_POKE = WM_DDE_FIRST + 7;?
一個DDE客戶程序提交此消息給一個DDE服務程序,客戶使用此消息來請求服務器接收一個


未經同意的數據項;服務器通過答復WM_DDE_ACK消息提示是否它接收這個數據項;?
WM_DDE_EXECUTE = WM_DDE_FIRST + 8;?
一個DDE客戶程序提交此消息給一個DDE服務程序來發送一個字符串給服務器讓它象串行命


令一樣被處理,服務器通過提交WM_DDE_ACK消息來作回應;?
WM_DDE_LAST = WM_DDE_FIRST + 8;?
WM_APP = $8000;?
WM_USER = $0400;?
此消息能幫助應用程序自定義私有消息;?
/?
通知消息(Notification message)是指這樣一種消息,一個窗口內的子控件發生了一些事情


,需要通?
知父窗口。通知消息只適用于標準的窗口控件如按鈕、列表框、組合框、編輯框,以及


Windows 95公?
共控件如樹狀視圖、列表視圖等。例如,單擊或雙擊一個控件、在控件中選擇部分文本、操


作控件的?
滾動條都會產生通知消息。?
按扭?
B N _ C L I C K E D //用戶單擊了按鈕?
B N _ D I S A B L E //按鈕被禁止?
B N _ D O U B L E C L I C K E D //用戶雙擊了按鈕?
B N _ H I L I T E //用戶加亮了按鈕?
B N _ PA I N T按鈕應當重畫?
B N _ U N H I L I T E加亮應當去掉?
組合框?
C B N _ C L O S E U P組合框的列表框被關閉?
C B N _ D B L C L K用戶雙擊了一個字符串?
C B N _ D R O P D O W N組合框的列表框被拉出?
C B N _ E D I T C H A N G E用戶修改了編輯框中的文本?
C B N _ E D I T U P D AT E編輯框內的文本即將更新?
C B N _ E R R S PA C E組合框內存不足?
C B N _ K I L L F O C U S組合框失去輸入焦點?
C B N _ S E L C H A N G E在組合框中選擇了一項?
C B N _ S E L E N D C A N C E L用戶的選擇應當被取消?
C B N _ S E L E N D O K用戶的選擇是合法的?
C B N _ S E T F O C U S組合框獲得輸入焦點?
編輯框?
E N _ C H A N G E編輯框中的文本己更新?
E N _ E R R S PA C E編輯框內存不足?
E N _ H S C R O L L用戶點擊了水平滾動條?
E N _ K I L L F O C U S編輯框正在失去輸入焦點?
E N _ M A X T E X T插入的內容被截斷?
E N _ S E T F O C U S編輯框獲得輸入焦點?
E N _ U P D AT E編輯框中的文本將要更新?
E N _ V S C R O L L用戶點擊了垂直滾動條消息含義?
列表框?
L B N _ D B L C L K用戶雙擊了一項?
L B N _ E R R S PA C E列表框內存不夠?
L B N _ K I L L F O C U S列表框正在失去輸入焦點?
L B N _ S E L C A N C E L選擇被取消?
L B N _ S E L C H A N G E選擇了另一項?
L B N _ S E T F O C U S列表框獲得輸入焦點?
------------------------------------------------------------------
static bool flag = false;
? ? ? ? protected override void WndProc(ref Message m)//C# 重寫 WndProc 移動窗口
? ? ? ? {
? ? ? ? ? ?switch (m.Msg) {
? ? ? ? ? ? ? ? ?case 0x0200: //WM_MOUSEMOVE
? ? ? ? ? ? ? ? ? ? ? ? ?if (flag)
? ? ? ? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?PostMessage(this.Handle, 0x00A1,new IntPtr(2),m.LParam);//這里


需要導入 user32.dll?
? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ? ? ? ?case 0x201://WM_LBUTTONDOWN
? ? ? ? ? ? ? ? ? ? ? ? ?flag = true;
? ? ? ? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ? ? ? ?case 0x202://WM_LBUTTONUP
? ? ? ? ? ? ? ? ? ? ? ? flag = false;


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break;


? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? base.WndProc(ref m);
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }


? ? ? [DllImport("user32.dll", CharSet = CharSet.Unicode)]
? ? ? ? public static extern IntPtr PostMessage(IntPtr hwnd, int wMsg, IntPtr wParam,?


IntPtr lParam);
------------------------------------------------------------
?[DllImport("user32.dll")]
? ? ? ? public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wparam, int?


lparam);
? ? ? ? protected override void OnMouseDown(MouseEventArgs e)
? ? ? ? {
? ? ? ? ? ? base.OnMouseDown(e); if (e.Button == MouseButtons.Left)//按下的是鼠標左


鍵 ?
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Capture = false;//釋放鼠標,使能夠手動操作 ? ? ? ??
? ? ? ? ? ? ? ? SendMessage(Handle, 0x00A1, 2, 0);//拖動窗體 ? ??
? ? ? ? ? ? }
? ? ? ? }
?--------------------------------------------------------
? protected override void WndProc(ref Message m)
? ? ? ? {
? ? ? ? ? ? switch (m.Msg)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? case 0x0201://鼠標左鍵按下的消息
? ? ? ? ? ? ? ? ? ? m.Msg = 0x00A1;//更改消息為非客戶區按下鼠標
? ? ? ? ? ? ? ? ? ? m.LParam = IntPtr.Zero;//默認值
? ? ? ? ? ? ? ? ? ? m.WParam = new IntPtr(2);//鼠標放在標題欄內
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? ? base.WndProc(ref m);
? ? ? ? }
?----------------------------------------------------


?重寫 WndProc函數來同時實現無標題欄的窗體移動和禁止雙擊窗體最大化


protected override void WndProc(ref Message m)
? ? ? ? {
? ? ? ? ? ? const int WM_NCHITTEST = 0x84;
? ? ? ? ? ? const int HTCLIENT = 0x01;
? ? ? ? ? ? const int HTCAPTION = 0x02;
? ? ? ? ? ? const int WM_SYSCOMMAND = 0x112;
? ? ? ? ? ? const int SC_MAXMIZE = 0xF030;
? ? ? ? ? ? const int WM_NCLBUTTONDBLCLK = 0xA3;
? ? ? ? ? ? switch (m.Msg)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? case 0x4e:
? ? ? ? ? ? ? ? case 0xd:
? ? ? ? ? ? ? ? case 0xe:
? ? ? ? ? ? ? ? case 0x14:
? ? ? ? ? ? ? ? ? ? base.WndProc(ref m);
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case WM_NCHITTEST://鼠標點任意位置后可以拖動窗體
? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? this.DefWndProc(ref m);
? ? ? ? ? ? ? ? ? ? if (m.Result.ToInt32() == HTCLIENT)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? m.Result = new IntPtr(HTCAPTION);
? ? ? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? case WM_NCLBUTTONDBLCLK://禁止雙擊最大化
? ? ? ? ? ? ? ? ? ? Console.WriteLine(this.WindowState);
? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? return;


? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? base.WndProc(ref m);
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
----------------------------------------------------------
第一步,先在類的級別中申明兩個API函數,


  ///注冊熱鍵?
  [DllImport("user32.dll")]?
  private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers,?


Keys vk);?
  ///卸載熱鍵?
  [DllImport("user32.dll")]?
  private static extern bool UnregisterHotKey(IntPtr hWnd, int id);


  注意引入名字空間 System.Runtime.InteropServices;


  上面兩個函數參數的解釋:


  RegisterHotKey 函數中,


  hWnd為本程序窗口的句柄,在C#的窗口中直接用Handle屬性就可以引用窗口句柄


  id為熱鍵的標示符,是我們自己定義的,因為一個程序中可以定義多個熱鍵,所以要用


這個字段來區別,具體用法見下


  fsModifiers為激活熱鍵時,是否和系統鍵組合使用,none:0 Alt:1 Ctrl:2 Shift:4,并且還


可以用或運算來組合使用


  vk就是要定義的熱鍵,C#中按鍵都被包含在Keys枚舉中


  UnregisterHotKey 函數中,


  hWnd和RegisterHotKey 函數中是一樣的,id為要卸載的熱鍵標示


  第二步,在窗口的初始化中注冊熱鍵,例如 RegisterHotKey(Handle, 100, 0, Keys.F9);


  將些熱鍵識別為100,0表示不使用系統鍵,Keys.F9表示此熱鍵為F9,若要同時按


Shift+Ctrl+F9,則第三個參數應該為 2|4 其實對二進制運算熟悉的朋友,        


       可以立刻算出 2|4=6


  第三步,可以響應熱鍵了:


  重寫窗體的WndProc函數,具體代碼為


  protected override void WndProc(ref Message m) {?
  //這個if的條件中固定的?
  if (m.Msg == 0x312) {?
  //這個if就在于判斷是哪個熱鍵,100對應上面RegisterHotKey函數中的第二個參數?
  if (m.WParam.ToInt32() == 100) {?
  //這里就是響應的函數?
  DoSomething();?
  }?
  }?
  base.WndProc(ref m);?
  }


  WndProc()函數的功能就是處理Windows消息,在其它地方還將看到這個函數的妙用!


  第四步,在程序結束的時候調用UnregisterHotKey(Handle,100)卸載此熱鍵!


  WIN32


  第一步,在int WINAPI WinMain()函數中,


  while(GetMessage(&msg,NULL,0,0)){……}


  之前,注冊熱鍵


  RegisterHotKey(hWnd,100,0,VK_F9)


  VK_F9為WinUser.h中定義的宏,其他鍵也是用類似的形式進行定義,不過數字鍵和字


母鍵,直接用'0','A'這樣的形式


  第二步,在while(GetMessage(&msg,NULL,0,0)) {……}


  循環體內,添加代碼


  //這是響應熱鍵條件,從WM_HOTKEY宏的定義中,可以看出來它代表的值為 0x312?


,和C#中的if條件是一致的?
  if(msg.message ==WM_HOTKEY)?
  {?
  //這里的條件用來判斷熱鍵的標示符?
  if(msg.wParam==100)?
  {?
  //這里調用想要執行的函數?
  DoSomething();?
  }?
  }


  第三步,在while()循環結束后,調用 UnregisterHotKey(hWnd,100) 卸載熱鍵。


  MFC


  第一步,在MFC的窗體中添加其WM_HOTKEY消息的響應,


  void C熱鍵Dlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)?
  {?
  //這里用來判斷熱鍵的標識符?
  if(nHotKeyId == 100)?
  {?
  //響應函數?
  DoSomething();?
  }?
  CDialog::OnHotKey(nHotKeyId, nKey1, nKey2);?
  }


  第二步,在MFC窗體的初始化地方,添加注冊熱鍵的代碼:


  RegisterHotKey(m_hWnd,100,0,VK_F9);


  注意上面的字段m_hWnd,是CWnd類中字段,完成由MFC控制,我們只需要在適合地


方引用就可以了。


  第三步,在窗體銷毀的地方調用 UnregisterHotKey(hWnd,100) 卸載熱鍵就可以了。


  到這里,大家可以已經掌握了在三種環境中設置系統級熱鍵的方法。筆者的體會是,在


WIN32和C#中方法大概相同,筆者就是在C#的基礎上,嘗試著在WIN32中實現該功能,結


果一次成功,但是在MFC中就走了一些彎路。
------------------------------------------------------------------------


? protected override void WndProc(ref Message m)
? ? ? ? {
? ? ? ? ? ? switch (m.Msg)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? case 0x0005://change size: WM_SIZE
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? FormWindowState newState = FormWindowState.Normal;
? ? ? ? ? ? ? ? ? ? ? ? switch (m.WParam.ToInt32())
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? case 0://SIZE_RESTORED
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? newState = FormWindowState.Normal;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? case 1://SIZE_MINIMIZED
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? newState = FormWindowState.Minimized;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? case 2://SIZE_MAXIMIZED
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? newState = FormWindowState.Maximized;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? ? ? ? ? if (newState != this.preWindowState)
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? this.OnWindowStateChanged(new?


WindowStateChangedEventArgs(this.preWindowState, newState));
? ? ? ? ? ? ? ? ? ? ? ? ? ? this.preWindowState = newState;
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? default:
? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? ? base.WndProc(ref m);
? ? ? ? }
? ? ? ? #endregion
? ? }
}
========

總結

以上是生活随笔為你收集整理的C# 消息处理学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。