<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.6000.16441" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV><FONT face=Arial size=2>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...</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV><FONT face=Arial size=2>
<DIV><BR>/****************************************************************************/<BR>/*
Clipboard
*/<BR>/****************************************************************************/</DIV>
<DIV> </DIV>
<DIV>int clipboardSize(void)<BR>{ HANDLE h, h2;<BR> WCHAR *src;<BR>
unsigned char *csrc;<BR> int len, bytesNeeded;</DIV>
<DIV> </DIV>
<DIV> // Do we have text in the clipboard?<BR>
if(!IsClipboardFormatAvailable(CF_TEXT))<BR> return
0;<BR> if(!OpenClipboard(stWindow))<BR> return 0;</DIV>
<DIV> </DIV>
<DIV> // Get it in unicode format.<BR> h =
GetClipboardData(CF_UNICODETEXT);</DIV>
<DIV> </DIV>
<DIV> src = GlobalLock(h);</DIV>
<DIV> </DIV>
<DIV> // How many bytes do we want to store those unicode chars in UTF8
format?<BR> bytesNeeded = WideCharToMultiByte( CP_UTF8, 0, src,
-1,<BR> NULL, 0, NULL, NULL );</DIV>
<DIV> </DIV>
<DIV> h2 = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
bytesNeeded);<BR> csrc = GlobalLock(h2);</DIV>
<DIV> </DIV>
<DIV> // Convert Unicode text to UTF8.<BR> WideCharToMultiByte(
CP_UTF8, 0, src, -1,<BR> csrc,
bytesNeeded, NULL, NULL );</DIV>
<DIV> </DIV>
<DIV> // Consider CrLf as a 1-byte character.<BR> len =
bytesNeeded;<BR> while(len--)<BR> if(((*csrc == 13)
&& (csrc[1] == 10)))<BR> {
<BR> bytesNeeded--;<BR> csrc++;<BR>
}<BR> else<BR> {
<BR> csrc++;<BR> } </DIV>
<DIV> </DIV>
<DIV><BR> // Clipboard size is bytesNeeded excluding the terminating
character.<BR> len = bytesNeeded - 1;</DIV>
<DIV> </DIV>
<DIV> GlobalUnlock(h);<BR> GlobalUnlock(h2);</DIV>
<DIV> </DIV>
<DIV> return len;<BR>}</DIV>
<DIV> </DIV>
<DIV><BR>/* send the given string to the clipboard */<BR>int
clipboardWriteFromAt(int count, int byteArrayIndex, int startIndex)<BR>{ HANDLE
h, h2;<BR> unsigned char *src;<BR> int wcharsNeeded, len;<BR>
WCHAR *out, *tmp;</DIV>
<DIV> </DIV>
<DIV> if(!OpenClipboard(stWindow))<BR> return 0;</DIV>
<DIV> </DIV>
<DIV> // Get the pointer to the byte array.<BR> src = (unsigned char
*)byteArrayIndex + startIndex;</DIV>
<DIV> </DIV>
<DIV> // How many WCHARs do we need to store the UTF8 represented bytes
from Squeak?<BR> wcharsNeeded = MultiByteToWideChar( CP_UTF8, 0,
src,<BR> count+1, NULL,
<BR> 0 );</DIV>
<DIV> </DIV>
<DIV> // If we have Cr only "returns" then we will need another character
for Lf.<BR> len = wcharsNeeded * sizeof(WCHAR);<BR>
while(len--)<BR> if ((*src++ == 13) && (*src !=
10))<BR> wcharsNeeded++; </DIV>
<DIV> </DIV>
<DIV> // Point to start of byte aray.<BR> src = (unsigned char
*)byteArrayIndex + startIndex;</DIV>
<DIV> </DIV>
<DIV> // Allocate needed memory for wcharsNeeded WCHARs.<BR> h =
GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, wcharsNeeded *
sizeof(WCHAR));<BR> out = GlobalLock(h);</DIV>
<DIV> </DIV>
<DIV> // Convert them to Unicode UTF16.<BR> MultiByteToWideChar(
CP_UTF8, 0, src,<BR> count+1,
out, <BR> wcharsNeeded );</DIV>
<DIV> </DIV>
<DIV> // Allocate needed memory for intermediate buffer.<BR> // OK,
i could do some more work here in order to avoid a whole new buffer just
for<BR> // fixing the CrLf thing, but it's ok for now...<BR> h2 =
GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, wcharsNeeded *
sizeof(WCHAR));<BR> tmp = GlobalLock(h2);</DIV>
<DIV> </DIV>
<DIV> // Add missing Lf characters...<BR> len =
wcharsNeeded;<BR> while(len--)<BR> if((*out ==
13))<BR> { /* special case: crlf translation
*/<BR> *tmp = 13;<BR> tmp++;<BR> *tmp =
10;<BR> tmp++;<BR> out++;<BR>
}<BR> else<BR> { /* regular
case: lookup translation */<BR> *tmp =
*out;<BR> tmp++;<BR> out++;<BR> }</DIV>
<DIV> </DIV>
<DIV> EmptyClipboard();<BR> GlobalUnlock(h);<BR>
GlobalUnlock(h2);</DIV>
<DIV> </DIV>
<DIV> // Send the Unicode text to the clipboard.<BR>
SetClipboardData(CF_UNICODETEXT, h2);</DIV>
<DIV> </DIV>
<DIV> *src=0;<BR> *tmp=0;</DIV>
<DIV> </DIV>
<DIV> /* Note: After setting clipboard data,<BR>
the memory block previously allocated belongs to<BR> the
clipboard - not to the app. */<BR> CloseClipboard();<BR> return
1;<BR>}</DIV>
<DIV> </DIV>
<DIV><BR>/* transfer the clipboard data into the given byte array */<BR>int
clipboardReadIntoAt(int count, int byteArrayIndex, int startIndex)<BR>{ HANDLE
h, h2;<BR> unsigned char *dst, *tmp;<BR> WCHAR *src;<BR> int
tel,len, bytesNeeded;</DIV>
<DIV> </DIV>
<DIV><BR> if(!IsClipboardFormatAvailable(CF_TEXT)) /* check for format
CF_TEXT */<BR> return 0;</DIV>
<DIV> </DIV>
<DIV> if(!OpenClipboard(stWindow))<BR> return 0;</DIV>
<DIV> </DIV>
<DIV> // Get clipboard data in Unicode format<BR> h =
GetClipboardData(CF_UNICODETEXT);<BR> src = GlobalLock(h);</DIV>
<DIV> </DIV>
<DIV> // How many bytes do we want to store the Unicode chars to UTF8
representation?<BR> bytesNeeded = WideCharToMultiByte( CP_UTF8, 0, src,
-1,<BR> tmp, 0, NULL, NULL ) +
1;</DIV>
<DIV> </DIV>
<DIV> h2 = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
bytesNeeded);<BR> tmp = GlobalLock(h2);</DIV>
<DIV> </DIV>
<DIV> // Convert Unicode text to UTF8.<BR> WideCharToMultiByte(
CP_UTF8, 0, src, -1,<BR> tmp,
bytesNeeded, NULL, NULL);</DIV>
<DIV> </DIV>
<DIV> len = bytesNeeded;</DIV>
<DIV> </DIV>
<DIV> // Get the pointer to the byte array.<BR> dst= (unsigned char
*)byteArrayIndex + startIndex;</DIV>
<DIV> </DIV>
<DIV> while(len--)<BR> if(((*tmp == 13) &&
(tmp[1] == 10)))<BR> { /* RvL
17-04-1998<BR> drop
the line feed after a carriage
return<BR> but leave
lone line feeds
alone<BR> may
transfer less than 'len' bytes but who
cares<BR> i.e. if
they use the clipboardSize there
should<BR> be no
problem.*/<BR> *dst =
13;<BR> dst++;<BR>
tmp++;<BR>
tmp++;<BR> }<BR>
else<BR> { /* regular case: lookup translation
*/<BR> *dst =
*tmp;<BR> dst++;<BR> tmp++;<BR> }
</DIV>
<DIV> </DIV>
<DIV> GlobalUnlock(h);<BR> GlobalUnlock(h2);<BR>
CloseClipboard();<BR> return bytesNeeded;<BR>}</DIV>
<DIV> </DIV>
<DIV>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...</DIV>
<DIV> </DIV>
<DIV>fromSystemClipboard: aString</DIV>
<DIV> ^ aString convertFromWithConverter: (UTF8TextConverter new).</DIV>
<DIV> </DIV>
<DIV>toSystemClipboard: aString</DIV>
<DIV> | result utfString |<BR>" aString isOctetString ifTrue: [^
aString asOctetString]."</DIV>
<DIV> utfString := aString convertToWithConverter: (UTF8TextConverter
new).</DIV>
<DIV> result _ WriteStream on: (String new: utfString size).</DIV>
<DIV> utfString do: [:each | result nextPut: each].</DIV>
<DIV> ^ result contents.</DIV>
<DIV> </DIV>
<DIV>I am pretty sure it will need some minor fixes...</DIV>
<DIV>I'll post links to ready made builds of this version so others can try it
too, soon.</DIV>
<DIV> </DIV>
<DIV>Any comments, suggestions, C-related fixes are most welcome...</DIV>
<DIV> </DIV>
<DIV>Christos</FONT></DIV></BODY></HTML>