Почему не работает защищенное переопределение void WndProc (ref Message m)

Я пытался понять это уже очень давно; Я искал это несколько раз и читал больше статей и вопросов по этому поводу, чем я могу вспомнить, и я не могу точно понять, что происходит не так. Это небольшая программа, которую я пытался скомпилировать, чтобы протестировать создание горячей клавиши для использования приложением.

Источник для теста, который я пытался выяснить, выглядит следующим образом:

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);
        }
    }
}

Я компилировал csc.exe с использованием С# 4.0. Каждый раз, когда я пытаюсь скомпилировать этот или аналогичный код, я продолжаю получать эту ошибку:

Main.csx(37,27): ошибка CS0115: «Prg.MainClass.WndProc(System.Windows.Forms.Message)»: не найден подходящий метод для переопределения

В каждом примере использования User32.dll для регистрации горячей клавиши был метод «защищенного переопределения WndProc», и все говорили, что у них он работал нормально, но я не могу понять, почему он не будет работать на всю жизнь. меня. Если бы кто-то мог помочь мне решить эту проблему, это было бы очень признательно. Я использую 64-разрядную версию Windows 7 Professional, а путь к файлу 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()); но он по-прежнему не обнаруживал нажатия клавиш, даже когда форма была сфокусирована.


Редактировать


Проблема решена благодаря 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();
        }
    }
}

person Devon Mathews    schedule 22.11.2017    source источник
comment
ваш класс не происходит ни от чего, кроме Object. для этого нет WndProc.   -  person Daniel A. White    schedule 22.11.2017
comment
WndProc объявлен в Form, поэтому, чтобы переопределить его, вам нужно находиться в классе, производном от него. В классе, производном от Form, вы обычно добавляете кнопки и тому подобное.   -  person zzxyz    schedule 22.11.2017


Ответы (1)


2 ошибки:

  • вы должны зарегистрировать горячие клавиши, прежде чем показывать свой f1. Поменять местами последние 2 строки

  • в настоящее время вы переопределяете WndProc для MainClass, а не для каждой формы. Таким образом, ваша форма f1 наследует базовый Form.WndProc, а не переопределенный. Так что просто объявите f1 как MainClass, и все заработает.

person Antoine    schedule 22.11.2017
comment
Эй, спасибо за подведение итогов. Вы не только решили проблему, но и прояснили некоторую путаницу с помощью двух простых предложений. Спасибо :) - person Devon Mathews; 22.11.2017