00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "CMSWindowsClipboardBitmapConverter.h"
00016 #include "CLog.h"
00017
00018
00019
00020
00021
00022 CMSWindowsClipboardBitmapConverter::CMSWindowsClipboardBitmapConverter()
00023 {
00024
00025 }
00026
00027 CMSWindowsClipboardBitmapConverter::~CMSWindowsClipboardBitmapConverter()
00028 {
00029
00030 }
00031
00032 IClipboard::EFormat
00033 CMSWindowsClipboardBitmapConverter::getFormat() const
00034 {
00035 return IClipboard::kBitmap;
00036 }
00037
00038 UINT
00039 CMSWindowsClipboardBitmapConverter::getWin32Format() const
00040 {
00041 return CF_DIB;
00042 }
00043
00044 HANDLE
00045 CMSWindowsClipboardBitmapConverter::fromIClipboard(const CString& data) const
00046 {
00047
00048 HGLOBAL gData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, data.size());
00049 if (gData != NULL) {
00050
00051 char* dst = (char*)GlobalLock(gData);
00052 if (dst != NULL) {
00053 memcpy(dst, data.data(), data.size());
00054 GlobalUnlock(gData);
00055 }
00056 else {
00057 GlobalFree(gData);
00058 gData = NULL;
00059 }
00060 }
00061
00062 return gData;
00063 }
00064
00065 CString
00066 CMSWindowsClipboardBitmapConverter::toIClipboard(HANDLE data) const
00067 {
00068
00069 const char* src = (const char*)GlobalLock(data);
00070 if (src == NULL) {
00071 return CString();
00072 }
00073 UInt32 srcSize = (UInt32)GlobalSize(data);
00074
00075
00076 const BITMAPINFO* bitmap = reinterpret_cast<const BITMAPINFO*>(src);
00077 LOG((CLOG_INFO "bitmap: %dx%d %d", bitmap->bmiHeader.biWidth, bitmap->bmiHeader.biHeight, (int)bitmap->bmiHeader.biBitCount));
00078 if (bitmap->bmiHeader.biPlanes == 1 &&
00079 (bitmap->bmiHeader.biBitCount == 24 ||
00080 bitmap->bmiHeader.biBitCount == 32) &&
00081 bitmap->bmiHeader.biCompression == BI_RGB) {
00082
00083 CString image(src, srcSize);
00084 GlobalUnlock(data);
00085 return image;
00086 }
00087
00088
00089 LOG((CLOG_INFO "convert image from: depth=%d comp=%d", bitmap->bmiHeader.biBitCount, bitmap->bmiHeader.biCompression));
00090 void* raw;
00091 BITMAPINFOHEADER info;
00092 LONG w = bitmap->bmiHeader.biWidth;
00093 LONG h = bitmap->bmiHeader.biHeight;
00094 info.biSize = sizeof(BITMAPINFOHEADER);
00095 info.biWidth = w;
00096 info.biHeight = h;
00097 info.biPlanes = 1;
00098 info.biBitCount = 32;
00099 info.biCompression = BI_RGB;
00100 info.biSizeImage = 0;
00101 info.biXPelsPerMeter = 1000;
00102 info.biYPelsPerMeter = 1000;
00103 info.biClrUsed = 0;
00104 info.biClrImportant = 0;
00105 HDC dc = GetDC(NULL);
00106 HBITMAP dst = CreateDIBSection(dc, (BITMAPINFO*)&info,
00107 DIB_RGB_COLORS, &raw, NULL, 0);
00108
00109
00110 const char* srcBits = (const char*)bitmap + bitmap->bmiHeader.biSize;
00111 if (bitmap->bmiHeader.biBitCount >= 16) {
00112 if (bitmap->bmiHeader.biCompression == BI_BITFIELDS &&
00113 (bitmap->bmiHeader.biBitCount == 16 ||
00114 bitmap->bmiHeader.biBitCount == 32)) {
00115 srcBits += 3 * sizeof(DWORD);
00116 }
00117 }
00118 else if (bitmap->bmiHeader.biClrUsed != 0) {
00119 srcBits += bitmap->bmiHeader.biClrUsed * sizeof(RGBQUAD);
00120 }
00121 else {
00122 srcBits += (1 << bitmap->bmiHeader.biBitCount) * sizeof(RGBQUAD);
00123 }
00124
00125
00126 HDC dstDC = CreateCompatibleDC(dc);
00127 HGDIOBJ oldBitmap = SelectObject(dstDC, dst);
00128 SetDIBitsToDevice(dstDC, 0, 0, w, h, 0, 0, 0, h,
00129 srcBits, bitmap, DIB_RGB_COLORS);
00130 SelectObject(dstDC, oldBitmap);
00131 DeleteDC(dstDC);
00132 GdiFlush();
00133
00134
00135 CString image((const char*)&info, info.biSize);
00136 image.append((const char*)raw, 4 * w * h);
00137
00138
00139 DeleteObject(dst);
00140 ReleaseDC(NULL, dc);
00141
00142
00143 GlobalUnlock(data);
00144
00145 return image;
00146 }