title: How to hook external process with SetWindowsHookEx and WH_KEYBOARD
body: <p>I am trying to hook for example Notepad without sucess. Making a global hook seems to work fine.</p>
  
  <p>Testing on XP SP2.</p>
  
  <p>Edit: Amended code works now.</p>
  
  <p>MyDLL code</p>
  
  <pre><code>#include &lt;windows.h&gt;
  #include &lt;iostream&gt;
  #include &lt;stdio.h&gt;
  
  HINSTANCE hinst;
  #pragma data_seg(".shared")
  HHOOK hhk;
  #pragma data_seg()
  //#pragma comment(linker, "/SECTION:.shared,RWS") compiler error in VC++ 2008 express
  
  LRESULT CALLBACK wireKeyboardProc(int code, WPARAM wParam,LPARAM lParam) {  
      if (code &lt; 0) {
          return CallNextHookEx(0, code, wParam, lParam);
      }
      Beep(1000, 20);
      return CallNextHookEx(hhk, code, wParam, lParam);
  }
  
  extern "C" __declspec(dllexport) void install(unsigned long threadID) { 
      hhk = SetWindowsHookEx(WH_KEYBOARD, wireKeyboardProc, hinst, threadID);
  }
  extern "C" __declspec(dllexport) void uninstall() {
      UnhookWindowsHookEx(hhk); 
  }
  
  BOOL WINAPI DllMain(__in HINSTANCE hinstDLL, __in  DWORD fdwReason, __in  LPVOID lpvReserved) {
      hinst = hinstDLL;
      return TRUE;
  }
  </code></pre>
  
  <p>My program</p>
  
  <pre><code>#include &lt;Windows.h&gt;
  
  unsigned long GetTargetThreadIdFromWindow(char *className, char *windowName)
  {
      HWND targetWnd;
      HANDLE hProcess;
      unsigned long processID = 0;
  
      targetWnd = FindWindow(className, windowName);
      return GetWindowThreadProcessId(targetWnd, &amp;processID);
  } 
  
  int _tmain(int argc, _TCHAR* argv[]) {
      unsigned long threadID = GetTargetProcessIdFromWindow("Notepad", "Untitled - Notepad");
      printf("TID: %i", threadID);    
  
      HINSTANCE hinst = LoadLibrary(_T("MyDLL.dll")); 
  
      if (hinst) {
          typedef void (*Install)(unsigned long);
          typedef void (*Uninstall)();
  
          Install install = (Install) GetProcAddress(hinst, "install");
          Uninstall uninstall = (Uninstall) GetProcAddress(hinst, "uninstall");
  
          install(threadID);
  
          Sleep(20000);
  
          uninstall();
      }
  
      return 0;
  }
  </code></pre>