🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
8 messages
8 total messages Started by Jos� Sun, 13 May 2007 16:13
Clipbored and Unicode
#2043
Author: Jos�
Date: Sun, 13 May 2007 16:13
31 lines
1787 bytes
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�
Re: Clipbored and Unicode
#2045
Author: Bob Gonder
Date: Mon, 14 May 2007 01:04
49 lines
2698 bytes
Jos� wrote:

>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.

>  char *pText = (char *)GlobalLock((HGLOBAL)TextHandle);

You need to use the text before you release it.

>  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();
}

>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.

>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.
Re: Clipbored and Unicode
#1950
Author: Jos�
Date: Mon, 14 May 2007 15:58
53 lines
2958 bytes
On Sun, 13 May 2007 18:04:22 -0700, Bob Gonder
<notbg@notmindspring.invalid> wrote in
borland.public.cppbuilder.nativeapi:

>>  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.

>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.

>>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�
Re: Clipbored and Unicode
#1951
Author: Remy Lebeau (TeamB)
Date: Mon, 14 May 2007 17:09
131 lines
4571 bytes
"Jos�" <jose@127.0.0.1> wrote in message
news:qdde43trid2dep05rjl9pu2k2ohufnguf1@4ax.com...

> 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.

> 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.

> 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();
    }

> Again the Unicode characters are replaced by question marks.

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

> 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

> 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.

> It takes an int as second parameter

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

> I want to store a lot more.

Then do so.  TClipboard allows it.

> 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
Re: Clipbored and Unicode
#1952
Author: Remy Lebeau (TeamB)
Date: Mon, 14 May 2007 17:14
24 lines
1735 bytes
"Jos�" <jose@127.0.0.1> wrote in message
news:va0h43tjrindd9a4jt1p4c10kkl5mi2bgg@4ax.com...

> 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.

> 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.

> 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
Re: Clipbored and Unicode
#1954
Author: Bob Gonder
Date: Mon, 14 May 2007 19:44
21 lines
1606 bytes
Remy Lebeau (TeamB) wrote:

>        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
 
Re: Clipbored and Unicode
#1955
Author: Jos�
Date: Mon, 14 May 2007 20:14
31 lines
2120 bytes
On Mon, 14 May 2007 10:09:36 -0700, "Remy Lebeau \(TeamB\)"
<no.spam@no.spam.com> wrote in borland.public.cppbuilder.nativeapi:

>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();

>    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�
Re: Clipbored and Unicode
#1958
Author: Remy Lebeau (TeamB)
Date: Mon, 14 May 2007 22:26
10 lines
1262 bytes
"Bob Gonder" <notbg@notmindspring.invalid> wrote in message
news:6deh43h7sivjtn2e614s6hj3ss6217dok1@4ax.com...

> Are you sure you want to do that ( GlobalFree )?

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


Gambit
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads