예제 #1
0
 public Boolean LoadPictureFromClipBoard()
 {
     if (Win32Api.OpenClipboard(IntPtr.Zero) == true)                        // 以当前的任务或者说是进程来打开剪贴板。返回值不为0则表示打开成功
     {
         Win32Structure.BITMAPINFOHEADER BmpInfo = new Win32Structure.BITMAPINFOHEADER();
         IntPtr MemPointer, Buffer;
         if (Win32Api.IsClipboardFormatAvailable(Win32Const.CF_DIB) != 0)                                                               // 剪贴板中有DIB图像数据
         {
             Buffer     = Win32Api.GetClipboardData(Win32Const.CF_DIB);                                                                 // 得到DIB数据的起始地址
             MemPointer = Win32Api.GlobalLock(Buffer);
             BmpInfo    = (Win32Structure.BITMAPINFOHEADER)Marshal.PtrToStructure(MemPointer, typeof(Win32Structure.BITMAPINFOHEADER)); // 复制数据带结构体
             AllocateBitmap(BmpInfo.Width, Math.Abs(BmpInfo.Height), (ushort)BmpInfo.BitCount);
             if (BmpInfo.BitCount <= 8)
             {
                 m_PaletteSize = BmpInfo.ClrUsed == 0 ? (1 << (BmpInfo.BitCount)) : (int)BmpInfo.ClrUsed;      // 得到实际的调色板的数量
                 Win32Api.CopyMemory(m_PaletteAddress, MemPointer + 40, m_PaletteSize * 4);                    // 复制剪贴板数据
                 if (BmpInfo.Height < 0)                                                                       // FastBitmap的图像复制容许这个值为负值
                 {
                     Win32Api.CopyMemory(m_Pointer, MemPointer + 40 + m_PaletteSize * 4, m_Stride * m_Height); // 复制图像数据
                 }
                 else
                 {
                     for (int Y = 0; Y < m_Height; Y++)                                                          // 调整行序
                     {
                         Win32Api.CopyMemory(m_Pointer + Y * m_Stride, MemPointer + 40 + m_PaletteSize * 4 + (m_Height - 1 - Y) * m_Stride, m_Stride);
                     }
                 }
                 Win32Api.SetDIBColorTable(m_Hdc, 0, m_PaletteSize, m_PaletteAddress);                           // 设置DC的调色板
             }
             else
             {
                 if (BmpInfo.Height < 0)
                 {
                     Win32Api.CopyMemory(m_Pointer, MemPointer + 40, m_Stride * m_Height);                       // 24/32位图像无调色板,直接复制数据
                 }
                 else
                 {
                     for (int Y = 0; Y < m_Height; Y++)
                     {
                         Win32Api.CopyMemory(m_Pointer + Y * m_Stride, MemPointer + 40 + (m_Height - 1 - Y) * m_Stride, m_Stride);
                     }
                 }
             }
             Win32Api.GlobalUnlock(Buffer);
         }
         Win32Api.CloseClipboard();
     }
     return(true);
 }
예제 #2
0
        public Boolean CopyToClipBoard(Boolean CompatibleWithPhotoShop = true)
        {
            if (m_Handle == IntPtr.Zero)
            {
                return(false);
            }

            Win32Structure.BITMAPINFOHEADER BmpInfo = new Win32Structure.BITMAPINFOHEADER();
            IntPtr MemPointer, Buffer;
            int    BufferSize = 0;

            //   FastBitmap本身的数据顶点数据位于屏幕的左上角,因此设置为负值则后面的图像数据无需单独行拷贝
            //   但是PhotoShop不支持这种格式。
            BmpInfo.Height = (CompatibleWithPhotoShop == true ? m_Height : -m_Height);

            BmpInfo.Width       = m_Width;
            BmpInfo.Compression = Win32Const.BI_RGB;
            BmpInfo.Planes      = 1;
            BmpInfo.Size        = 40;
            BmpInfo.BitCount    = m_BitCount;
            BmpInfo.ClrUsed     = (uint)m_PaletteSize;                       // 增加这一句,否则从剪贴板获取数据就错位(mspaint的黏贴也不对)

            switch (m_BitCount)
            {
            case 1:
            case 4:
            case 8:
                BufferSize = 40 + m_PaletteSize * 4 + m_Stride * m_Height;              // 文件头+调色板+图像数据
                break;

            case 24:
            case 32:
                BufferSize = 40 + m_Stride * m_Height;                                    // 文件头+图像数据
                break;

            default:
                return(false);
            }
            Buffer = Win32Api.GlobalAlloc(Win32Const.GMEM_MOVEABLE, BufferSize);    // 给全局内存对象分配全局内存 ,必须使用GMEM_MOVEABLE标志  http://topic.csdn.net/u/20070122/10/cde3555b-c4da-40ca-8fd9-a5c05fcf75df.html
            if (Buffer == IntPtr.Zero)
            {
                return(false);
            }
            MemPointer = Win32Api.GlobalLock(Buffer);                               // 通过给全局内存对象加锁获得对全局内存块的引用

            Marshal.StructureToPtr(BmpInfo, MemPointer, true);                      // 封送结构体到非托管内存中

            switch (m_BitCount)
            {
            case 1:
            case 4:
            case 8:
                Win32Api.CopyMemory(MemPointer + 40, m_PaletteAddress, m_PaletteSize * 4);                   // 拷贝调色板数据
                if (CompatibleWithPhotoShop == true)
                {
                    for (int Y = 0; Y < Height; Y++)
                    {
                        Win32Api.CopyMemory(MemPointer + m_PaletteSize * 4 + 40 + Y * Stride, m_Pointer + Stride * (Height - 1 - Y), Stride);
                    }
                }
                else
                {
                    Win32Api.CopyMemory(MemPointer + m_PaletteSize * 4 + 40, m_Pointer, m_Stride * m_Height);      // 拷贝图像数据
                }
                break;

            case 24:
            case 32:
                if (CompatibleWithPhotoShop == true)
                {
                    for (int Y = 0; Y < Height; Y++)
                    {
                        Win32Api.CopyMemory(MemPointer + 40 + Stride * Y, Pointer + Stride * (Height - 1 - Y), Stride);
                    }
                }
                else
                {
                    Win32Api.CopyMemory(MemPointer + 40, m_Pointer, m_Stride * m_Height);       // 拷贝图像数据
                }
                break;

            default:
                return(false);
            }
            Win32Api.GlobalUnlock(Buffer);                                          // 使用完全局内存块后需要对全局内存块解锁
            if (Win32Api.OpenClipboard(IntPtr.Zero) == true)                        // 以当前的任务或者说是进程来打开剪贴板。返回值不为0则表示打开成功
            {
                Win32Api.EmptyClipboard();                                          // 这个函数将清空剪贴板,并释放剪贴板中数据的句柄,然后将剪贴板的所有权分配给当前打开剪贴板的窗口
                Win32Api.SetClipboardData(Win32Const.CF_DIB, Buffer);
                Win32Api.CloseClipboard();                                          //GlobalFree Buffer 这个释放就交给系统去释放了,千万不要在这里释放,否则会造成一些莫名其妙的错误
                return(true);
            }
            else
            {
                Win32Api.CloseClipboard();
                return(false);
            }
        }