title: C++ KeyBoard hook
body: <p>Subject: substitute certain keys to another key value.</p>
  
  <p>For e.g. if I press P it should be F24.</p>
  
  <p>When I try to load key values from .ini file hook ceases to be a global. It works only if winapi form in focus.</p>
  
  <p>My DLL code:</p>
  
  <pre><code>    extern "C" __declspec(dllexport) LRESULT CALLBACK KeyboardHook(int, WPARAM, LPARAM);
      extern "C" __declspec(dllexport) void loadSettings(LPSTR);
      bool shouldUpdateKey = false;
  
      int ArcherKey;
  
      LRESULT CALLBACK KeyboardHook(int code, WPARAM wParam, LPARAM lParam)
          {
  
              if ((lParam &gt;&gt; 20))
              {
                  if (wParam == ArcherKey) 
                  {
                  shouldUpdateKey = shouldUpdateKey ? false : true;
                  if (shouldUpdateKey) 
                  {
                  MessageBox(NULL, L"ArcherKey", L"", MB_OK);
                  keybd_event(0x87, 45, 1, 0); //press F24
                  return 1; 
                  }
                  }
              }
  
  
              return CallNextHookEx(NULL, code, wParam, lParam);
          }
  
        LPSTR GetValueFromINI(LPSTR FileName, LPSTR Section, LPSTR Key)
          {
              char *key;
              key = (char *)malloc(256);
              GetPrivateProfileStringA(Section, Key, NULL, key, 256, FileName);
              return key;
              free(key);
          }
  
        void loadSettings(LPSTR FileName) 
          {
              ArcherKey = atoi(GetValueFromINI(FileName, "HotKey", "Archer key"));
          }
  </code></pre>
  
  <p>I use <strong>shouldUpdateKey</strong> to avoid x2 callback (when key pressed down and pressed up) call. Also i try to add this statement <strong>if (lParam >>31) ^ 1</strong>, but this statement always false.</p>
  
  <p>.exe code:</p>
  
  <pre><code>LRESULT(*pKeybHook)(int, WPARAM, LPARAM);
  HHOOK hhookMsg;
  void(*loadSettings)(LPSTR);
  
  int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                       _In_opt_ HINSTANCE hPrevInstance,
                       _In_ LPTSTR    lpCmdLine,
                       _In_ int       nCmdShow)
  {
  /* default code */
  
  HMODULE dll = LoadLibrary(_T("MainHookDLL.dll"));
      if (dll)
      {
  
          pKeybHook = (LRESULT(*)(int, WPARAM, LPARAM)) GetProcAddress(dll, "_KeyboardHook@12");
  
          loadSettings = (void(*)(LPSTR)) GetProcAddress(dll, "loadSettings");
  
          loadSettings("C:\\Settings.ini");
  
          hhookMsg = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)(pKeybHook), dll, 0);
  
      }
  
  /* defult code */
      UnhookWindowsHookEx(hhookMsg); // unhook
      FreeLibrary(dll);
      return (int) msg.wParam;
  }       
  </code></pre>
  
  <p><strong>Settings.ini structure:</strong></p>
  
  <pre><code>[HotKey]
  Archer key=80
  </code></pre>
  
  <p>So my problem:
  If try to load settings from file, hook works only in active winapi window. It shows MessageBox\etc, but only in active winapi form.
  If replace <strong>wParam == ArcherKey</strong> to <strong>wParam == 80</strong> it works global, in all apps.
  I debug my application, after load from .ini file i have ArcherKey = 80. So I really can't understand what a mistake I actually have.</p>