Stringstream to clipboard with memcpy?

Hi. I'm trying to, as the title suggests, copy the contents of a stringstream to the clip board. Here's what I have:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
stringstream ss;

ss << "Example string";

HANDLE h;
h = GlobalAlloc(GMEM_FIXED, sizeof(ss.str().c_str()));

memcpy(h, ss.str().c_str(), sizeof(ss.str().c_str()));

OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_TEXT, h);
CloseClipboard();


The first four characters come out right and the rest is garbage.
it's ss.str().size(), not sizeof.
Last edited on
Ty sir.
You're suprised that sizeof(const char*) isn't the length of your string?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <sstream>
#include <cstring>
#include <cstdlib>

#include <Windows.h>

using std::stringstream ;

bool PasteToClipboard(const std::string& text)
{
    bool succeeded = false ;

    if ( HANDLE clipdata = GlobalAlloc(GMEM_FIXED, text.length()+1) )
    {
        std::memcpy(clipdata, text.data(), text.length()+1) ;

        if ( OpenClipboard(NULL) )
        {
            if ( EmptyClipboard() && SetClipboardData(CF_TEXT, clipdata) )
              succeeded = true ;  

            CloseClipboard() ;
        }

        if ( !succeeded )
            GlobalFree(clipdata) ;
    }

    return succeeded ;
}

int main()
{
    stringstream ss;

    ss << "Example string";

    return PasteToClipboard(ss.str()) ? EXIT_SUCCESS : EXIT_FAILURE ;
}
Note that the MSDN entry on the SetClipboardData function states:

If the hMem parameter identifies a memory object, the object must have been allocated using the function with the GMEM_MOVEABLE flag.

Rather than the GMEM_FIXED you are using. See the following article for further information (including the need to unlock the memory before closing the Clipboard)

SetClipboardData function
http://msdn.microsoft.com/en-us/library/windows/desktop/ms649051%28v=vs.85%29.aspx

And as used in this examples on this page

Using the Clipboard
http://msdn.microsoft.com/en-us/library/windows/desktop/ms649016%28v=vs.85%29.aspx

Andy
Last edited on
I swear I verified GMEM_FIXED was correct. Maybe the Alzheimer's is kicking in.

At any rate, corrected code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <sstream>
#include <cstring>
#include <cstdlib>

#include <Windows.h>

bool PasteToClipboard(const std::string& text)
{
    bool succeeded = false ;

    if ( HANDLE clipdata = GlobalAlloc(GMEM_MOVEABLE, text.length()+1) )
    {
        if ( auto clipdataptr = GlobalLock(clipdata) )
        {
            std::memcpy(clipdataptr, text.data(), text.length()+1) ;
            GlobalUnlock(clipdata) ;

            if ( OpenClipboard(NULL) )
            {
                if ( EmptyClipboard() && SetClipboardData(CF_TEXT, clipdata) )
                  succeeded = true ;  

                CloseClipboard() ;
            }
        }

        if ( !succeeded )
            GlobalFree(clipdata) ;
    }

    return succeeded ;
}

int main()
{
    std::stringstream ss;

    ss << "Example string";

    return PasteToClipboard(ss.str()) ? EXIT_SUCCESS : EXIT_FAILURE ;
}
Hmmm...

I have found this Microsoft example which is using GEM_FIXED... it's part of the MFC documentation. As it disagrees with the entry for the SetClipboardData function, I am suspicious of it.

Clipboard: Using the Windows Clipboard
http://msdn.microsoft.com/en-gb/library/vstudio/80db3kax%28v=vs.100%29.aspx

Andy
Topic archived. No new replies allowed.