 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
José Guest
|
Posted: Sun May 13, 2007 9:13 pm Post subject: Clipbored and Unicode |
|
|
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
|
Posted: Mon May 14, 2007 6:04 am Post subject: Re: Clipbored and Unicode |
|
|
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
|
Posted: Mon May 14, 2007 8:58 pm Post subject: Re: Clipbored and Unicode |
|
|
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
|
Posted: Mon May 14, 2007 10:09 pm Post subject: Re: Clipbored and Unicode |
|
|
"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
|
Posted: Mon May 14, 2007 10:14 pm Post subject: Re: Clipbored and Unicode |
|
|
"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
|
Posted: Tue May 15, 2007 12:44 am Post subject: Re: Clipbored and Unicode |
|
|
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
|
Posted: Tue May 15, 2007 1:14 am Post subject: Re: Clipbored and Unicode |
|
|
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
|
Posted: Tue May 15, 2007 3:26 am Post subject: Re: Clipbored and Unicode |
|
|
"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 |
|
 |
|
|
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
|
|