WINDOWS 訊息處理的盡情擁抱(C#)

來源:互聯網
上載者:User

就任何一個程式員來說,對WINDOWS訊息機制的認知和對訊息的處理,可以說是必修的內容。我們知道,WINDOWS訊息的兩個參數wParam 、lParam有時是數實值型別,有時則是指標類型。特別是指標類型,它指向的是一個記憶體位址,那麼對它們的處理則因開發語言的不同而有所不同。

    都說C#取消了指標(非安全模式例外),可我個人覺得,C#並沒有真正取消指標,只是把她裝扮得更加迷人罷了!而不需程式員通過 *p 之類去直接處理而已。

    下面我就以一個常式,來看看C#中是如何處理WINDOWS訊息中指標類型的參數的。這個常式是AOGO曾經用MASM彙編來實現的,這就是限制一個表單大小的變化在一個許可的範圍內。本常式只限制寬度不超過600。

    這裡主要涉及到兩個問題:
1. 如何取得指標所指向的記憶體位址中的內容?
2. 如何將指標指向新的內容?(也可能是將新內容複寫到指標所指向的記憶體位址中)

處理這兩個問題的方法哦是知道了,至於它的內部實現機制哦就不明白了 ^_^ ^_^ ^_^
有了這兩個方法,我們就可以對WINDOWS的任何訊息進行處理了。C#的厲害由此可見!!!

好啦,哦不多說啦。看源碼就啥都明白了

===================== Form1.cs =====================

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;   // 注意這個命名空間

namespace WinMsgApp
{

   public class Form1 : System.Windows.Forms.Form
   {

      // 聲明Winodws訊息常量
      private const int WM_SIZEING = 0x0214;

      // 聲明RECT結構
      public struct RECT
      {
         public int left;
         public int top;
         public int right;
         public int bottom;
      }

      // 以下是C# IDE自動產生的程式碼
      private System.Windows.Forms.TextBox textBox1;
      private System.Windows.Forms.TextBox textBox2;
      private System.Windows.Forms.TextBox textBox3;
      private System.Windows.Forms.TextBox textBox4;
      private System.Windows.Forms.Label label1;
      private System.Windows.Forms.Label label2;
      private System.Windows.Forms.Label label3;
      private System.Windows.Forms.Label label4;
      
      private System.ComponentModel.Container components = null;

      public Form1()
      {
         InitializeComponent();
      }

      protected override void Dispose( bool disposing )
      {
         if( disposing )
         {
            if (components != null)
            {
               components.Dispose();
            }
         }
         base.Dispose( disposing );
      }

      #region Windows Form Designer generated code

      private void InitializeComponent()
      {
         this.textBox1 = new System.Windows.Forms.TextBox();
         this.textBox2 = new System.Windows.Forms.TextBox();
         this.textBox3 = new System.Windows.Forms.TextBox();
         this.textBox4 = new System.Windows.Forms.TextBox();
         this.label1 = new System.Windows.Forms.Label();
         this.label2 = new System.Windows.Forms.Label();
         this.label3 = new System.Windows.Forms.Label();
         this.label4 = new System.Windows.Forms.Label();
         this.SuspendLayout();
         //
         // textBox1
         //
         this.textBox1.Location = new System.Drawing.Point(80, 8);
         this.textBox1.Name = "textBox1";
         this.textBox1.TabIndex = 0;
         this.textBox1.Text = "";
         //
         // textBox2
         //
         this.textBox2.Location = new System.Drawing.Point(80, 32);
         this.textBox2.Name = "textBox2";
         this.textBox2.TabIndex = 1;
         this.textBox2.Text = "";
         //
         // textBox3
         //
         this.textBox3.Location = new System.Drawing.Point(80, 56);
         this.textBox3.Name = "textBox3";
         this.textBox3.TabIndex = 2;
         this.textBox3.Text = "";
         //
         // textBox4
         //
         this.textBox4.Location = new System.Drawing.Point(80, 80);
         this.textBox4.Name = "textBox4";
         this.textBox4.TabIndex = 3;
         this.textBox4.Text = "";
         //
         // label1
         //
         this.label1.Location = new System.Drawing.Point(0, 8);
         this.label1.Name = "label1";
         this.label1.Size = new System.Drawing.Size(78, 23);
         this.label1.TabIndex = 4;
         this.label1.Text = "Left:";
         this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
         //
         // label2
         //
         this.label2.Location = new System.Drawing.Point(0, 32);
         this.label2.Name = "label2";
         this.label2.Size = new System.Drawing.Size(78, 23);
         this.label2.TabIndex = 5;
         this.label2.Text = "Top:";
         this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
         //
         // label3
         //
         this.label3.Location = new System.Drawing.Point(0, 56);
         this.label3.Name = "label3";
         this.label3.Size = new System.Drawing.Size(78, 23);
         this.label3.TabIndex = 6;
         this.label3.Text = "Right:";
         this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
         //
         // label4
         //
         this.label4.Location = new System.Drawing.Point(0, 80);
         this.label4.Name = "label4";
         this.label4.Size = new System.Drawing.Size(78, 23);
         this.label4.TabIndex = 7;
         this.label4.Text = "Bottom:";
         this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
         //
         // Form1
         //
         this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
         this.ClientSize = new System.Drawing.Size(296, 117);
         this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                        this.label4,
                                                        this.label3,
                                                        this.label2,
                                                        this.label1,
                                                        this.textBox4,
                                                        this.textBox3,
                                                        this.textBox2,
                                                        this.textBox1});
         this.Name = "Form1";
         this.Text = "Form1";
         this.ResumeLayout(false);

      }
      #endregion
      // 自動產生的程式碼到此結束

      // 以下是處理WINDOWS訊息的主要代碼
      protected override void WndProc(ref System.Windows.Forms.Message m )
      {
         switch(m.Msg)
         {      
            case WM_SIZEING:
                
               // 第一種方法,簡潔明了
               // RECT rc = (RECT)m.GetLParam(typeof(RECT));

               // 第二種方法,易懂稍繁
               RECT rc = new RECT();

               // 將m.LParam指標所指向的RECT結構複製到rc
               rc = (RECT)m.GetLParam(rc.GetType());

               // 將結構rc各欄位的值顯示出來
               textBox1.Text = rc.left.ToString();
               textBox2.Text = rc.top.ToString();
               textBox3.Text = rc.right.ToString();
               textBox4.Text = rc.bottom.ToString();

               // 限制表單寬度不超過600
               if (rc.right - rc.left >600)
               {
                  rc.right =rc.left +600;
               }

               // 將結構rc複製到m.LParam指標所指向的RECT結構
               Marshal.StructureToPtr(rc,m.LParam,true);

               break;
            default:
               base.WndProc(ref m);   // 調用基類函數處理其他訊息。
               break;
         }
      }
      
  
      [STAThread]
      static void Main()
      {
         Application.Run(new Form1());
      }
   }
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.