BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Clipbored and Unicode

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Native API)
View previous topic :: View next topic  
Author Message
José
Guest





PostPosted: Sun May 13, 2007 9:13 pm    Post subject: Clipbored and Unicode Reply with quote



The clipboard contains text, including Unicode characters. I'm trying
to exchange these with my program, but not successfully.

I used to do it by typing ^V in a TMemo or a TRichEdit, but I have
discovered that this is a sure way to lose Unicode characters.

With the help of the help files (often not helpful at all), I tried
this:

TClipboard *cb=Clipboard();
cb->Open();
int TextHandle = cb->GetAsHandle(CF_TEXT);
char *pText = (char *)GlobalLock((HGLOBAL)TextHandle);
GlobalUnlock((HGLOBAL)TextHandle);
cb->Close();

Again the Unicode characters are replaced by question marks. Perhaps
this should be expected, since char* has no space for Unicode. But
what else can I do?

To write into the clipboard, I found that SetAsHandle (the obvious
opposite of GetAsHandle) is unusable. It takes an int as second
parameter, and I want to store a lot more. But the following works. I
haven't tried it with Unicode yet:

TClipboard *cb=Clipboard();
cb->Open();
cb->SetTextBuf(string.c_str());
cb->Close();
--
José
Back to top
Bob Gonder
Guest





PostPosted: Mon May 14, 2007 6:04 am    Post subject: Re: Clipbored and Unicode Reply with quote



José wrote:

Quote:
The clipboard contains text, including Unicode characters. I'm trying

TClipboard *cb=Clipboard();
cb->Open();
int TextHandle = cb->GetAsHandle(CF_TEXT);

You want CF_UNICODETEXT for unicode text.
Since that is not a listed format for TClipboard, you might want to
write your own clipboard functions with the WinApi. It's not hard.

Quote:
char *pText = (char *)GlobalLock((HGLOBAL)TextHandle);

You need to use the text before you release it.

Quote:
GlobalUnlock((HGLOBAL)TextHandle);
cb->Close();
(You will be doing the same thing above if you use the WinApi.)



You might try this from thr help:
void __fastcall TMainForm::EditPasteClick(TObject* Sender)
{ RichEdit1->PasteFromClipboard();
}

Quote:
Again the Unicode characters are replaced by question marks. Perhaps
this should be expected, since char* has no space for Unicode. But
what else can I do?

wchar_t is for unicode.

Quote:
To write into the clipboard, I found that SetAsHandle (the obvious
opposite of GetAsHandle) is unusable. It takes an int as second
parameter, and I want to store a lot more.

It takes a Handle. That is, the same kind of thing you got above:
HGLOBAL h = GlobalAlloc( size, flags );
char * data = GlobalLock( h );
lstrcpy( data, "This goes to the clipboard" );
GlobalUnlock( h );
SetAsHandle( CF_TEXT, h );
// -Do-not- GlobalFree because clipboard owns it.
(You are going to be doing the same thing if you use the WinApi.)

So, it looks like VCL doesn't supprt unicode, which people have been
saying all along. That's ok because you can use the WinApi to do it.
Don't know if the TRichEdit will read it once you get it past the
clipboard though.
Back to top
José
Guest





PostPosted: Mon May 14, 2007 8:58 pm    Post subject: Re: Clipbored and Unicode Reply with quote



On Sun, 13 May 2007 18:04:22 -0700, Bob Gonder
<notbg (AT) notmindspring (DOT) invalid> wrote in
borland.public.cppbuilder.nativeapi:

Quote:
TClipboard *cb=Clipboard();
cb->Open();
int TextHandle = cb->GetAsHandle(CF_TEXT);

You want CF_UNICODETEXT for unicode text.
Since that is not a listed format for TClipboard, you might want to
write your own clipboard functions with the WinApi. It's not hard.

CF_UNICODETEXT is not in the help file, so how was I to know? It is
accepted though, and it works with wchar_t. However, there are more
than a million Unicode characters, which means that wchar_t, which is
only 16 bits, is insufficient. However, I guess that it will seldon
happen that I need more than 16 bits.

Quote:
You might try this from thr help:
void __fastcall TMainForm::EditPasteClick(TObject* Sender)
{ RichEdit1->PasteFromClipboard();
}

