【问题标题】:Why isn't "protected override void WndProc(ref Message m)" working为什么“受保护的覆盖无效 WndProc(ref Message m)”不起作用
【发布时间】:2017-11-22 02:35:50
【问题描述】:

我已经尝试了很长时间了。我已经搜索了好几次,并且阅读了更多关于此的文章和问题,而不是我记得的,我似乎无法弄清楚到底出了什么问题。这是我一直在尝试编译的一个小程序,用于测试生成应用程序使用的热键。

我一直试图弄清楚的测试来源如下:

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Prg
{
    class MainClass
    {
        [DllImport("User32.dll")]
        private static extern int RegisterHotKey(IntPtr hWnd, int id, int 
        fsModifiers, int vk);
        [DllImport("User32.dll")]
        private static extern int UnregisterHotKey(IntPtr hWnd, int id);

        public static Form f1 = new Form();

        public static int Register(Form f)
        {
            IntPtr ip = f.Handle;
            return RegisterHotKey(ip, 1, 0, (int)Keys.Escape);
        }

        public static void b1_click(object sender, EventArgs e)
        {
            //Blah Blah stuff
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0312)
            {
                MessageBox.Show("wow");
            }
            base.WndProc(ref m);
        }
        public static void Main()
        {
            Button b1 = new Button();
            b1.Location = new Point(10, 10);
            b1.Text = "wow";
            b1.Click += new EventHandler(b1_click);
            f1.Width = 200;
            f1.Height = 200;
            f1.Controls.Add(b1);
            f1.ShowDialog();
            Register(f1);
        }
    }
}

我一直在使用 C# 4.0 编译 csc.exe。每次我尝试编译此代码或类似代码时,都会不断收到此错误:

Main.csx(37,27):错误 CS0115: 'Prg.MainClass.WndProc(System.Windows.Forms.Message)':找不到合适的方法来覆盖

使用 User32.dll 注册热键的每个示例都在其中包含“受保护的覆盖 WndProc”方法,每个人都说它对他们来说工作得很好,但我不知道为什么它不起作用为了我的一生。如果有人可以帮助我解决这个问题,将不胜感激。我使用的是 Windows 7 Professional 64 位,csc.exe 的路径是 C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe

谢谢:)


编辑


我现在已经编译好了,但是现在的问题是它似乎没有注册和热键,或者至少根本没有拿起 KeyPress。我的代码有错误吗?

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Prg
{
    class MainClass : Form
    {
        [DllImport("User32.dll")]
        private static extern int RegisterHotKey(IntPtr hWnd, int id, int 
        fsModifiers, int vk);
        [DllImport("User32.dll")]
        private static extern int UnregisterHotKey(IntPtr hWnd, int id);

        public static Form f1 = new Form();

        public static int Register(Form f)
        {
            IntPtr ip = f.Handle;
            return RegisterHotKey(ip, 1, 0, (int)Keys.Escape);
        }

        public static void b1_click(object sender, EventArgs e)
        {
            //Blah Blah stuff
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0312)
            {
                MessageBox.Show("wow");
            }
            base.WndProc(ref m);
        }
        public static void Main()
        {
            Button b1 = new Button();
            b1.Location = new Point(10, 10);
            b1.Text = "wow";
            b1.Click += new EventHandler(b1_click);
            f1.Width = 200;
            f1.Height = 200;
            f1.Controls.Add(b1);
            f1.ShowDialog();
            Register(f1);
        }
    }
}

我尝试了几种不同的解决方案,但都没有让热键工作。我什至尝试重写源代码以使用 Application.Run(new MainClass());但即使表单获得焦点,它仍然没有检测到 Keypress。


编辑


感谢 zzxyz 帮助编译,Antoine 帮助我修复了代码中的错误,问题得以解决。多谢你们。这是编译和工作的代码,适用于任何可能遇到相同问题或只是喜欢通过示例学习的人。再次感谢。

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Prg
{
    class MainClass : Form
    {
        [DllImport("User32.dll")]
        private static extern int RegisterHotKey(IntPtr hWnd, int id, int 
        fsModifiers, int vk);
        [DllImport("User32.dll")]
        private static extern int UnregisterHotKey(IntPtr hWnd, int id);

        public static MainClass f1 = new MainClass();

        public static int Register(Form f)
        {
            IntPtr ip = f.Handle;
            return RegisterHotKey(ip, 1, 0, (int)Keys.Escape);
        }

        public static void b1_click(object sender, EventArgs e)
        {
            //Blah Blah stuff
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0312)
            {
                MessageBox.Show("wow");
            }
            base.WndProc(ref m);
        }
        public static void Main()
        {
            Button b1 = new Button();
            b1.Location = new Point(10, 10);
            b1.Text = "wow";
            b1.Click += new EventHandler(b1_click);
            f1.Width = 200;
            f1.Height = 200;
            f1.Controls.Add(b1);
            Register(f1);
            f1.ShowDialog();
        }
    }
}

【问题讨论】:

  • 你的类不是从Object以外的任何东西派生的。没有WndProc
  • WndProc 在Form 中声明,因此要覆盖它,您需要在派生自它的类中。表单派生类也是您通常添加按钮等的地方。

标签: c# winforms wndproc registerhotkey


【解决方案1】:

2 个错误:

  • 您必须在显示 f1 之前注册热键。交换最后两行

  • 目前,您覆盖 MainClass 的 WndProc,而不是每个窗体。因此,您的表单 f1 继承了基本的 Form.WndProc,而不是您覆盖的表单。因此,只需将 f1 声明为 MainClass,它就会起作用。

【讨论】:

  • 嘿,谢谢你的总结。你不仅解决了问题,而且用两个简单的句子消除了相当多的困惑。谢谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-05
  • 2015-01-12
  • 1970-01-01
  • 2012-01-31
  • 1970-01-01
  • 2013-07-01
  • 2016-12-28
相关资源
最近更新 更多