2017-08-10 5 views
-2

je le code suivant dans un formulaire:Un initialiseur sur le terrain ne peut pas référencer le champ non statique, la méthode ou la propriété

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

qui me donne l'erreur suivante sur Microsoft C# 2008:

un initialiseur de domaine ne peut pas référencer le champ non statique, la méthode ou la propriété 'ScreenShots.ScreenShotConfigurationForm.HookCallback (int, System.IntPtr, System.IntPtr)'

  1. Qu'est-ce que cela signifie?
  2. Comment puis-je le résoudre?

Une capture d'écran de ce que je vois: enter image description here

+4

Si cette méthode nécessite une forme existante pour faire son travail alors * il ne doit pas être statique *. Si le * comportement * de la méthode est que c'est supposé * faire, c'est travailler sur un nouveau formulaire, plutôt que sur un formulaire existant, alors créer un nouveau formulaire est (par définition) correct. – Servy

+0

Et si la méthode n'a pas besoin d'une instance pour faire son travail, la rendre statique (et/ou la sortir de cette classe). – Blorgbeard

+0

* cela signifie que je dois instancier une nouvelle instance de la forme ou de l'icône chaque fois que j'appelle cette méthode * - pas nécessaire 'var myForm = new MyForm1();' Si vous avez un code comme ci-dessus, alors vous pouvez utiliser la variable 'myForm' pour appeler n'importe quelle méthode non-statique – Subbu

Répondre

0

Qu'est-ce que cela signifie?

L'erreur dit:

A field initializer

Il fait référence au champ private LowLevelKeyboardProc _proc. C'est un champ non statique. La partie de l'initialiseur est = HookCallback;.

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

HookCallback est une méthode non-statique, et l'initialisation du champ ne fait évidemment référence à elle. Ce qui est interdit ici, ce sont les membres d'instance qui sont initialisés avec d'autres membres d'instance. Comme ils sont tous initialisés "en même temps" - quand l'instance est créée - ils ne doivent pas se référer les uns aux autres lors de l'initialisation.

C'est quelque chose que le compilateur C# pourrait réellement comprendre en théorie - la spécification définit un ordre spécifique dans lequel les initialiseurs s'exécutent - mais pour une raison quelconque, les concepteurs ont choisi le message d'erreur.

Comment le réparer?

Les initialiseurs de champ ne sont autorisés qu'à accéder aux membres de l'instance. Vous pouvez accéder aux membres d'instance dans le constructeur, qui s'exécute juste après les initialiseurs de champ. Donc, il suffit de déplacer l'initialisation à votre constructeur (comme recommended by Microsoft):

private LowLevelKeyboardProc _proc; 

public ScreenShotConfigurationForm() 
{ 
    InitializeComponent(); 
    _proc = HookCallback; 
} 
+0

Yeaaooohhh !!! Merci beaucoup: J'essayais de résoudre ce problème au moins 5 jours en vain ... et la solution était si évidente ... un peu incroyable ... Merci vraiment !!! –