That won't do. RichEdit does not accept Unicode. That was where the
problem started: I used to enter data in my program by type ^V in a
TMemo, or a TRichEdit. That was satisfactory as long as there were no
Uni characters in the clipboard.

Quote:
To write into the clipboard, I found that SetAsHandle (the obvious
opposite of GetAsHandle) is unusable. It takes an int as second
parameter, and I want to store a lot more.

It takes a Handle. That is, the same kind of thing you got above:
HGLOBAL h = GlobalAlloc( size, flags );
char * data = GlobalLock( h );
lstrcpy( data, "This goes to the clipboard" );
GlobalUnlock( h );
SetAsHandle( CF_TEXT, h );
// -Do-not- GlobalFree because clipboard owns it.
(You are going to be doing the same thing if you use the WinApi.)

Some changes are obviously needed:
1. char must be wchar_t of course. Or even something with 32 bits
2. I swapped the parameters of GlobalAlloc.
3. I found that HGLOBAL equals void* (I hate those enigmatic type
names).
4. The 2nd parameter of SetAsHandle must be an int, so your example
doesn't work. I can write (int)h, but this write unexpected stuff to
the clipboard.

So I can read the clipboard now, but I cannot write yet.
--
José
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Mon May 14, 2007 10:09 pm    Post subject: Re: Clipbored and Unicode Reply with quote

"José" <jose (AT) 127 (DOT) 0.0.1> wrote in message
news:qdde43trid2dep05rjl9pu2k2ohufnguf1 (AT) 4ax (DOT) com...

Quote:
The clipboard contains text, including Unicode characters. I'm
trying to exchange these with my program, but not successfully.

That is because you are not handling Unicode at all.

Quote:
I used to do it by typing ^V in a TMemo or a TRichEdit, but I have
discovered that this is a sure way to lose Unicode characters.

That is because the VCL uses Ansi windows, not Unicode windows. So a
paste will read the clipboard as Ansi text, not as Unicode text.

Quote:
With the help of the help files (often not helpful at all), I tried
this:


That code is also not retreiving any Unicode at all. If the clipboard
contains Unicode, and you read it as CF_TEXT, the OS converts the text
automatically. Unicode has its own separate Clipboard format
registered - CF_UNICODETEXT. You need to use that instead of CF_TEXT,
ie:

TClipboard *cb = Clipboard();
WideString ws;
AnsiString as;

cb->Open();
try
{
if( cb->HasFormat(CF_UNICODETEXT) )
{
HGLOBAL TextHandle = (HGLOBAL)
cb->GetAsHandle(CF_UNICODETEXT);
if( TextHandle )
{
ws = (wchar_t *) GlobalLock(TextHandle);
GlobalUnlock(TextHandle);
}
}
else if( cb->HasFormat(CF_TEXT) )
{
as = cb->AsText;
}
}
__finally {
cb->Close();
}

Quote:
Again the Unicode characters are replaced by question marks.

As they should be, because you are reading the clipboard as Ansi, not
Unicode.

Quote:
Perhaps this should be expected, since char* has no space for
Unicode.
But what else can I do?

Read the documentation. CF_UNICODETEXT is documented at MSDN as one
of the Standard Formats:

Clipboard Formats
http://msdn2.microsoft.com/en-us/library/ms649013.aspx

Quote:
To write into the clipboard, I found that SetAsHandle (the obvious
opposite of GetAsHandle) is unusable.

It is very usable. You are just not using it correctly.

Quote:
It takes an int as second parameter

The integer is expected to be an HGLOBAL handle to the data that you
want to store.

Quote:
I want to store a lot more.

Then do so. TClipboard allows it.

Quote:
But the following works. I haven't tried it with Unicode yet:

You can't use SetTextBuf() with Unicode, as it uses CF_TEXT instead of
CF_UNICODETEXT. You will have to use SetAsHandle() directly instead:

TClipboard *cb = Clipboard();
WideString ws = "whatever";

wchar_t *pStr = ws.c_bstr();
if( !pStr )
pStr = L"";

ULONG ulSize = (sizeof(wchar_t) * (Length(ws) + 1));
HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
ulSize);
if( hData )
{
try
{
void *pData = GlobalLock(hData);
memcpy(pData, pStr, ulSize);
GlobalUnlock(hData);
cb->SetAsHandle(CF_UNICODETEXT, (int) hData);
}
__finally {
GlobalFree(hData);
}
}

