Search code examples
c#marshallingclipboardcopymemory

c# using SetClipboardData fail with ERROR_INVALID_HANDLE


when I try to set a string to clipboard with native method SetClipboardData. It fails and get a error code 6 ERROR_INVALID_HANDLE with GetLastError() method. I can not find out how it fails, here is the code:

                string copyMessage = "need copy to clipboard";
                const int GMEM_MOVABLE = 0x0002;
                const int GHND = GMEM_MOVABLE;

                uint format;
                uint bytes;
                IntPtr hGlobal = IntPtr.Zero;
                format = CF_UNICODETEXT;

                byte[] copyMessageBytes = Encoding.Unicode.GetBytes(copyMessage + "\0");

                // IMPORTANT: SetClipboardData requires memory that was acquired with GlobalAlloc using GMEM_MOVABLE.
                hGlobal = GlobalAlloc(GHND, (UIntPtr)copyMessageBytes.Length);
                if (hGlobal == IntPtr.Zero)
                {
                    return false;
                }
                Marshal.Copy(copyMessageBytes, 0, hGlobal, copyMessageBytes.Length);

                if (SetClipboardData(format, hGlobal).ToInt64() != 0) // code fails here
                {
                    // IMPORTANT: SetClipboardData takes ownership of hGlobal upon success.
                    hGlobal = IntPtr.Zero;
                }
                else
                {
                    return false;
                }

I use Marshal.Copy(byte[] source, int startIndex, IntPtr destination, int length) to copy bytes to hGlobal , is it right? In this case, dose I must use native method CopyMemory() to do this? why?

Thx


Solution

  • I found how to fix it. That is because I alloc memory by GlobalAlloc(), then need to call GlobalLock() before copy data, then need to call GlobalUnlock() after copy.