Ok guys... this is my solution for unicode clipboard support in Windows VM... It works fine... I can make some improvements in memory management but it's ok for now...
 

/****************************************************************************/
/*                      Clipboard                                           */
/****************************************************************************/
 
int clipboardSize(void)
{ HANDLE h, h2;
  WCHAR *src;
  unsigned char *csrc;
  int len, bytesNeeded;
 
  // Do we have text in the clipboard?
  if(!IsClipboardFormatAvailable(CF_TEXT))
    return 0;
  if(!OpenClipboard(stWindow))
    return 0;
 
  // Get it in unicode format.
  h = GetClipboardData(CF_UNICODETEXT);
 
  src = GlobalLock(h);
 
  // How many bytes do we want to store those unicode chars in UTF8 format?
  bytesNeeded = WideCharToMultiByte( CP_UTF8, 0, src, -1,
        NULL, 0, NULL, NULL );
 
  h2 = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, bytesNeeded);
  csrc = GlobalLock(h2);
 
  // Convert Unicode text to UTF8.
  WideCharToMultiByte( CP_UTF8, 0, src, -1,
        csrc, bytesNeeded, NULL, NULL );
 
  // Consider CrLf as a 1-byte character.
  len = bytesNeeded;
  while(len--)
    if(((*csrc == 13) && (csrc[1] == 10)))
      {
 bytesNeeded--;
 csrc++;
      }
    else
      {
 csrc++;
      } 
 

  // Clipboard size is bytesNeeded excluding the terminating character.
  len = bytesNeeded - 1;
 
  GlobalUnlock(h);
  GlobalUnlock(h2);
 
  return len;
}
 

/* send the given string to the clipboard */
int clipboardWriteFromAt(int count, int byteArrayIndex, int startIndex)
{ HANDLE h, h2;
  unsigned char *src;
  int wcharsNeeded, len;
  WCHAR *out, *tmp;
 
  if(!OpenClipboard(stWindow))
    return 0;
 
  // Get the pointer to the byte array.
  src = (unsigned char *)byteArrayIndex + startIndex;
 
  // How many WCHARs do we need to store the UTF8 represented bytes from Squeak?
  wcharsNeeded = MultiByteToWideChar( CP_UTF8, 0, src,
        count+1, NULL,  
 0 );
 
  // If we have Cr only "returns" then we will need another character for Lf.
  len = wcharsNeeded * sizeof(WCHAR);
  while(len--)
    if ((*src++ == 13) && (*src != 10))
      wcharsNeeded++; 
 
  // Point to start of byte aray.
  src = (unsigned char *)byteArrayIndex + startIndex;
 
  // Allocate needed memory for wcharsNeeded WCHARs.
  h = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, wcharsNeeded * sizeof(WCHAR));
  out = GlobalLock(h);
 
  // Convert them to Unicode UTF16.
  MultiByteToWideChar( CP_UTF8, 0, src,
        count+1, out,  
 wcharsNeeded );
 
  // Allocate needed memory for intermediate buffer.
  // OK, i could do some more work here in order to avoid a whole new buffer just for
  // fixing the CrLf thing, but it's ok for now...
  h2 = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, wcharsNeeded * sizeof(WCHAR));
  tmp = GlobalLock(h2);
 
  // Add missing Lf characters...
  len = wcharsNeeded;
  while(len--)
    if((*out == 13))
      { /* special case: crlf translation */
 *tmp = 13;
 tmp++;
 *tmp = 10;
 tmp++;
 out++;
      }
    else
      { /* regular case: lookup translation */
 *tmp = *out;
 tmp++;
 out++;
      }
 
  EmptyClipboard();
  GlobalUnlock(h);
  GlobalUnlock(h2);
 
  // Send the Unicode text to the clipboard.
  SetClipboardData(CF_UNICODETEXT, h2);
 
  *src=0;
  *tmp=0;
 
  /* Note: After setting clipboard data,
     the memory block previously allocated belongs to
     the clipboard - not to the app. */
  CloseClipboard();
  return 1;
}
 

/* transfer the clipboard data into the given byte array */
int clipboardReadIntoAt(int count, int byteArrayIndex, int startIndex)
{ HANDLE h, h2;
  unsigned char *dst, *tmp;
  WCHAR *src;
  int tel,len, bytesNeeded;
 

  if(!IsClipboardFormatAvailable(CF_TEXT)) /* check for format CF_TEXT */
    return 0;
 
  if(!OpenClipboard(stWindow))
    return 0;
 
  // Get clipboard data in Unicode format
  h = GetClipboardData(CF_UNICODETEXT);
  src = GlobalLock(h);
 
  // How many bytes do we want to store the Unicode chars to UTF8 representation?
  bytesNeeded = WideCharToMultiByte( CP_UTF8, 0, src, -1,
        tmp, 0, NULL, NULL ) + 1;
 
  h2 = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, bytesNeeded);
  tmp = GlobalLock(h2);
 
  // Convert Unicode text to UTF8.
  WideCharToMultiByte( CP_UTF8, 0, src, -1,
        tmp, bytesNeeded, NULL, NULL);
 
  len = bytesNeeded;
 
  // Get the pointer to the byte array.
  dst= (unsigned char *)byteArrayIndex + startIndex;
 
  while(len--)
    if(((*tmp == 13) && (tmp[1] == 10)))
      { /* RvL 17-04-1998
           drop the line feed after a carriage return
           but leave lone line feeds alone
           may transfer less than 'len' bytes but who cares
           i.e. if they use the clipboardSize there should
           be no problem.*/
 *dst = 13;
 dst++;
        tmp++;
        tmp++;
      }
    else
      { /* regular case: lookup translation */
 *dst = *tmp;
 dst++;
 tmp++;
      } 
 
  GlobalUnlock(h);
  GlobalUnlock(h2);
  CloseClipboard();
  return bytesNeeded;
}
 
The only thing is that in the image side you need a UTF8TextConverter before sending text to the clipboard or getting from it...so, my unicode clipboard interpreter has these methods...
 
fromSystemClipboard: aString
 ^ aString convertFromWithConverter: (UTF8TextConverter new).
 
toSystemClipboard: aString
 | result utfString |
" aString isOctetString ifTrue: [^ aString asOctetString]."
 utfString := aString convertToWithConverter: (UTF8TextConverter new).
 result _ WriteStream on: (String new: utfString size).
 utfString do: [:each | result nextPut: each].
 ^ result contents.
 
I am pretty sure it will need some minor fixes...
I'll post links to ready made builds of this version so others can try it too, soon.
 
Any comments, suggestions, C-related fixes are most welcome...
 
Christos