title: Receiving WM_COPYDATA in Python
body: <p>I am trying to read from Python the <code>WM_COPYDATA</code> message some applications (I'm trying with Spotify) send to WindowsLiveMessenger to update the "What I'm listening to..." phrase.</p>
  
  <p>From what I have been able to find, <code>WM_COPYDATA</code> messages come in a <code>COPYDATASTRUCT</code> with the following structure:</p>
  
  <ul>
  <li><code>dwData</code> in our case 0x547 so that it access the listening now feature  </li>
  <li><code>cbData</code> with the length of the string received  </li>
  <li><code>lpData</code> with a pointer to the string itself, may include Unicode characters</li>
  </ul>
  
  <p>The string should have the following format: <code>\0Music\0status\0format\0song\0artist\0album\0</code> as stated by <a href="http://listeningnowtracker.googlecode.com/svn-history/r8/trunk/ListeningNowTracker/README.TXT" rel="noreferrer">ListeningNowTracker</a></p>
  
  <p>What we receive in a <code>WM_COPYDATA</code> event is a pointer for <code>lParam</code> that contains the <code>COPYDATASTRUCT</code>.</p>
  
  <p>I started tinkering with pywin32 functions and I remembered that they do not accept Unicode characters from past experience, then I switched to ctypes. Despite this being an almost new world in Python for me, I tried with <code>POINTER()</code> and all I got was unknown objects for me or access violations.</p>
  
  <p>I think that the code should create a <code>COPYDATASTRUCT</code>:</p>
  
  <pre><code>class CopyDataStruct(Structure):
      _fields_ = [('dwData', c_int),
                  ('cbData', c_int),
                  ('lpData', c_void_p)]
  </code></pre>
  
  <p>Then make the <code>lParam</code> be a pointer to that structure, get the string pointer from <code>lpData</code> and finally get the string with <code>ctypes.string_at(lpData,cbData)</code>.</p>
  
  <p>Any tips?</p>
  
  <p><strong>UPDATE 1</strong></p>
  
  <p>The <code>WM_COPYDATA</code> event is received by a hidden window built with <code>win32gui</code> just for this purpose. The copydata event is connected to a function called <code>OnCopyData</code> and this is its header:<br>
  <code>def OnCopyData(self, hwnd, msg, wparam, lparam):</code><br>
  The values the function delivers are correct as compared with the ones from the Spy++ messages log.</p>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>This should be close to what I want, but gives a NULL pointer error.</p>
  
  <pre><code>class CopyDataStruct(ctypes.Structure):
      _fields_ = [('dwData', c_int),
                  ('cbData', c_int),
                  ('lpData', c_wchar_p)]
  
  PCOPYDATASTRUCT = ctypes.POINTER(CopyDataStruct)
  pCDS = ctypes.cast(lparam,  PCOPYDATASTRUCT)
  print ctypes.wstring_at(pCDS.contents.lpData)
  </code></pre>