🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #7909

Re: Clipboard

#7909
From: Remy Lebeau (TeamB)
Date: Tue, 14 Dec 2004 23:24
201 lines
6906 bytes
"Chris" <chris@REMOVETHISchrischfmousey.karoo.co.uk> wrote in message
news:41bf3edb@newsgroups.borland.com...

> How would I go about placing an image (bitmap) and some
> text on the clipboard at the same time?

Simply call OpenClipboard(), then call SetClipboardData() multiple times
(one for each format you want to store), then finally call CloseClipboard().
For example:

    void __fastcall TForm1::CopyBitmapToClipboard(TBitmap *ABitmap, const
AnsiString &AText)
    {
        if( ::OpenClipboard(Handle) )
        {
            EmptyClipboard();
            try
            {
                Word wFormat;
                int iData;
                HPALETTE hPalette = NULL;

                ABitmap->SaveToClipboardFormat(wFormat, iData, hPalette);
                ::SetClipboardData(Format, reinterpret_cast<HANDLE>(iData));
                if( hPalette ) ::SetClipboardData(CF_PALETTE, hPalette);

                HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE,
AText.Length()+1);
                if( hMem )
                {
                    char *ptr = ::GlobalLock(hMem);
                    memcpy(ptr, AText.c_str(), AText.Length()+1);
                    ::GlobalUnlock(hMem);
                    ::SetClipboardData(CF_TEXT, hMem);
                }
            }
            __finally {
                ::CloseClipboard();
            }
        }
    }

    void __fastcall TForm1::PasteBitmapFromClipboard(TBitmap *ABitmap,
AnsiString &AText)
    {
        if( ::OpenClipboard(Handle) )
        {
            try
            {
                HANDLE hMem = ::GetClipboardData(CF_BITMAP);
                if( hMem )
                {
                    HPALETTE hPalette = ::GetClipboardData(CF_PALETTE);
                    ABitmap->LoadFromClipboardFormat(CF_BITMAP,
reinterprt_cast<int>(hMem), hPalette);
                }
                else
                    ABitmap->Handle = NULL;

                hMem = ::GetClipboardData(CF_TEXT);
                if( hMem )
                {
                    char *ptr = (char*) ::GlobalLock(hMem);
                    try {
                        AText = ptr;
                    }
                    __finally {
                        ::GlobalUnlock(hMem);
                    }
                }
                else
                    AText = "";
            }
            __finally {
                ::CloseClipboard();
            }
        }
    }

> I need to place text such as
>
> begin.image1
>     image.name=Image1
>     image.x=10
>     image.y=10
>     image.lockaspect=1
>
> etc but I also need the bitmap data too.

If your application is the only one using the data, then the alternative to
the above is to register a custom clipboard format and then pack the text
and data together into a single data block.  For example:

    UINT uMyFormat = 0;

    class TReadOnlyMemoryStream : public TCustomMemoryStream
    {
    private:
        HGLOBAL FMem;
    public:
        __fastcall TReadOnlyMemoryStream(HGLOBAL AMem)
            : TCustomMemoryStream(), FMem(AMem)
        {
            SetPointer(::GlobalLock(FMem), ::GlobalSize(FMem));
        }
        __fastcall ~TReadOnlyMemoryStream()
        {
            ::GlobalUnlock(FMem);
        }
        void __fastcall Clear()
        {
            SetPointer(NULL, 0);
            Position = 0;
        }
        void __fastcall SetSize(int NewSize)
        {
            // read-only stream
        }
        int __fastcall Write(const void* Buffer, int Count)
        {
            // read-only stream
            return 0;
        }
    };

    __fastcall TForm1::TForm1(TComponent *Owner)
        : TForm(Owner)
    {
        uMyFormat = RegisterClipboardFormat("My Image Data");
    }

    void __fastcall TForm1::CopyBitmapToClipboard(TBitmap *ABitmap, const
AnsiString &AText)
    {
        TMemoryStream *Stream = new TMemoryStream;
        try
        {
            int length = AText.Length();
            Stream->Write(&length, sizeof(int));
            Stream->Write(AText.c_str(), length);
            ABitmap->SaveToStream(Stream);

            if( ::OpenClipboard(Handle) )
            {
                EmptyClipboard();
                try
                {
                    HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE,
Stream->Size);
                    if( hMem )
                    {
                        void *ptr = ::GlobalLock(hMem);
                        memcpy(ptr, Stream->Memory, Stream->Size);
                        ::GlobalUnlock(hMem);
                        ::SetClipboardData(uMyFormat, hMem);
                    }
                }
                __finally {
                    ::CloseClipboard();
                }
            }
        }
        __finally {
            delete Stream;
        }
    }

    void __fastcall TForm1::PasteBitmapFromClipboard(TBitmap *ABitmap,
AnsiString &AText)
    {
        if( ::OpenClipboard(Handle) )
        {
            try
            {
                HANDLE hMem = ::GetClipboardFormat(uMyFormat);
                if( hMem )
                {
                    TReadOnlyMemoryStream *Stream = new
TReadOnlyMemoryStream(hMem);
                    try
                    {
                        int length = 0;
                        Stream->Read(&length, sizeof(int));
                        AText.SetLength(length);
                        Stream->Read(AText.c_str(), length);
                        ABitmap->LoadFromStream(Stream);
                    }
                    __finally {
                        delete Stream;
                    }
                }
            }
            __finally {
                ::CloseClipboard();
            }
        }
    }


Gambit
Technical Details
Message-ID: <41bf760a$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!newsfeed2.dallas1.level3.net!news.level3.com!bloom-beacon.mit.edu!npeer.de.kpn-eurorings.net!border2.nntp.ams.giganews.com!nntp.giganews.com!pe2.news.blueyonder.co.uk!blueyonder!news-peer-test!btnet!newsfeed.bt.es!caladan.landsraad.net!newsgroups.borland.com!not-for-mail
References: <41bf3edb@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,23e8f8184da9efdb
X-Google-Attributes: gid10cc67,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Remy Lebeau \(TeamB\)" <no.spam@no.spam.com>
Newsgroups: borland.public.cppbuilder.nativeapi
References: <41bf3edb@newsgroups.borland.com>
Subject: Re: Clipboard
Date: Tue, 14 Dec 2004 15:24:25 -0800
Lines: 203
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1409
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409
NNTP-Posting-Host: 68.69.17.41
Message-ID: <41bf760a$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1103066634 68.69.17.41 (14 Dec 2004 15:23:54 -0800)
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!newsfeed2.dallas1.level3.net!news.level3.com!bloom-beacon.mit.edu!npeer.de.kpn-eurorings.net!border2.nntp.ams.giganews.com!nntp.giganews.com!pe2.news.blueyonder.co.uk!blueyonder!news-peer-test!btnet!newsfeed.bt.es!caladan.landsraad.net!newsgroups.borland.com!not-for-mail