title: Drag and drop files/text to tray icon (C#, WindowsForms)
body: <p>I'm trying allow drag and drop to the tray icon on my application.</p>
  
  <p>I know it's <a href="https://stackoverflow.com/questions/2742954/drag-and-drop-on-notifyicon-in-tray-in-c">impossible</a> to do this with the higher level C# WindowsForms API, since <code>NotifyIcon</code> doesn't support drag events.</p>
  
  <p>So with a little help of a more windows-experienced friend I set out to try this via Win32 API. The idea was registering a hook in the tray window handler (after setting <code>DragAcceptFiles(hWnd,TRUE);</code> on the "SysPager" window handler).</p>
  
  <p>The hooking and dropping part is working from the tray to the DLL.</p>
  
  <pre><code>LRESULT CALLBACK myHookProc (int code, WPARAM wParam, LPARAM lParam){
    if (code == HC_ACTION)
    {
      PMSG msg = (PMSG) lParam;
      switch(msg-&gt;message){
        case WM_DROPFILES:
          ::MessageBox(NULL, L"Dropped files!", L"Test", MB_OK);
          // call my app's registered hook
          break;
    }
    return CallNextHookEx(oldHookProc, code, wParam, lParam);
  }
  </code></pre>
  
  <p>As expected I get the message box popping up.</p>
  
  <p>The problem is that I now need to call a function on my C# (WindowsForms) application to notify of this event. Here's where I ran into brick wall.</p>
  
  <p>When I register the callback from my application in the DLL, I store it; but when <code>myHookProc</code> is called, it's value is NULL.</p>
  
  <p>Turns out I was misunderstanding how DLLs work; there isn't a shared instance between my application and the tray area (they're copied or each has its own "instance" if you could call it that) so I can't use any static variables or anything like that to hold the callback reference back to my application.</p>
  
  <p>Spent a couple of hours investigating this and the only solution seems to be shared memory (tried the <code>#pragma data_seg</code> I ran into in some forum, but to no avail), but it starts to feel too much of an overkill for such a "simple" use case.</p>
  
  <p>So the million dollar questions are:</p>
  
  <ol>
  <li>Is it really necessary to offload the hooking to a DLL?</li>
  <li>Do I really need to resort to shared memory to accomplish this?</li>
  <li>(Bonus question) WM_DROPFILES only works for files; how can I get a drop event fired for text?</li>
  </ol>
  
  <p>Please keep in mind this is my first shot with .NET, C# and Win32 (less than a week); detailed answers explaining why - rather than just stating - will be greatly appreciated!</p>
  
  <p>Thanks.</p>