SetBuffer() would have been better than SetAsHandle(), but SetBuffer()
is protected, so you can't use it unless you derive your own class
from TClipboard and then call SetClipboard(), or at least use an
accessor class. For example:

class TClipboardAccess : public TClipboard
{
public:
using TClipboard::SetBuffer;
};

TClipboard *cb = Clipboard();
WideString ws = "whatever";

wchar_t *pStr = ws.c_bstr();
if( !pStr )
pStr = L"";

((TClipboardAccess*)cb)->SetBuffer(CF_UNICODETEXT, pStr,
sizeof(wchar_t) * (Length(ws)+1));


Gambit
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Mon May 14, 2007 10:14 pm    Post subject: Re: Clipbored and Unicode Reply with quote

"José" <jose (AT) 127 (DOT) 0.0.1> wrote in message
news:va0h43tjrindd9a4jt1p4c10kkl5mi2bgg (AT) 4ax (DOT) com...

Quote:
CF_UNICODETEXT is not in the help file, so how was I to know?

You probably didn't read Microsoft's documentation, only Borland's.

Quote:
It is accepted though, and it works with wchar_t. However, there
are more than a million Unicode characters, which means that
wchar_t, which is only 16 bits, is insufficient.

I'm guessing that you haven't read up on how Unicode actually works,
correct? It is more than sufficient for all of the world's current
languages, with room to spare.

Quote:
The 2nd parameter of SetAsHandle must be an int, so your
example doesn't work. I can write (int)h, but this write unexpected
stuff to the clipboard.

Bob's example was for Ansi, not Unicode. See my other reply.


Gambit
Back to top
Bob Gonder
Guest





PostPosted: Tue May 15, 2007 12:44 am    Post subject: Re: Clipbored and Unicode Reply with quote

Remy Lebeau (TeamB) wrote:

Quote:
try
{
void *pData = GlobalLock(hData);
memcpy(pData, pStr, ulSize);
GlobalUnlock(hData);
cb->SetAsHandle(CF_UNICODETEXT, (int) hData);
}
__finally {
GlobalFree(hData);

Are you sure you want to do that ( GlobalFree )?
From BDS help:
Do not delete a handle after passing it to SetAsHandle. The handle
belongs to the clipboard, which will free it.
From MSDN:
The application may not write to or free the data once ownership has
been transferred to the system,
http://msdn2.microsoft.com/en-us/library/ms649051.aspx
Back to top
José
Guest





PostPosted: Tue May 15, 2007 1:14 am    Post subject: Re: Clipbored and Unicode Reply with quote

On Mon, 14 May 2007 10:09:36 -0700, "Remy Lebeau \(TeamB\)"
<no.spam (AT) no (DOT) spam.com> wrote in borland.public.cppbuilder.nativeapi:

Quote:
Unicode has its own separate Clipboard format
registered - CF_UNICODETEXT. You need to use that instead of CF_TEXT,

To write into the clipboard, I found that SetAsHandle (the obvious
opposite of GetAsHandle) is unusable.

It is very usable. You are just not using it correctly.

Well, I agree that it is too easy to shout 'rubbish' if you don't
understand how something must be used. And that happens easily if the
documentation is unclear, or if you are as stupid as I so you don't
understand the documentation.

It is my understanding that G/SetTextBuf have no alternative for
anything but ASCII, while G/SetAsHandle are more versatile. But of
course they are harder to use, and a programming example is very
helpful.

And you taught me a lot more. I didn't know things like WideString and
c_bstr() yet, although I am familiar with String and c_str();

Quote:
ULONG ulSize = (sizeof(wchar_t) * (Length(ws) + 1));

Well, ws.Length() was a bit better, but apart from that your
programming examples were just the thing. Big hugs for you!

--
José
Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Tue May 15, 2007 3:26 am    Post subject: Re: Clipbored and Unicode Reply with quote

"Bob Gonder" <notbg (AT) notmindspring (DOT) invalid> wrote in message
news:6deh43h7sivjtn2e614s6hj3ss6217dok1 (AT) 4ax (DOT) com...

Quote:
Are you sure you want to do that ( GlobalFree )?

Good catch. It should only be freed if an exception is thrown.


Gambit
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Native API) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.