在继承的窗体中,可以重写WndProc方法。
    但我现在要做一个控件,通过Form f=this.FindForm()来获得控件在窗体
    而且我还想重写f的WndProc方法,但这个方法是受保护的虚方法,不在派生类中,无法看到。这时该如何做?

解决方案 »

  1.   

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;namespace WindowsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            private delegate IntPtr WndProcCallBack(IntPtr hwnd, int Msg, IntPtr wParam, IntPtr lParam);        [DllImport("user32.dll", SetLastError = true)]
            private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
            [DllImport("user32.dll", SetLastError = true)]
            private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
            [DllImport("User32.dll")]
            private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
            private const int GWL_WNDPROC = -4;
            private IntPtr prevWndFunc;
            private const int WM_MOUSEMOVE = 0x0200;        private IntPtr newWndProc(IntPtr hWnd, int iMsg, IntPtr wParam, IntPtr lParam)
            {
                switch (iMsg)
                {
                    case WM_MOUSEMOVE:
                        Text = "MouseMove: " + DateTime.Now.ToString();
                        break;
                }
                return CallWindowProc(prevWndFunc, hWnd, iMsg, wParam, lParam);
            }        private void Form1_Load(object sender, EventArgs e)
            {
                prevWndFunc = new IntPtr(GetWindowLong(button1.Handle, GWL_WNDPROC));
                Text = prevWndFunc.ToString();
                WndProcCallBack vWndProcCallBack = new WndProcCallBack(newWndProc);
                SetWindowLong(button1.Handle, GWL_WNDPROC, 
                    Marshal.GetFunctionPointerForDelegate(vWndProcCallBack).ToInt32());
            }        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
            {
                SetWindowLong(button1.Handle, GWL_WNDPROC, prevWndFunc.ToInt32());
                prevWndFunc = IntPtr.Zero;
            }
        }
    }
      

  2.   

    谢谢楼上的:)感觉又回到了C++的年代
    有没有不调用API的方法?
      

  3.   

    。net System.Windows.Forms.NativeWindow 类继承这个类有一个 AssignHandle 方法把,把有控件句柄对象传进取就可以了(Form 也可以)然后就和可以重写很多东西了,就和从写具体到 Google找 或 msdn 里也有列子
    不过不要记 ReleaseHandle(); 否则会出怪异的问题。以前VS2002写过,现在找不到了已经
      

  4.   

    楼主的意思是,想在运行时获取控件的容器窗体后,动态更改该窗体的WinProc的行为,这和继承没有关系,是纯粹的运行时技巧。所以zswang(伴水清清)(专家门诊清洁工)的办法是唯一的。