-2

I have the following code into a Form:

using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Media;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ScreenShots
{
    public partial class ScreenShotConfigurationForm : Form
    {

        // ----- some other stuff (code, methods, etc...) is placed in here -----

        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x0100;
        private LowLevelKeyboardProc _proc = HookCallback; // <<<< This is the row that is causing the error
        private IntPtr _hookID = IntPtr.Zero;

        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);
                if (vkCode == 44) // 44 is the key code of PrintScreen button
                {
                    MakeScreenShot();
                }
            }

            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

        private IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())

            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]

        private extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private extern IntPtr GetModuleHandle(string lpModuleName);
    }
}

That is giving me the following error on Microsoft C# 2008:

A field initializer cannot reference the non-static field, method, or property 'ScreenShots.ScreenShotConfigurationForm.HookCallback(int, System.IntPtr, System.IntPtr)'

  1. What does it mean?
  2. How can I solve it?

A screenshot of what I see: enter image description here

willy wonka
  • 1,440
  • 1
  • 18
  • 31
  • 4
    If that method requires an existing form to do its work then *it shouldn't be static*. If the *behavior* of the method is that it's *supposed* to do it's work on a new form, rather than some existing form, then creating a new form is (by definition) correct. – Servy Aug 10 '17 at 17:28
  • And if the method doesn't need an instance in order to do its work, make it static (and/or move it out of that class). – Blorgbeard Aug 10 '17 at 17:36
  • *it means that I must instantiate a new instance of the form or of the icon every time I call that method* - not necessary `var myForm = new MyForm1();` If you have a code as above, then you can use the variable `myForm` to call any non-static method – Subbu Aug 10 '17 at 17:37
  • 2
    Please show your code and errors - ideally as a [mcve] - in *text* rather than as screenshots. Screenshots make it much harder to read, and we can't copy/paste the code. – Jon Skeet Aug 10 '17 at 17:54
  • 1
    That's a *very* long way from being a *minimal* example. – Jon Skeet Aug 10 '17 at 22:43
  • 1
    You've gone down this rabbit hole the wrong way. Go back to your initial error: "A field initializer cannot reference the non-static ..". Don't just try things until it goes away - that has just caused you more problems. You need to understand what that error means in order to fix it the right way. – Blorgbeard Aug 10 '17 at 23:45
  • @Blorgbeard I've reedited the question the previous was too messy. – willy wonka Aug 11 '17 at 03:32
  • @Servy I've reedited the question the previous was too messy. – willy wonka Aug 11 '17 at 03:33
  • @Subbu I've reedited the question the previous was too messy. – willy wonka Aug 11 '17 at 03:33
  • @JonSkeet I've reedited the question the previous was too messy. – willy wonka Aug 11 '17 at 03:34

1 Answers1

3

What does it mean?

The error said:

A field initializer

It's referring to the field private LowLevelKeyboardProc _proc. It's a non-static field. The initializer part is = HookCallback;.

cannot reference the non-static field, method, or property 'HookCallback'

HookCallback is a non-static method, and the field initializer is obviously referring to it.

The thing that is forbidden here is instance members being initialized with other instance members. Since they are all initialized "at the same time" - when the instance is created - they should not refer to each other when being initialized.

It's something that the C# compiler could actually figure out in theory - the spec defines a specific order in which initializers run - but for whatever reason, the designers went with the error message instead.

How do you fix it?

It's only field initializers which aren't allowed to access instance members. You can access instance members in the constructor, which runs right after the field initializers. So, just move the initialization to your constructor (as recommended by Microsoft):

private LowLevelKeyboardProc _proc;

public ScreenShotConfigurationForm()
{
    InitializeComponent();
    _proc = HookCallback;
}
Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
  • Yeaaooohhh!!! Thanks very much: I was trying to solve such issue at least 5 days in vain... and the solution was so obvious... kind of incredible... Thanks really!!! – willy wonka Aug 11 '17 at 06:31
  • 1
    I also want to add thanks - No body answered my question but @willywonka's code was almost identical to mine (except my HookCallBack was static) and therefore not working. Your answer solved the problem for me, thank you very much!!! – Chud37 Oct 05 '18 at 11:00